1/*
2  Copyright (C) 2000-2005 SKYRIX Software AG
3
4  This file is part of SOPE.
5
6  SOPE is free software; you can redistribute it and/or modify it under
7  the terms of the GNU Lesser General Public License as published by the
8  Free Software Foundation; either version 2, or (at your option) any
9  later version.
10
11  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12  WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  License for more details.
15
16  You should have received a copy of the GNU Lesser General Public
17  License along with SOPE; see the file COPYING.  If not, write to the
18  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19  02111-1307, USA.
20*/
21
22#include "common.h"
23#include "NGStringTextStream.h"
24#include "NGStreamExceptions.h"
25
26@implementation NGStringTextStream
27
28+ (id)textStreamWithString:(NSString *)_string {
29  return [[[self alloc] initWithString:_string] autorelease];
30}
31- (id)initWithString:(NSString *)_string {
32  if ((self = [super init])) {
33    self->string    = [_string retain];
34    self->index     = 0;
35    self->isMutable = [_string isKindOfClass:[NSMutableString class]];
36  }
37  return self;
38}
39
40- (void)dealloc {
41  [self->string release];
42  [super dealloc];
43}
44
45/* accessors */
46
47- (NSString *)string {
48  return string;
49}
50
51/* operations */
52
53- (BOOL)close {
54  // releases string
55  [self->string release]; self->string = nil;
56  return YES;
57}
58
59// NGTextInputStream
60
61- (unichar)readCharacter {
62  // throws
63  //   NGStreamNotOpenException  when the stream is not open
64  unsigned currentLength = [string length];
65  unichar  result;
66
67  if (string == nil) {
68    [NGStreamNotOpenException raiseWithReason:
69       @"tried to read from a string text stream which was closed"];
70  }
71
72  if (currentLength == index)
73    [[[NGEndOfStreamException alloc] init] raise];
74
75  result = [string characterAtIndex:index];
76  index++;
77  return result;
78}
79
80// NGExtendedTextInputStream
81
82- (NSString *)readLineAsString {
83  // throws
84  //   NGStreamNotOpenException  when the stream is not open
85
86  unsigned currentLength = [string length];
87  NSRange  range;
88
89  if (string == nil) {
90    [NGStreamNotOpenException raiseWithReason:
91            @"tried to read from a string text stream which was closed"];
92  }
93
94  if (currentLength == index)
95    //[[[NGEndOfStreamException alloc] init] raise]
96    return nil;
97
98  range.location = index;
99  range.length   = (currentLength - index);
100
101  range = [string rangeOfString:@"\n" options:NSLiteralSearch range:range];
102  if (range.length == 0) { // did not found newline
103    NSString *result = [string substringFromIndex:index];
104    index = currentLength;
105    return result;
106  }
107  else {
108    NSString *result = nil;
109
110    range.length   = (range.location - index);
111    range.location = index;
112
113    result = [string substringWithRange:range];
114
115    index += range.length + 1;
116
117    return result;
118  }
119}
120
121// NGTextOutputStream
122
123- (BOOL)writeCharacter:(unichar)_character {
124  // throws
125  //   NGReadOnlyStreamException when the stream is not writeable
126  //   NGStreamNotOpenException  when the stream is not open
127
128  if (string == nil) {
129    [NGStreamNotOpenException raiseWithReason:
130            @"tried to write to a string text stream which was closed"];
131    return NO;
132  }
133  if (!isMutable) {
134    [[[NGReadOnlyStreamException alloc] init] raise];
135    return NO;
136  }
137
138  [(NSMutableString *)string appendString:
139    [NSString stringWithCharacters:&_character length:1]];
140  return YES;
141}
142
143- (BOOL)writeString:(NSString *)_string {
144  // throws
145  //   NGReadOnlyStreamException when the stream is not writeable
146  //   NGStreamNotOpenException  when the stream is not open
147
148  if (string == nil) {
149    [NGStreamNotOpenException raiseWithReason:
150            @"tried to write to a string text stream which was closed"];
151    return NO;
152  }
153  if (!isMutable) {
154    [[[NGReadOnlyStreamException alloc] init] raise];
155    return NO;
156  }
157
158  [(NSMutableString *)string appendString:_string];
159  return YES;
160}
161
162- (BOOL)flush {
163  return YES;
164}
165
166@end /* NGStringTextStream */
167