]> err.no Git - sope/blob - sope-core/NGStreams/NGTextStream.m
converted all Xcode projects from Xcode < 2.1 to 2.1
[sope] / sope-core / NGStreams / NGTextStream.m
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 "NGTextStream.h"
23 #include "common.h"
24
25 @implementation NGTextStream
26
27 + (int)version {
28   return 2;
29 }
30
31 - (void)dealloc {
32   [self->lastException release];
33   [super dealloc];
34 }
35
36 /* NGTextInputStream */
37
38 - (NSException *)lastException {
39   return nil;
40 }
41 - (void)setLastException:(NSException *)_exception {
42   ASSIGN(self->lastException, _exception);
43 }
44 - (void)resetLastException {
45   [self->lastException release];
46   self->lastException = nil;
47 }
48
49 - (unichar)readCharacter {
50   [self subclassResponsibility:_cmd];
51   return 0;
52 }
53
54 - (BOOL)isOpen {
55   return YES;
56 }
57
58 /* NGExtendedTextInputStream */
59
60 - (NSString *)readLineAsString {
61   NSMutableString *str;
62   unichar c;
63
64   *(&str) = (id)[NSMutableString string];
65
66   NS_DURING {
67     while ((c = [self readCharacter]) != '\n')
68       [str appendString:[NSString stringWithCharacters:&c length:1]];
69   }
70   NS_HANDLER {
71     if ([localException isKindOfClass:[NGEndOfStreamException class]]) {
72       if ([str length] == 0) str = nil;
73     }
74     else
75       [localException raise];
76   }
77   NS_ENDHANDLER;
78   
79   return str;
80 }
81
82 - (unsigned)readCharacters:(unichar *)_chars count:(unsigned)_count {
83   /*
84     Read up to _count characters, but one at the minimum.
85   */
86   volatile unsigned pos;
87
88   NS_DURING {
89     for (pos = 0; pos < _count; pos++)
90       _chars[pos] = [self readCharacter];
91   }
92   NS_HANDLER {
93     if ([localException isKindOfClass:[NGEndOfStreamException class]]) {
94       if (pos == 0)
95         [localException raise];
96     }
97     else
98       [localException raise];
99   }
100   NS_ENDHANDLER;
101
102   NSAssert1(pos > 0, @"invalid character count to be returned: %i", pos);
103   return pos;
104 }
105
106 - (BOOL)safeReadCharacters:(unichar *)_chars count:(unsigned)_count {
107   volatile unsigned pos;
108   
109   for (pos = 0; pos < _count; pos++)
110     _chars[pos] = [self readCharacter];
111   
112   return YES;
113 }
114
115 /* NGTextOutputStream */
116
117 - (BOOL)writeCharacter:(unichar)_character {
118   [self subclassResponsibility:_cmd];
119   return NO;
120 }
121
122 - (BOOL)writeString:(NSString *)_string {
123   unsigned length = [_string length], cnt = 0;
124   unichar  buffer[length];
125   void     (*writeChar)(id, SEL, unichar);
126
127   writeChar = (void (*)(id,SEL,unichar))
128     [self methodForSelector:@selector(writeCharacter:)];
129   
130   [_string getCharacters:buffer];
131   for (cnt = 0; cnt < length; cnt++)
132     writeChar(self, @selector(writeCharacter:), buffer[cnt]);
133   
134   return YES;
135 }
136
137 - (BOOL)flush {
138   return YES;
139 }
140
141 /* NGExtendedTextOutputStream */
142
143 - (BOOL)writeFormat:(NSString *)_format arguments:(va_list)_ap {
144   NSString *tmp;
145   
146   tmp = [[[NSString alloc] initWithFormat:_format arguments:_ap] autorelease];
147   [self writeString:tmp];
148   return YES;
149 }
150 - (BOOL)writeFormat:(NSString *)_format, ... {
151   va_list ap;
152   BOOL res = NO;
153
154   va_start(ap, _format);
155
156   NS_DURING {
157     res = [self writeFormat:_format arguments:ap];
158   }
159   NS_HANDLER {
160     va_end(ap);
161     [localException raise];
162   }
163   NS_ENDHANDLER;
164   va_end(ap);
165
166   return res;
167 }
168
169 - (BOOL)writeNewline {
170   if (![self writeString:@"\n"]) return NO;
171   return [self flush];
172 }
173
174 - (unsigned)writeCharacters:(const unichar *)_chars count:(unsigned)_count {
175   /*
176     Write up to _count characters, but one at the minimum.
177   */
178   volatile unsigned pos;
179
180   NS_DURING {
181     for (pos = 0; pos < _count; pos++)
182       [self writeCharacter:_chars[pos]];
183   }
184   NS_HANDLER {
185     if ([localException isKindOfClass:[NGEndOfStreamException class]]) {
186       if (pos == 0)
187         [localException raise];
188     }
189     else
190       [localException raise];
191   }
192   NS_ENDHANDLER;
193
194   NSAssert1(pos > 0, @"invalid character count to be returned: %i", pos);
195   return pos;
196 }
197
198 - (BOOL)safeWriteCharacters:(const unichar *)_chars count:(unsigned)_count {
199   unsigned pos;
200
201   for (pos = 0; pos < _count; pos++) {
202     if (![self writeCharacter:_chars[pos]])
203       return NO;
204   }
205   
206   return YES;
207 }
208
209 @end /* NGTextStream */