Overview
Comment: | Better hiding of the internal OFStream methods. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
2a9e91b67cf178e251d17ea87a74aba2 |
User & Date: | js on 2010-04-09 14:59:30 |
Other Links: | manifest | tags |
Context
2010-04-09
| ||
15:12 | Add OFSeekableStream and implement seeking for OFFile. check-in: 0890f73f75 user: js tags: trunk | |
14:59 | Better hiding of the internal OFStream methods. check-in: 2a9e91b67c user: js tags: trunk | |
00:55 | Add an optional write cache to OFStream. check-in: 66c1d7718d user: js tags: trunk | |
Changes
Modified src/OFFile.m from [a377c2db9b] to [77172f2547].
︙ | ︙ | |||
219 220 221 222 223 224 225 | self = [super init]; fd = fd_; return self; } | < < < < < < < < | | | | | > > > > > > > > | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | self = [super init]; fd = fd_; return self; } - (BOOL)_atEndOfStream { if (fd == -1) return YES; return eos; } - (size_t)_readNBytes: (size_t)size intoBuffer: (char*)buf { size_t ret; if (fd == -1 || eos) @throw [OFReadFailedException newWithClass: isa size: size]; if ((ret = read(fd, buf, size)) == 0) eos = YES; return ret; } - (size_t)_writeNBytes: (size_t)size fromBuffer: (const char*)buf { size_t ret; if (fd == -1 || eos || (ret = write(fd, buf, size)) < size) @throw [OFWriteFailedException newWithClass: isa size: size]; return ret; } - close { if (fd != -1) close(fd); fd = -1; return self; } - (void)dealloc { if (closable && fd != -1) close(fd); [super dealloc]; } @end /// \cond internal @implementation OFFileSingleton - initWithPath: (OFString*)path mode: (OFString*)mode { |
︙ | ︙ |
Modified src/OFSocket.m from [df33a24aa3] to [3f6d8a7208].
︙ | ︙ | |||
41 42 43 44 45 46 47 | #endif + socket { return [[[self alloc] init] autorelease]; } | | | | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #endif + socket { return [[[self alloc] init] autorelease]; } - (BOOL)_atEndOfStream { return eos; } - (size_t)_readNBytes: (size_t)size intoBuffer: (char*)buf { ssize_t ret; if (sock == INVALID_SOCKET || eos) @throw [OFNotConnectedException newWithClass: isa]; if ((ret = recv(sock, buf, size, 0)) < 0) @throw [OFReadFailedException newWithClass: isa]; if (ret == 0) eos = YES; return ret; } - (size_t)_writeNBytes: (size_t)size fromBuffer: (const char*)buf { ssize_t ret; if (sock == INVALID_SOCKET) @throw [OFNotConnectedException newWithClass: isa]; if ((ret = send(sock, buf, size, 0)) == -1) |
︙ | ︙ |
Modified src/OFStream.h from [f77e6ede23] to [9b81961a45].
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #import "OFObject.h" @class OFString; @class OFDataArray; /** * \brief A base class for different types of streams. */ @interface OFStream: OFObject { char *cache, *wcache; size_t cache_len, wcache_len; BOOL use_wcache; } /** * Returns a boolean whether the end of the stream has been reached. * | > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #import "OFObject.h" @class OFString; @class OFDataArray; /** * \brief A base class for different types of streams. * * IMPORTANT: If you want to subclass this, override _readNBytes:intoBuffer:, * _writeNBytes:fromBuffer: and _atEndOfStream, but nothing else. Those are not * defined in the headers, but do the actual work. OFStream uses those and does * all the caching and other stuff. If you override these methods without the * _ prefix, you *WILL* break caching and get broken results! */ @interface OFStream: OFObject { char *cache, *wcache; size_t cache_len, wcache_len; BOOL use_wcache; } /** * Returns a boolean whether the end of the stream has been reached. * * \return A boolean whether the end of the stream has been reached */ - (BOOL)atEndOfStream; /** * Reads at most size bytes from the stream into a buffer. * * \param buf The buffer into which the data is read * \param size The size of the data that should be read at most. * The buffer MUST be at least size big! * \return The number of bytes read */ - (size_t)readNBytes: (size_t)size intoBuffer: (char*)buf; /** * Reads exactly size bytes from the stream into a buffer. Unlike * readNBytes:intoBuffer:, this method does not return when less than the * specified size has been read - instead, it waits until it got exactly size * bytes. * * \param buf The buffer into which the data is read |
︙ | ︙ | |||
180 181 182 183 184 185 186 | * Writes everything in the write cache to the stream. */ - flushWriteCache; /** * Writes from a buffer into the stream. * | < < < < < < < < < < < < < < < < < | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | * Writes everything in the write cache to the stream. */ - flushWriteCache; /** * Writes from a buffer into the stream. * * \param buf The buffer from which the data is written to the stream * \param size The size of the data that should be written * \return The number of bytes written */ - (size_t)writeNBytes: (size_t)size fromBuffer: (const char*)buf; /** * Writes an uint8_t into the stream. * * \param int8 An uint8_t */ - (void)writeInt8: (uint8_t)int8; |
︙ | ︙ |
Modified src/OFStream.m from [15f17faee6] to [62c939ae2f].
︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 | selector: _cmd]; cache = NULL; wcache = NULL; return self; } - (BOOL)atEndOfStream { if (cache != NULL) return NO; | > > > > > > > > > > > > > > > > > > > > < < < | < < < | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | selector: _cmd]; cache = NULL; wcache = NULL; return self; } - (BOOL)_atEndOfStream { @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; } - (size_t)_readNBytes: (size_t)size intoBuffer: (char*)buf { @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; } - (size_t)_writeNBytes: (size_t)size fromBuffer: (const char*)buf { @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; } - (BOOL)atEndOfStream { if (cache != NULL) return NO; return [self _atEndOfStream]; } - (size_t)readNBytes: (size_t)size intoBuffer: (char*)buf { if (cache == NULL) return [self _readNBytes: size intoBuffer: buf]; if (size >= cache_len) { size_t ret = cache_len; memcpy(buf, cache, cache_len); [self freeMemory: cache]; cache = NULL; |
︙ | ︙ | |||
82 83 84 85 86 87 88 | cache = tmp; cache_len -= size; return size; } } | < < < < < < < | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | cache = tmp; cache_len -= size; return size; } } - (void)readExactlyNBytes: (size_t)size intoBuffer: (char*)buf { size_t len = 0; while (len < size) len += [self readNBytes: size - len |
︙ | ︙ | |||
231 232 233 234 235 236 237 | } /* Read until we get a newline or \0 */ tmp = [self allocMemoryWithSize: of_pagesize]; @try { for (;;) { | | | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | } /* Read until we get a newline or \0 */ tmp = [self allocMemoryWithSize: of_pagesize]; @try { for (;;) { if ([self _atEndOfStream]) { if (cache == NULL) return nil; ret_len = cache_len; if (ret_len > 0 && cache[ret_len - 1] == '\r') ret_len--; ret = [OFString stringWithCString: cache encoding: encoding length: ret_len]; [self freeMemory: cache]; cache = NULL; cache_len = 0; return ret; } len = [self _readNBytes: of_pagesize intoBuffer: tmp]; /* Look if there's a newline or \0 */ for (i = 0; i < len; i++) { if (OF_UNLIKELY(tmp[i] == '\n' || tmp[i] == '\0')) { ret_len = cache_len + i; ret_c = [self |
︙ | ︙ | |||
372 373 374 375 376 377 378 | } /* Read until we get the delimiter or \0 */ tmp = [self allocMemoryWithSize: of_pagesize]; @try { for (;;) { | | | | | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | } /* Read until we get the delimiter or \0 */ tmp = [self allocMemoryWithSize: of_pagesize]; @try { for (;;) { if ([self _atEndOfStream]) { if (cache == NULL) return nil; ret = [OFString stringWithCString: cache encoding: encoding length: cache_len]; [self freeMemory: cache]; cache = NULL; cache_len = 0; return ret; } len = [self _readNBytes: of_pagesize intoBuffer: tmp]; /* Look if there's the delimiter or \0 */ for (i = 0; i < len; i++) { if (tmp[i] != delim[j++]) j = 0; if (j == delim_len || tmp[i] == '\0') { |
︙ | ︙ | |||
465 466 467 468 469 470 471 | use_wcache = YES; return self; } - flushWriteCache { | | | | | < < < < < < < | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 | use_wcache = YES; return self; } - flushWriteCache { [self _writeNBytes: wcache_len fromBuffer: wcache]; [self freeMemory: wcache]; wcache = NULL; wcache_len = 0; use_wcache = NO; return self; } - (size_t)writeNBytes: (size_t)size fromBuffer: (const char*)buf { if (!use_wcache) return [self _writeNBytes: size fromBuffer: buf]; else { wcache = [self resizeMemory: wcache toSize: wcache_len + size]; memcpy(wcache + wcache_len, buf, size); wcache_len += size; return size; } } - (void)writeInt8: (uint8_t)int8 { [self writeNBytes: 1 fromBuffer: (char*)&int8]; } - (void)writeBigEndianInt16: (uint16_t)int16 |
︙ | ︙ |
Modified tests/OFStreamTests.m from [f89e698465] to [837d422c65].
︙ | ︙ | |||
24 25 26 27 28 29 30 | @interface StreamTester: OFStream { int state; } @end @implementation StreamTester | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | @interface StreamTester: OFStream { int state; } @end @implementation StreamTester - (BOOL)_atEndOfStream { return (state > 1 ? YES : NO); } - (size_t)_readNBytes: (size_t)size intoBuffer: (char*)buf { switch (state) { case 0: if (size < 1) return 0; memcpy(buf, "f", 1); |
︙ | ︙ |