home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1996 by Lele Gaifax. All Rights Reserved
- *
- * This software may be used and distributed freely for any purpose
- * provided that this notice is included unchanged on any and all
- * copies. The author does not warrant or guarantee this software in
- * any way.
- *
- * This file is part of the PyObjC package.
- *
- * $RCSfile: OC_Stream.m,v $
- * $Revision: 1.1.1.3 $
- * $Date: 1996/10/23 17:19:50 $
- *
- * Created Fri Oct 4 13:38:20 1996.
- */
-
- #include "ObjC.h"
- #include "OC_Stream.h"
-
- #ifndef WITH_FOUNDATION
-
- #include <libc.h>
- #include <streams/streams.h>
-
- #define CLASS_VERSION 0
-
- #define ASSERT_OPEN() if (!stream) NX_RAISE(OC_closedStreamError, NULL, NULL)
- #define ASSERT_SEEKABLE() ASSERT_OPEN(); else if (! stream->flags & NX_CANSEEK) NX_RAISE(OC_nonSeekableStreamError, NULL, NULL)
- #define ASSERT_READABLE() ASSERT_OPEN(); else if (! stream->flags & NX_CANREAD) NX_RAISE(OC_nonReadableStreamError, NULL, NULL)
- #define ASSERT_WRITEABLE() ASSERT_OPEN(); else if (! stream->flags & NX_CANWRITE) NX_RAISE(OC_nonWriteableStreamError, NULL, NULL)
-
- @interface OC_MemoryStream : OC_Stream
- {
- }
-
- + newFromMemory:(void *) mem length:(unsigned int) len;
- + newFromMemory:(void *) mem length:(unsigned int) len withMode:(int) m;
-
- - (void) close;
-
- @end /* OC_MemoryStream class interface */
-
- @interface OC_MappedFileStream : OC_MemoryStream
- {
- }
-
- + newFromFilename:(const char *) name;
- + newFromFilename:(const char *) name withMode:(int) m;
-
- @end /* OC_MappedFileStream class interface */
-
- @implementation OC_Stream
-
- + (void) initialize
- {
- if (self == [OC_Stream class])
- {
- [OC_Stream setVersion:CLASS_VERSION];
- }
- }
-
- + newFromStream:(NXStream *) s
- {
- id instance = [[self alloc] initFromStream:s];
-
- return instance;
- }
-
- + newFromFilename:(const char *) name
- {
- return [OC_MappedFileStream newFromFilename:name];
- }
-
- + newFromFilename:(const char *) name withMode:(int) m
- {
- return [OC_MappedFileStream newFromFilename:name withMode:m];
- }
-
- + newFromMemory:(void *) mem length:(unsigned int) len
- {
- return [OC_MemoryStream newFromMemory:mem length:len withMode:NX_READONLY];
- }
-
- + newFromMemory:(void *) mem length:(unsigned int) len withMode:(int) m
- {
- return [OC_MemoryStream newFromMemory:mem length:len withMode:m];
- }
-
- - initFromStream:(NXStream *) s
- {
- if (s == NULL)
- {
- PyErr_SetString (ObjCStreams_Error, "invalid stream");
- return nil;
- }
-
- [super init];
- stream = s;
- return self;
- }
-
- - (void) freeWhenDone:(BOOL) yn
- {
- freeWhenDone = yn;
- }
-
- - free
- {
- if (freeWhenDone && stream)
- [self close];
- return [super free];
- }
-
- - (BOOL) saveToFilename:(const char *) name
- {
- ASSERT_OPEN();
- if (NXSaveToFile (stream, name) == -1)
- return NO;
- else
- return YES;
- }
-
- - (NXStream *) stream
- {
- return stream;
- }
-
- - (int) readByte:(char *) cp
- {
- char c;
-
- ASSERT_READABLE();
- c = NXGetc (stream);
- if (c != EOF && cp)
- *cp = c;
-
- return c;
- }
-
- - (int) readBytes:(void *) buf length:(unsigned int) len
- {
- ASSERT_READABLE();
- return NXRead (stream, buf, len);
- }
-
- - (int) writeByte:(char) c
- {
- ASSERT_WRITEABLE();
- return NXPutc (stream, c);
- }
-
- - (int) writeBytes:(void *) buf length:(unsigned int) len
- {
- ASSERT_WRITEABLE();
- return NXWrite (stream, buf, len);
- }
-
- - (void) setStreamPosition:(long) pos seekMode:(int) mode
- {
- ASSERT_SEEKABLE();
- NXSeek (stream, pos, mode);
- }
-
- - (long) streamPosition
- {
- ASSERT_OPEN();
- return NXTell (stream);
- }
-
- - (BOOL) isAtEof
- {
- ASSERT_OPEN();
- return NXAtEOS (stream);
- }
-
- - (void) flushStream
- {
- ASSERT_OPEN();
- NXFlush (stream);
- }
-
- - (void) close
- {
- if (stream)
- {
- NXClose (stream);
- stream = NULL;
- }
- }
-
- - (BOOL) isClosed
- {
- return stream == NULL;
- }
-
- - (BOOL) isWritable
- {
- return (stream && stream->flags & NX_CANWRITE);
- }
-
- @end /* OC_Stream class implementation */
-
- @implementation OC_MemoryStream
-
- + newFromMemory:(void *) p length:(unsigned int) l
- {
- return [self newFromMemory:p length:l withMode:NX_READONLY];
- }
-
- + newFromMemory:(void *) p length:(unsigned int) l withMode:(int) m
- {
- BOOL append;
-
- if (m == OCS_APPEND)
- {
- m = NX_READWRITE;
- append = YES;
- }
- else
- append = NO;
-
- if (m != NX_READONLY && (p || l))
- {
- PyErr_SetString (ObjCStreams_Error, "Writable memory stream must be initialized with NULL");
- return nil;
- }
- else
- {
- NXStream *s = NXOpenMemory (p, l, m);
- OC_MemoryStream *instance;
-
- if (s == 0)
- {
- PyErr_SetString (ObjCStreams_Error, "cannot open memory stream");
- return nil;
- }
-
- if (append)
- NXSeek (s, 0, NX_FROMEND);
-
- instance = [[self alloc] initFromStream:s];
- [instance freeWhenDone:YES];
- return instance;
- }
- }
-
- - (void) close
- {
- [super close]; // XXX should free the buffer
- // with vm_deallocate().
- }
-
- @end /* OC_MemoryStream class implementation */
-
- @implementation OC_MappedFileStream
-
- + newFromFilename:(const char *) name
- {
- return [self newFromFilename:name withMode:NX_READONLY];
- }
-
- + newFromFilename:(const char *) name withMode:(int) m
- {
- OC_MappedFileStream *instance;
- NXStream *s;
- BOOL append;
-
- if (m == OCS_APPEND)
- {
- m = NX_READWRITE;
- append = YES;
- }
- else
- append = NO;
-
- s = NXMapFile (name, m);
-
- if (s == 0)
- {
- PyErr_SetString (ObjCStreams_Error, "unable to open file");
- return nil;
- }
-
- if (append)
- NXSeek (s, 0, NX_FROMEND);
-
- instance = [[self alloc] initFromStream:s];
- [instance freeWhenDone:YES];
-
- return instance;
- }
-
- @end /* OC_MappedFileStream implementation */
-
- #else /* WITH_FOUNDATION */
-
- @implementation OC_Stream
-
- + newFromMemory:(void *) p length:(unsigned int) l
- {
- return [self dataWithBytes:p length:l];
- }
-
- + newFromMemory:(void *) p length:(unsigned int) l withMode:(int) m
- {
- if (m == OCS_READONLY)
- return [self dataWithBytes:p length:l];
- else
- {
- [self notImplemented:_cmd];
- return nil;
- }
- }
-
- + newFromFilename:(const char *) name
- {
- [self newFromFilename:name withMode:OCS_READONLY];
- }
-
- + newFromFilename:(const char *) name withMode:(int) m
- {
- id data;
- id path = [NSString stringWithCString:name];
-
- if (m == OCS_READONLY)
- data = [self dataWithContentsOfMappedFile:path];
- else
- {
- [self notImplemented:_cmd];
- data = nil;
- }
-
- return data;
- }
-
- - (BOOL) saveToFilename:(const char *) name
- {
- id path = [NSString stringWithCString:name];
-
- return [self writeToFile:path atomically:NO]; // XXX ???
- }
-
- - (int) readByte:(unsigned char *) cp
- {
- char onebyte;
- NSRange range = (NSRange) { offset, 1 };
-
- if (offset >= [self length])
- return -1;
-
- [self getBytes:&onebyte range:range];
- if (cp)
- *cp = onebyte;
- offset++;
-
- return onebyte;
- }
-
- - (int) readBytes:(void *) buf length:(int) len
- {
- NSRange range;
-
- if (offset >= [self length])
- return -1;
-
- if (offset+len >= [self length])
- len = [self length] - offset;
- range = (NSRange) { offset, len };
-
- [self getBytes:buf range:range];
- offset += len;
-
- return len;
- }
-
- - (int) writeByte:(unsigned char) c
- {
- [self notImplemented:_cmd];
- return -1;
- }
-
- - (int) writeBytes:(const void *) buf length:(int) len
- {
- [self notImplemented:_cmd];
- return -1;
- }
-
- - (void) setStreamPosition:(long) pos seekMode:(int) mode
- {
- switch (mode)
- {
- case OCS_FROMCURRENT:
- pos += offset;
- /* FALLTHROUGH */
-
- case OCS_FROMSTART:
- if (pos >= [self length])
- offset = [self length];
- else
- offset = pos;
- break;
-
- case OCS_FROMEND:
- offset = [self length];
- if (-pos > offset)
- offset = 0;
- else
- offset += pos;
- break;
- }
- }
-
- - (unsigned int) streamPosition
- {
- return offset;
- }
-
- - (BOOL) isAtEof
- {
- return offset == [self length];
- }
-
- - (void) flushStream
- {
- }
-
- - (void) close
- {
- }
-
- - (BOOL) isClosed
- {
- return NO;
- }
-
- - (BOOL) isWritable
- {
- [self notImplemented:_cmd];
- return NO;
- }
-
- - (int) writeFormat: (id <String>)format, ...
- {
- [self notImplemented:_cmd];
- return -1;
- }
-
- - (int) readFormat: (id <String>)format, ...
- {
- [self notImplemented:_cmd];
- return -1;
- }
-
- - (int) writeFormat: (id <String>)format arguments: (va_list)arg
- {
- [self notImplemented:_cmd];
- return -1;
- }
-
- - (int) readFormat: (id <String>)format arguments: (va_list)arg
- {
- [self notImplemented:_cmd];
- return -1;
- }
-
- - (void) writeLine: (id <String>)l
- {
- [self notImplemented:_cmd];
- }
-
- - (id <String>) readLine
- {
- [self notImplemented:_cmd];
- return nil;
- }
-
- @end /* Stream OC_Stream category implementation */
-
- #endif /* GNU_RUNTIME */
-
- /*
- ** Local Variables:
- ** change-log-default-name:"../ChangeLog.PyObjC"
- ** End:
- */
-