home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Languages / python / PyObjC-0.47-MIHS / pyobjc-0.47-src / Modules / OC_Stream.m < prev    next >
Encoding:
Text File  |  1996-10-23  |  8.4 KB  |  486 lines

  1. /* Copyright (c) 1996 by Lele Gaifax.  All Rights Reserved
  2.  *
  3.  * This software may be used and distributed freely for any purpose
  4.  * provided that this notice is included unchanged on any and all
  5.  * copies. The author does not warrant or guarantee this software in
  6.  * any way.
  7.  *
  8.  * This file is part of the PyObjC package.
  9.  *
  10.  * $RCSfile: OC_Stream.m,v $
  11.  * $Revision: 1.1.1.3 $
  12.  * $Date: 1996/10/23 17:19:50 $
  13.  *
  14.  * Created Fri Oct  4 13:38:20 1996.
  15.  */
  16.  
  17. #include "ObjC.h"
  18. #include "OC_Stream.h"
  19.  
  20. #ifndef WITH_FOUNDATION
  21.  
  22. #include <libc.h>
  23. #include <streams/streams.h>
  24.  
  25. #define CLASS_VERSION 0
  26.  
  27. #define ASSERT_OPEN() if (!stream) NX_RAISE(OC_closedStreamError, NULL, NULL)
  28. #define ASSERT_SEEKABLE() ASSERT_OPEN(); else if (! stream->flags & NX_CANSEEK) NX_RAISE(OC_nonSeekableStreamError, NULL, NULL)
  29. #define ASSERT_READABLE() ASSERT_OPEN(); else if (! stream->flags & NX_CANREAD) NX_RAISE(OC_nonReadableStreamError, NULL, NULL)
  30. #define ASSERT_WRITEABLE() ASSERT_OPEN(); else if (! stream->flags & NX_CANWRITE) NX_RAISE(OC_nonWriteableStreamError, NULL, NULL)
  31.  
  32. @interface OC_MemoryStream : OC_Stream
  33. {
  34. }
  35.  
  36. + newFromMemory:(void *) mem length:(unsigned int) len;
  37. + newFromMemory:(void *) mem length:(unsigned int) len withMode:(int) m;
  38.  
  39. - (void) close;
  40.  
  41. @end /* OC_MemoryStream class interface */
  42.  
  43. @interface OC_MappedFileStream : OC_MemoryStream
  44. {
  45. }
  46.  
  47. + newFromFilename:(const char *) name;
  48. + newFromFilename:(const char *) name withMode:(int) m;
  49.  
  50. @end /* OC_MappedFileStream class interface */
  51.  
  52. @implementation OC_Stream
  53.  
  54. + (void) initialize
  55. {
  56.   if (self == [OC_Stream class])
  57.     {
  58.       [OC_Stream setVersion:CLASS_VERSION];
  59.     }
  60. }
  61.  
  62. + newFromStream:(NXStream *) s
  63. {
  64.   id instance = [[self alloc] initFromStream:s];
  65.  
  66.   return instance;
  67. }
  68.  
  69. + newFromFilename:(const char *) name
  70. {
  71.   return [OC_MappedFileStream newFromFilename:name];
  72. }
  73.  
  74. + newFromFilename:(const char *) name withMode:(int) m
  75. {
  76.   return [OC_MappedFileStream newFromFilename:name withMode:m];
  77. }
  78.  
  79. + newFromMemory:(void *) mem length:(unsigned int) len
  80. {
  81.   return [OC_MemoryStream newFromMemory:mem length:len withMode:NX_READONLY];
  82. }
  83.  
  84. + newFromMemory:(void *) mem length:(unsigned int) len withMode:(int) m
  85. {
  86.   return [OC_MemoryStream newFromMemory:mem length:len withMode:m];
  87. }
  88.  
  89. - initFromStream:(NXStream *) s
  90. {
  91.   if (s == NULL)
  92.     {
  93.       PyErr_SetString (ObjCStreams_Error, "invalid stream");
  94.       return nil;
  95.     }
  96.  
  97.   [super init];
  98.   stream = s;
  99.   return self;
  100. }
  101.  
  102. - (void) freeWhenDone:(BOOL) yn
  103. {
  104.   freeWhenDone = yn;
  105. }
  106.  
  107. - free
  108. {
  109.   if (freeWhenDone && stream)
  110.     [self close];
  111.   return [super free];
  112. }
  113.  
  114. - (BOOL) saveToFilename:(const char *) name
  115. {
  116.   ASSERT_OPEN();
  117.   if (NXSaveToFile (stream, name) == -1)
  118.     return NO;
  119.   else
  120.     return YES;
  121. }
  122.  
  123. - (NXStream *) stream
  124. {
  125.   return stream;
  126. }
  127.  
  128. - (int) readByte:(char *) cp
  129. {
  130.   char c;
  131.  
  132.   ASSERT_READABLE();
  133.   c = NXGetc (stream);
  134.   if (c != EOF && cp)
  135.     *cp = c;
  136.  
  137.   return c;
  138. }
  139.  
  140. - (int) readBytes:(void *) buf length:(unsigned int) len
  141. {
  142.   ASSERT_READABLE();
  143.   return NXRead (stream, buf, len);
  144. }
  145.  
  146. - (int) writeByte:(char) c
  147. {
  148.   ASSERT_WRITEABLE();
  149.   return NXPutc (stream, c);
  150. }
  151.  
  152. - (int) writeBytes:(void *) buf length:(unsigned int) len
  153. {
  154.   ASSERT_WRITEABLE();
  155.   return NXWrite (stream, buf, len);
  156. }
  157.  
  158. - (void) setStreamPosition:(long) pos seekMode:(int) mode
  159. {
  160.   ASSERT_SEEKABLE();
  161.   NXSeek (stream, pos, mode);
  162. }
  163.  
  164. - (long) streamPosition
  165. {
  166.   ASSERT_OPEN();
  167.   return NXTell (stream);
  168. }
  169.  
  170. - (BOOL) isAtEof
  171. {
  172.   ASSERT_OPEN();
  173.   return NXAtEOS (stream);
  174. }
  175.  
  176. - (void) flushStream
  177. {
  178.   ASSERT_OPEN();
  179.   NXFlush (stream);
  180. }
  181.  
  182. - (void) close
  183. {
  184.   if (stream)
  185.     {
  186.       NXClose (stream);
  187.       stream = NULL;
  188.     }
  189. }
  190.  
  191. - (BOOL) isClosed
  192. {
  193.   return stream == NULL;
  194. }
  195.  
  196. - (BOOL) isWritable
  197. {
  198.   return (stream && stream->flags & NX_CANWRITE);
  199. }
  200.  
  201. @end /* OC_Stream class implementation */
  202.  
  203. @implementation OC_MemoryStream
  204.  
  205. + newFromMemory:(void *) p length:(unsigned int) l
  206. {
  207.   return [self newFromMemory:p length:l withMode:NX_READONLY];
  208. }
  209.  
  210. + newFromMemory:(void *) p length:(unsigned int) l withMode:(int) m
  211. {
  212.   BOOL append;
  213.  
  214.   if (m == OCS_APPEND)
  215.     {
  216.       m = NX_READWRITE;
  217.       append = YES;
  218.     }
  219.   else
  220.     append = NO;
  221.   
  222.   if (m != NX_READONLY && (p || l))
  223.     {
  224.       PyErr_SetString (ObjCStreams_Error, "Writable memory stream must be initialized with NULL");
  225.       return nil;
  226.     }
  227.   else
  228.     {
  229.       NXStream *s = NXOpenMemory (p, l, m);
  230.       OC_MemoryStream *instance;
  231.       
  232.       if (s == 0)
  233.     {
  234.       PyErr_SetString (ObjCStreams_Error, "cannot open memory stream");
  235.       return nil;
  236.     }
  237.  
  238.       if (append)
  239.     NXSeek (s, 0, NX_FROMEND);
  240.       
  241.       instance = [[self alloc] initFromStream:s];
  242.       [instance freeWhenDone:YES];
  243.       return instance;
  244.     }
  245. }
  246.  
  247. - (void) close
  248. {
  249.   [super close];        // XXX should free the buffer
  250.                 // with vm_deallocate().
  251. }
  252.  
  253. @end /* OC_MemoryStream class implementation */
  254.  
  255. @implementation OC_MappedFileStream
  256.  
  257. + newFromFilename:(const char *) name
  258. {
  259.   return [self newFromFilename:name withMode:NX_READONLY];
  260. }
  261.  
  262. + newFromFilename:(const char *) name withMode:(int) m
  263. {
  264.   OC_MappedFileStream *instance;
  265.   NXStream *s;
  266.   BOOL append;
  267.   
  268.   if (m == OCS_APPEND)
  269.     {
  270.       m = NX_READWRITE;
  271.       append = YES;
  272.     }
  273.   else
  274.     append = NO;
  275.   
  276.   s = NXMapFile (name, m);
  277.  
  278.   if (s == 0)
  279.     {
  280.       PyErr_SetString (ObjCStreams_Error, "unable to open file");
  281.       return nil;
  282.     }
  283.  
  284.   if (append)
  285.     NXSeek (s, 0, NX_FROMEND);
  286.   
  287.   instance = [[self alloc] initFromStream:s];
  288.   [instance freeWhenDone:YES];
  289.  
  290.   return instance;
  291. }
  292.  
  293. @end /* OC_MappedFileStream implementation */
  294.  
  295. #else /* WITH_FOUNDATION */
  296.  
  297. @implementation OC_Stream
  298.  
  299. + newFromMemory:(void *) p length:(unsigned int) l
  300. {
  301.   return [self dataWithBytes:p length:l];
  302. }
  303.  
  304. + newFromMemory:(void *) p length:(unsigned int) l withMode:(int) m
  305. {
  306.   if (m == OCS_READONLY)
  307.     return [self dataWithBytes:p length:l];
  308.   else
  309.     {
  310.       [self notImplemented:_cmd];
  311.       return nil;
  312.     }
  313. }
  314.  
  315. + newFromFilename:(const char *) name
  316. {
  317.   [self newFromFilename:name withMode:OCS_READONLY];
  318. }
  319.  
  320. + newFromFilename:(const char *) name withMode:(int) m
  321. {
  322.   id data;
  323.   id path = [NSString stringWithCString:name];
  324.   
  325.   if (m == OCS_READONLY)
  326.     data = [self dataWithContentsOfMappedFile:path];
  327.   else
  328.     {
  329.       [self notImplemented:_cmd];
  330.       data = nil;
  331.     }
  332.  
  333.   return data;
  334. }
  335.  
  336. - (BOOL) saveToFilename:(const char *) name
  337. {
  338.   id path = [NSString stringWithCString:name];
  339.  
  340.   return [self writeToFile:path atomically:NO]; // XXX ???
  341. }
  342.  
  343. - (int) readByte:(unsigned char *) cp
  344. {
  345.   char onebyte;
  346.   NSRange range = (NSRange) { offset, 1 };
  347.  
  348.   if (offset >= [self length])
  349.     return -1;
  350.   
  351.   [self getBytes:&onebyte range:range];
  352.   if (cp)
  353.     *cp = onebyte;
  354.   offset++;
  355.   
  356.   return onebyte;
  357. }
  358.  
  359. - (int) readBytes:(void *) buf length:(int) len
  360. {
  361.   NSRange range;
  362.  
  363.   if (offset >= [self length])
  364.     return -1;
  365.  
  366.   if (offset+len >= [self length])
  367.     len = [self length] - offset;
  368.   range = (NSRange) { offset, len };
  369.   
  370.   [self getBytes:buf range:range];
  371.   offset += len;
  372.  
  373.   return len;
  374. }
  375.  
  376. - (int) writeByte:(unsigned char) c
  377. {
  378.   [self notImplemented:_cmd];
  379.   return -1;
  380. }
  381.  
  382. - (int) writeBytes:(const void *) buf length:(int) len
  383. {
  384.   [self notImplemented:_cmd];
  385.   return -1;
  386. }
  387.  
  388. - (void) setStreamPosition:(long) pos seekMode:(int) mode
  389. {
  390.   switch (mode)
  391.     {
  392.     case OCS_FROMCURRENT:
  393.       pos += offset;
  394.       /* FALLTHROUGH */
  395.       
  396.     case OCS_FROMSTART:
  397.       if (pos >= [self length])
  398.     offset = [self length];
  399.       else
  400.     offset = pos;
  401.       break;
  402.  
  403.     case OCS_FROMEND:
  404.       offset = [self length];
  405.       if (-pos > offset)
  406.     offset = 0;
  407.       else
  408.     offset += pos;
  409.       break;
  410.     }
  411. }
  412.       
  413. - (unsigned int) streamPosition
  414. {
  415.   return offset;
  416. }
  417.  
  418. - (BOOL) isAtEof
  419. {
  420.   return offset == [self length];
  421. }
  422.  
  423. - (void) flushStream
  424. {
  425. }
  426.  
  427. - (void) close
  428. {
  429. }
  430.  
  431. - (BOOL) isClosed
  432. {
  433.   return NO;
  434. }
  435.  
  436. - (BOOL) isWritable
  437. {
  438.   [self notImplemented:_cmd];
  439.   return NO;
  440. }
  441.  
  442. - (int) writeFormat: (id <String>)format, ...
  443. {
  444.   [self notImplemented:_cmd];
  445.   return -1;
  446. }
  447.  
  448. - (int) readFormat: (id <String>)format, ...
  449. {
  450.   [self notImplemented:_cmd];
  451.   return -1;
  452. }
  453.   
  454. - (int) writeFormat: (id <String>)format arguments: (va_list)arg
  455. {
  456.   [self notImplemented:_cmd];
  457.   return -1;
  458. }
  459.  
  460. - (int) readFormat: (id <String>)format arguments: (va_list)arg
  461. {
  462.   [self notImplemented:_cmd];
  463.   return -1;
  464. }
  465.  
  466. - (void) writeLine: (id <String>)l
  467. {
  468.   [self notImplemented:_cmd];
  469. }
  470.  
  471. - (id <String>) readLine
  472. {
  473.   [self notImplemented:_cmd];
  474.   return nil;
  475. }
  476.  
  477. @end /* Stream OC_Stream category implementation */
  478.  
  479. #endif /* GNU_RUNTIME */
  480.  
  481. /*
  482. ** Local Variables:
  483. ** change-log-default-name:"../ChangeLog.PyObjC"
  484. ** End:
  485. */
  486.