From 8e3ef39a5ad99ecd3c46ae4ee7272ade8c29fb48 Mon Sep 17 00:00:00 2001 From: Andrew McCallum Date: Tue, 17 Sep 1996 20:41:37 +0000 Subject: [PATCH] Patch from Adam Fedor. See ChangeLog. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1789 72102866-910b-0410-8b05-ffd578937521 --- Headers/gnustep/base/Stream.h | 2 ++ Headers/gnustep/base/Streaming.h | 8 +++++ Source/Makefile.in | 2 ++ Source/MemoryStream.m | 32 +++++++++++++---- Source/StdioStream.m | 60 ++++++++++++++++++-------------- Source/Stream.m | 18 ++++++++-- 6 files changed, 85 insertions(+), 37 deletions(-) diff --git a/Headers/gnustep/base/Stream.h b/Headers/gnustep/base/Stream.h index 0fe76a83d..fd7be2fd3 100644 --- a/Headers/gnustep/base/Stream.h +++ b/Headers/gnustep/base/Stream.h @@ -27,6 +27,8 @@ #include #include +extern id StreamException; + @interface Stream : NSObject - init; diff --git a/Headers/gnustep/base/Streaming.h b/Headers/gnustep/base/Streaming.h index 33cde17a8..8e03a253e 100644 --- a/Headers/gnustep/base/Streaming.h +++ b/Headers/gnustep/base/Streaming.h @@ -56,10 +56,18 @@ @end +typedef enum _seek_mode_t +{ + STREAM_SEEK_FROM_START, + STREAM_SEEK_FROM_CURRENT, + STREAM_SEEK_FROM_END +} seek_mode_t; + @protocol SeekableStreaming - (void) rewindStream; - (void) setStreamPosition: (unsigned)i; +- (void) setStreamPosition: (unsigned)i seekMode: (seek_mode_t)mode; @end diff --git a/Source/Makefile.in b/Source/Makefile.in index ec3627a3d..f11020d74 100644 --- a/Source/Makefile.in +++ b/Source/Makefile.in @@ -174,6 +174,7 @@ Time.m \ UdpPort.m \ behavior.m \ lex.pl.m \ +objc_streams.m \ o_array.m \ o_array_bas.m \ o_array_cbs.m \ @@ -295,6 +296,7 @@ include/behavior.h \ include/fake-main.h \ include/mframe.h \ include/numbers.h \ +include/objc_streams.h \ include/o_array.h \ include/o_array_bas.h \ include/o_array_cbs.h \ diff --git a/Source/MemoryStream.m b/Source/MemoryStream.m index c5a3666c6..e10798f81 100644 --- a/Source/MemoryStream.m +++ b/Source/MemoryStream.m @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,11 @@ enum { #define DEFAULT_MEMORY_STREAM_SIZE 64 +#define MEMORY_CHECK(buffer) \ + if (!buffer) \ + [NSException raise: StreamException \ + format: @"Virtual memory exhausted"] + extern int o_vscanf (void *stream, int (*inchar_func)(void*), @@ -90,6 +96,7 @@ static BOOL debug_memory_stream = NO; { char *b; OBJC_MALLOC(b, char, s); + MEMORY_CHECK(b); return [self _initOnMallocBuffer:b size:s eofPosition:i prefix:p position:i]; } @@ -139,6 +146,7 @@ static BOOL debug_memory_stream = NO; { size = MAX(prefix+position+l, size*2); buffer = objc_realloc (buffer, size); + MEMORY_CHECK(buffer); } memcpy(buffer+prefix+position, b, l); position += l; @@ -198,10 +206,10 @@ void unchar_func(void *s, int c) } #if HAVE_VSPRINTF -- (int) writeFormat: (id )format, ... +- (int) writeFormat: (id )format + arguments: (va_list)arg { int ret; - va_list ap; /* xxx Using this ugliness we at least let ourselves safely print formatted strings up to 128 bytes long. @@ -211,9 +219,7 @@ void unchar_func(void *s, int c) if (size - (prefix + position) < 128) [self setStreamBufferCapacity:size*2]; - va_start(ap, format); - ret = vsprintf(buffer+prefix+position, [format cStringNoCopy], ap); - va_end(ap); + ret = vsprintf(buffer+prefix+position, [format cStringNoCopy], arg); position += ret; /* xxx Make sure we didn't overrun our buffer. As per above kludge, this would happen if we happen to have more than @@ -243,9 +249,20 @@ void unchar_func(void *s, int c) return ret; } -- (void) setStreamPosition: (unsigned)i +- (void) setStreamPosition: (unsigned)i seekMode: (seek_mode_t)mode { - position = i; + switch (mode) + { + case STREAM_SEEK_FROM_START: + position = i; + break; + case STREAM_SEEK_FROM_CURRENT: + position += i; + break; + case STREAM_SEEK_FROM_END: + position = eofPosition + i; + break; + } } - (unsigned) streamPosition @@ -287,6 +304,7 @@ void unchar_func(void *s, int c) if (s > prefix + eofPosition) { buffer = objc_realloc (buffer, s); + MEMORY_CHECK(buffer); size = s; } } diff --git a/Source/StdioStream.m b/Source/StdioStream.m index fd74c00ef..a8428d007 100644 --- a/Source/StdioStream.m +++ b/Source/StdioStream.m @@ -26,8 +26,7 @@ #include #include #include - -/* xxx I should test return values of all functions on the FILE*. */ +#include enum { STREAM_READONLY = 0, @@ -105,14 +104,26 @@ o_vscanf (void *stream, - initWithFilename: (id )name fmode: (const char *)m { FILE *afp = fopen([name cStringNoCopy], (char*)m); - /* xxx Add error checking. */ + if (!afp) + { + /* xxxFIXME: should be NSLog */ + perror("Stream"); + [super dealloc]; + return nil; + } return [self initWithFilePointer:afp fmode:m]; } - initWithFileDescriptor: (int)fd fmode: (const char *)m { FILE *afp = fdopen(fd, (char*)m); - /* xxx Add error checking. */ + if (!afp) + { + /* xxxFIXME: should be NSLog */ + perror("Stream"); + [super dealloc]; + return nil; + } return [self initWithFilePointer:afp fmode:m]; } @@ -137,40 +148,35 @@ o_vscanf (void *stream, - (int) writeBytes: (const void*)b length: (int)len { - /* xxx Check error conditions. */ int ret = fwrite (b, 1, len, fp); - if (ret != len) - printf ("Write bytes differ.\n"); - assert (ret == len); + if (ferror(fp)) + { + [NSException raise: StreamException + format: @"%s", strerror(errno)]; + } + else if (ret != len) + { + [NSException raise: StreamException + format: @"Write bytes differ"]; + } return ret; } - (int) readBytes: (void*)b length: (int)len { - /* xxx Check error conditions. */ int ret = fread (b, 1, len, fp); -#if 0 /* No. Sometimes we don't get as much as we asked for, and that ok. */ - if (ret != len) + if (ferror(fp)) { - printf ("Read bytes differ.\n"); - if (feof (fp)) - [NSException raise: NSGenericException - format: @"Tried to read from eof"]; + [NSException raise: StreamException + format: @"%s", strerror(errno)]; } - assert (ret == len); -#endif return ret; } -- (int) writeFormat: (id )format, ... +- (int) writeFormat: (id )format + arguments: (va_list)arg { - int ret; - va_list ap; - - va_start(ap, format); - ret = vfprintf(fp, [format cStringNoCopy], ap); - va_end(ap); - return ret; + return vfprintf(fp, [format cStringNoCopy], arg); } static int @@ -232,9 +238,9 @@ stdio_unchar_func(void *s, int c) rewind(fp); } -- (void) setStreamPosition: (unsigned)i +- (void) setStreamPosition: (unsigned)i seekMode: (seek_mode_t)m { - fseek(fp, i, 0); + fseek(fp, i, m + SEEK_SET - STREAM_SEEK_FROM_START); } - (unsigned) streamPosition diff --git a/Source/Stream.m b/Source/Stream.m index 9a2f12cfc..b9a4ae503 100644 --- a/Source/Stream.m +++ b/Source/Stream.m @@ -27,6 +27,8 @@ #include #include +NSString* StreamException = @"StreamException"; + @implementation Stream /* This is the designated initializer. */ @@ -66,8 +68,13 @@ - (int) writeFormat: (id )format, ... { - [self subclassResponsibility:_cmd]; - return 0; + int ret; + va_list ap; + + va_start(ap, format); + ret = [self writeFormat: format arguments: ap]; + va_end(ap); + return ret; } - (int) readFormat: (id )format @@ -112,11 +119,16 @@ return NO; } -- (void) setStreamPosition: (unsigned)i +- (void) setStreamPosition: (unsigned)i seekMode: (seek_mode_t)mode { [self subclassResponsibility:_cmd]; } +- (void) setStreamPosition: (unsigned)i +{ + [self setStreamPosition: i seekMode: STREAM_SEEK_FROM_START]; +} + - (void) rewindStream { [self setStreamPosition:0];