~ubuntu-branches/ubuntu/edgy/sope/edgy

« back to all changes in this revision

Viewing changes to sope-core/NGStreams/NGDataStream.m

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Ley
  • Date: 2005-08-19 16:53:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050819165331-hs683wz1osm708pw
Tags: upstream-4.4rc.2
ImportĀ upstreamĀ versionĀ 4.4rc.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "NGDataStream.h"
 
23
#include "NGStreamExceptions.h"
 
24
#include "common.h"
 
25
 
 
26
// TODO: cache -bytes and -length of NSData for immutable data!
 
27
 
 
28
@implementation NGDataStream
 
29
 
 
30
+ (int)version {
 
31
  return [super version] + 2;
 
32
}
 
33
 
 
34
+ (id)dataStream {
 
35
  return [self streamWithData:[NSMutableData dataWithCapacity:1024]];
 
36
}
 
37
+ (id)dataStreamWithCapacity:(int)_capacity {
 
38
  return [self streamWithData:[NSMutableData dataWithCapacity:_capacity]];
 
39
}
 
40
 
 
41
+ (id)streamWithData:(NSData *)_data {
 
42
  return [[[self alloc] initWithData:_data] autorelease];
 
43
}
 
44
- (id)initWithData:(NSData *)_data mode:(NGStreamMode)_mode {
 
45
  if ((self = [super init])) {
 
46
    self->data     = [_data retain];
 
47
    self->position = 0;
 
48
 
 
49
    if ([self->data respondsToSelector:@selector(methodForSelector:)] == YES) {
 
50
      self->dataLength = (unsigned int(*)(id, SEL))
 
51
                         [self->data methodForSelector:@selector(length)];
 
52
      self->dataBytes  = (const void*(*)(id, SEL))
 
53
                         [self->data methodForSelector:@selector(bytes)];
 
54
    }
 
55
    else {
 
56
      self->dataLength = NULL;
 
57
      self->dataBytes  = NULL;
 
58
    }
 
59
    
 
60
    self->streamMode = _mode;
 
61
 
 
62
    /* for read-only streams */
 
63
    if (self->streamMode == NGStreamMode_readOnly) {
 
64
      self->bytes  = [self->data bytes];
 
65
      self->length = [self->data length];
 
66
    }
 
67
  }
 
68
  return self;
 
69
}
 
70
- (id)initWithData:(NSData *)_data {
 
71
  NGStreamMode smode;
 
72
  
 
73
  smode = [data isKindOfClass:[NSMutableData class]]
 
74
    ? NGStreamMode_readWrite
 
75
    : NGStreamMode_readOnly;
 
76
  return [self initWithData:_data mode:smode];
 
77
}
 
78
 
 
79
- (void)dealloc {
 
80
  [self->data          release];
 
81
  [self->lastException release];
 
82
  [super dealloc];
 
83
}
 
84
 
 
85
/* accessors */
 
86
 
 
87
/* NGTextInputStream */
 
88
 
 
89
- (NSException *)lastException {
 
90
  return self->lastException;
 
91
}
 
92
- (void)setLastException:(NSException *)_exception {
 
93
  ASSIGN(self->lastException, _exception);
 
94
}
 
95
- (void)resetLastException {
 
96
  [self->lastException release];
 
97
  self->lastException = nil;
 
98
}
 
99
 
 
100
- (NSData *)data {
 
101
  return self->data;
 
102
}
 
103
 
 
104
- (unsigned)availableBytes {
 
105
  // returns number of available bytes
 
106
  register unsigned currentLength = 0;
 
107
  
 
108
  if (self->bytes == NULL) {
 
109
    currentLength = (self->dataLength == NULL)
 
110
      ? [self->data length]
 
111
      : self->dataLength(self->data, @selector(length));
 
112
  }
 
113
  else
 
114
    currentLength = self->length;
 
115
  
 
116
  return (currentLength == position)
 
117
    ? 0
 
118
    : (currentLength - position);
 
119
}
 
120
 
 
121
/* primitives */
 
122
 
 
123
- (unsigned)readBytes:(void *)_buf count:(unsigned)_len {
 
124
  // throws
 
125
  //   NGStreamNotOpenException   when the stream is not open
 
126
  //   NGEndOfStreamException     when the end of the stream is reached
 
127
  register unsigned currentLength = 0;
 
128
  
 
129
  if (self->bytes == NULL) {
 
130
    currentLength = (self->dataLength == NULL)
 
131
      ? [self->data length]
 
132
      : self->dataLength(self->data, @selector(length));
 
133
  }
 
134
  else
 
135
    currentLength = self->length;
 
136
 
 
137
  if (self->data == nil) {
 
138
    NSException *e;
 
139
    
 
140
    e = [NGStreamNotOpenException exceptionWithStream:self reason:
 
141
                                    @"tried to read from a data stream "
 
142
                                    @"which was closed"];
 
143
    [self setLastException:e];
 
144
    return NGStreamError;
 
145
  }
 
146
 
 
147
  if (currentLength == position) {
 
148
    [self setLastException:
 
149
            [NGEndOfStreamException exceptionWithStream:self]];
 
150
    return NGStreamError;
 
151
  }
 
152
  {
 
153
    NSRange range;
 
154
    range.location = position;
 
155
 
 
156
    if ((position + _len) > currentLength)
 
157
      range.length = currentLength - position;
 
158
    else
 
159
      range.length = _len;
 
160
 
 
161
    [self->data getBytes:_buf range:range];
 
162
 
 
163
    position += range.length;
 
164
    return range.length;
 
165
  }
 
166
}
 
167
 
 
168
- (int)readByte {
 
169
  register const unsigned char *p;
 
170
  register unsigned int currentLength = 0;
 
171
  int result = 0;
 
172
  
 
173
  if (self->bytes == NULL) {
 
174
    currentLength = (self->dataLength == NULL)
 
175
      ? [self->data length]
 
176
      : self->dataLength(self->data, @selector(length));
 
177
  }
 
178
  else
 
179
    currentLength = self->length;
 
180
  
 
181
  if (currentLength == position)
 
182
    return -1;
 
183
  
 
184
  if (self->bytes == NULL) {
 
185
    p = (self->dataBytes == NULL)
 
186
      ? [self->data bytes]
 
187
      : self->dataBytes(self->data, @selector(bytes));
 
188
  }
 
189
  else
 
190
    p = self->bytes;
 
191
  result = p[self->position];
 
192
  self->position++;
 
193
  return result;
 
194
}
 
195
 
 
196
- (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len {
 
197
  // throws
 
198
  //   NGReadOnlyStreamException when the stream is not writeable
 
199
  //   NGStreamNotOpenException  when the stream is not open
 
200
  
 
201
  if (self->data == nil) {
 
202
    NSException *e;
 
203
 
 
204
    e = [NGStreamNotOpenException exceptionWithStream:self reason:
 
205
                                    @"tried to write to a data stream "
 
206
                                    @"which was closed"];
 
207
    [self setLastException:e];
 
208
    return NGStreamError;
 
209
  }
 
210
  if (!NGCanWriteInStreamMode(streamMode)) {
 
211
    NSException *e;
 
212
    
 
213
    e = [NGReadOnlyStreamException exceptionWithStream:self];
 
214
    [self setLastException:e];
 
215
    return NGStreamError;
 
216
  }
 
217
  [(NSMutableData *)self->data appendBytes:_buf length:_len];
 
218
 
 
219
  return _len;
 
220
}
 
221
 
 
222
- (BOOL)close {
 
223
  ASSIGN(self->lastException, (id)nil);
 
224
  [self->data release]; self->data = nil;
 
225
  position   = 0;
 
226
  streamMode = NGStreamMode_undefined;
 
227
  return YES;
 
228
}
 
229
 
 
230
- (NGStreamMode)mode {
 
231
  return streamMode;
 
232
}
 
233
- (BOOL)isRootStream {
 
234
  return YES;
 
235
}
 
236
 
 
237
// NGPositionableStream
 
238
 
 
239
- (BOOL)moveToLocation:(unsigned)_location {
 
240
  position = _location;
 
241
  return YES;
 
242
}
 
243
- (BOOL)moveByOffset:(int)_delta {
 
244
  position += _delta;
 
245
  return YES;
 
246
}
 
247
 
 
248
/* blocking .. */
 
249
 
 
250
- (BOOL)wouldBlockInMode:(NGStreamMode)_mode {
 
251
  return NO;
 
252
}
 
253
 
 
254
- (id)retain {
 
255
  return [super retain];
 
256
}
 
257
 
 
258
/* bytebuffer / lookahead API */
 
259
 
 
260
- (int)la:(unsigned)_la {
 
261
  register unsigned int currentLength, newpos;
 
262
  register const unsigned char *p;
 
263
  int result = 0;
 
264
  
 
265
  if (self->bytes == NULL) {
 
266
    currentLength = (self->dataLength == NULL)
 
267
      ? [self->data length]
 
268
      : self->dataLength(self->data, @selector(length));
 
269
  }
 
270
  else
 
271
    currentLength = self->length;
 
272
  
 
273
  if (currentLength == self->position) // already at EOF
 
274
    return -1;
 
275
  
 
276
  newpos = (self->position + _la);
 
277
  if (newpos >= currentLength)
 
278
    return -1; /* a look into EOF */
 
279
  
 
280
  if (self->bytes == NULL) {
 
281
    p = (self->dataBytes == NULL)
 
282
      ? [self->data bytes]
 
283
      : self->dataBytes(self->data, @selector(bytes));
 
284
  }
 
285
  else
 
286
    p = self->bytes;
 
287
  
 
288
  result = p[newpos];
 
289
  return result;
 
290
}
 
291
 
 
292
- (void)consume { // consume one byte
 
293
  register unsigned int currentLength = 0;
 
294
  
 
295
  if (self->bytes == NULL) {
 
296
    currentLength = (self->dataLength == NULL)
 
297
      ? [self->data length]
 
298
      : self->dataLength(self->data, @selector(length));
 
299
  }
 
300
  else
 
301
    currentLength = self->length;
 
302
  
 
303
  if (currentLength == self->position)
 
304
    return;
 
305
  
 
306
  self->position++; // consume
 
307
}
 
308
- (void)consume:(unsigned)_cnt { // consume _cnt bytes
 
309
  register unsigned int currentLength = 0;
 
310
 
 
311
  if (self->bytes == NULL) {
 
312
    currentLength = (self->dataLength == NULL)
 
313
      ? [self->data length]
 
314
      : self->dataLength(self->data, @selector(length));
 
315
  }
 
316
  else
 
317
    currentLength = self->length;
 
318
  
 
319
  if (currentLength == self->position)
 
320
    return;
 
321
  
 
322
  self->position += _cnt; // consume
 
323
  
 
324
  if (self->position > currentLength)
 
325
    self->position = currentLength;
 
326
}
 
327
 
 
328
@end /* NGDataStream */