2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo 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
11 OGo 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.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "NGStreamExceptions.h"
26 #include "NGFilterStream.h"
28 @implementation NGStream
32 - (void)setLastException:(NSException *)_exception {
35 - (NSException *)lastException {
39 - (unsigned)readBytes:(void *)_buf count:(unsigned)_len {
40 [self subclassResponsibility:_cmd];
43 - (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len {
44 [self subclassResponsibility:_cmd];
55 - (NGStreamMode)mode {
56 [self subclassResponsibility:_cmd];
59 - (BOOL)isRootStream {
60 [self subclassResponsibility:_cmd];
64 // methods method which write exactly _len bytes
66 - (BOOL)safeReadBytes:(void *)_buf count:(unsigned)_len {
67 return NGSafeReadBytesFromStream(self, _buf, _len);
70 - (BOOL)safeWriteBytes:(const void *)_buf count:(unsigned)_len {
71 return NGSafeWriteBytesToStream(self, _buf, _len);
77 NSLog(@"WARNING: called mark on a stream which doesn't support marking !");
81 [NGStreamException raiseWithStream:self reason:@"marking not supported"];
84 - (BOOL)markSupported {
88 /* convenience methods */
91 return NGReadByteFromStream(self);
96 - (NSString *)modeDescription {
97 NSString *result = @"unknown";
99 switch ([self mode]) {
100 case NGStreamMode_undefined: result = @"undefined"; break;
101 case NGStreamMode_readOnly: result = @"r"; break;
102 case NGStreamMode_writeOnly: result = @"w"; break;
103 case NGStreamMode_readWrite: result = @"rw"; break;
105 [NGUnknownStreamModeException raiseWithStream:self];
111 - (NSString *)description {
112 return [NSString stringWithFormat:
113 @"<%@[0x%08X] mode=%@>",
114 NSStringFromClass([self class]), (unsigned)self,
115 [self modeDescription]];
120 @implementation NGStream(DataMethods)
122 - (NSData *)readDataOfLength:(unsigned int)_length {
126 if (_length == 0) return [NSData data];
128 readCount = [self readBytes:buf count:_length];
129 if (readCount == NGStreamError)
132 return [NSData dataWithBytes:buf length:readCount];
135 - (NSData *)safeReadDataOfLength:(unsigned int)_length {
138 if (_length == 0) return [NSData data];
139 if (![self safeReadBytes:buf count:_length])
141 return [NSData dataWithBytes:buf length:_length];
144 - (unsigned int)writeData:(NSData *)_data {
145 return [self writeBytes:[_data bytes] count:[_data length]];
147 - (BOOL)safeWriteData:(NSData *)_data {
148 return [self safeWriteBytes:[_data bytes] count:[_data length]];
151 @end /* NGStream(DataMethods) */
153 // concrete implementations as functions
155 int NGReadByteFromStream(id<NGInputStream> _stream) {
156 volatile int result = -1;
161 l = [_stream readBytes:&c count:sizeof(unsigned char)];
162 if (l == NGStreamError) {
163 NSException *e = [(id)_stream lastException];
164 if ([e isKindOfClass:[NGEndOfStreamException class]])
173 if ([localException isKindOfClass:[NGEndOfStreamException class]])
176 [localException raise];
183 BOOL NGSafeReadBytesFromStream(id<NGInputStream> _in, void *_buf, unsigned _len){
184 volatile int toBeRead;
185 volatile int readResult;
186 volatile NGIOReadMethodType readBytes;
189 readBytes = (NGIOReadMethodType)
190 [(NSObject *)_in methodForSelector:@selector(readBytes:count:)];
196 *(&readResult) = (unsigned)readBytes(_in, @selector(readBytes:count:),
199 if (readResult == NGStreamError) {
200 /* TODO: improve exception handling ... */
201 [[(id)_in lastException] raise];
203 else if (readResult == toBeRead) {
204 // all bytes were read successfully, return
208 if (readResult < 1) {
209 [NSException raise:NSInternalInconsistencyException
210 format:@"readBytes:count: returned a value < 1"];
213 toBeRead -= readResult;
218 if ([localException isKindOfClass:[NGEndOfStreamException class]]) {
219 [[[NGEndOfStreamException alloc]
220 initWithStream:(id)_in
221 readCount:(_len - toBeRead)
223 data:[NSData dataWithBytes:_buf
224 length:(_len - toBeRead)]]
228 [localException raise];
235 BOOL NGSafeWriteBytesToStream(id<NGOutputStream> _o,const void *_b,unsigned _l) {
236 int toBeWritten = _l;
238 void *pos = (void *)_b;
239 NGIOWriteMethodType writeBytes;
241 writeBytes = (NGIOWriteMethodType)
242 [(NSObject *)_o methodForSelector:@selector(writeBytes:count:)];
246 (int)writeBytes(_o, @selector(writeBytes:count:), pos, toBeWritten);
248 if (writeResult == NGStreamError) {
249 /* remember number of written bytes ??? */
252 else if (writeResult == toBeWritten) {
253 // all bytes were written successfully, return
257 if (writeResult < 1) {
258 [NSException raise:NSInternalInconsistencyException
259 format:@"writeBytes:count: returned a value<1 in %@", _o];
262 toBeWritten -= writeResult;