[PATCH] Move FileDescriptor under Stream

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Move FileDescriptor under Stream

Paolo Bonzini-2
Most of the PositionableStream functionality is provided also by Stream
nowadays; the rest is all rewritten by the FileDescriptor and FileStream
classes.  So, it makes no sense anymore to leave Stream under
ReadWriteStream.

This cleanup allows to implement #nextPutAllOn: on PositionableStream
without the need to override it in FileDescriptor, so this patch does
that too.

(This patch was preceded by another one, to remove ByteStream; I'm not
posting that one because it's a stupid change that moves around a lot
of code).

Paolo


2008-08-05  Paolo Bonzini  <[hidden email]>

        * kernel/FileDescr.st: Make a subclass of Stream.
        * kernel/FileStream.st: Add here the creation of the buffer.
        * kernel/PosStream.st: Implement #nextPutAllOn:.  Move
        #skipSeparators...
        * kernel/StreamOps.st: ... here.

libgst:
2008-08-05  Paolo Bonzini  <[hidden email]>

        * dict.c: Adjust layout of FileDescriptor and FileStream.  Do not
        fill in FileStream variables in FileDescriptors.
        * dict.h: Likewise.  Match FileDescriptor instance variable names
        in gst_file_stream.
        * prims.def: Adjust renamed instance variables.

diff --git a/NEWS b/NEWS
index b40b42a..6dfc10d 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,8 @@ o   FileDescriptor and FileStream raise an exception if #next: cannot
     which is similar to #nextHunk but returns at most the number of bytes
     given by the argument.
 
+o   FileDescriptor is now a subclass of Stream.
+
 o   ObjectMemory>>#snapshot and ObjectMemory>>#snapshot: return false in
     the instance of GNU Smalltalk that produced the snapshot, and
     true in the instance of GNU Smalltalk that was restored from the
diff --git a/kernel/FileDescr.st b/kernel/FileDescr.st
index 9734d2a..a2da2f5 100644
--- a/kernel/FileDescr.st
+++ b/kernel/FileDescr.st
@@ -32,8 +32,8 @@
 
 
 
-ReadWriteStream subclass: FileDescriptor [
-    | fd file isPipe atEnd peek |
+Stream subclass: FileDescriptor [
+    | access fd file isPipe atEnd peek |
     
     <category: 'Streams-Files'>
     <comment: 'My instances are what conventional programmers think of as files.
@@ -334,22 +334,19 @@ do arbitrary processing on the files.'>
  "Return the next character in the file, or nil at eof"
 
  <category: 'basic'>
- | result |
+ | result data |
  peek isNil
     ifFalse:
- [collection at: 1 put: peek.
+ [data := peek.
  peek := nil.
  result := 1]
     ifTrue:
- [result := self
-    read: collection
-    from: 1
-    to: 1].
+ [data := self species new: 1.
+ result := self read: data from: 1 to: 1.
+ data := data at: 1].
  ^result > 0
-    ifTrue: [collection at: 1]
-    ifFalse:
- [atEnd := true.
- self pastEnd]
+    ifTrue: [data]
+    ifFalse: [atEnd := true.  self pastEnd]
     ]
 
     peekFor: anObject [
@@ -368,14 +365,12 @@ do arbitrary processing on the files.'>
  Returns nil when at end of stream."
 
  <category: 'basic'>
- | result |
+ | result data |
  peek isNil ifFalse: [^peek].
- result := self
-    read: collection
-    from: 1
-    to: 1.
+ data := self species new: 1.
+ result := self read: data from: 1 to: 1.
  ^result > 0
-    ifTrue: [peek := collection at: 1]
+    ifTrue: [peek := data at: 1]
     ifFalse:
  [atEnd := true.
  self pastEnd]
@@ -758,20 +753,10 @@ do arbitrary processing on the files.'>
 
  <category: 'initialize-release'>
  self addToBeFinalized.
- collection := self newBuffer.
- ptr := 1.
- endPtr := 0.
  access isNil ifTrue: [access := 3].
  atEnd := false
     ]
 
-    newBuffer [
- "Private - Answer a String to be used as the receiver's buffer"
-
- <category: 'initialize-release'>
- ^String new: 1
-    ]
-
     readStream [
  "Answer myself, or an alternate stream coerced for reading."
  <category: 'initialize-release'>
@@ -807,7 +792,7 @@ do arbitrary processing on the files.'>
 
  <category: 'low-level access'>
  | count answer |
- count := self read: (answer := String new: 1024).
+ count := self read: (answer := self species new: 1024).
  count < answer size ifTrue: [answer := answer copyFrom: 1 to: count].
  count = 0
     ifTrue:
@@ -1207,5 +1192,18 @@ do arbitrary processing on the files.'>
  int := int bitShift: -8.
  (int = 0 and: [anInteger < 0]) ifTrue: [int := 255]]
     ]
+
+    species [
+ <category: 'private'>
+ ^String
+    ]
+
+    isPositionable [
+ "Answer true if the stream supports moving backwards with #skip:."
+
+ <category: 'positioning'>
+ ^true
+    ]
+
 ]
 
diff --git a/kernel/FileStream.st b/kernel/FileStream.st
index 5da19fe..7bbab64 100644
--- a/kernel/FileStream.st
+++ b/kernel/FileStream.st
@@ -33,7 +33,7 @@
 
 
 FileDescriptor subclass: FileStream [
-    | writePtr writeEnd |
+    | collection ptr endPtr writePtr writeEnd |
     
     <category: 'Streams-Files'>
     <comment: 'My instances are what conventional programmers think of as files.
@@ -521,7 +521,7 @@ file object, such as /dev/rmt0 on UNIX or MTA0: on VMS).'>
  "Answer whether data has come to an end"
 
  <category: 'testing'>
- ^self basicAtEnd and: [super atEnd]
+ ^ptr > endPtr and: [super atEnd]
     ]
 
     bufferSize [
@@ -539,11 +539,21 @@ file object, such as /dev/rmt0 on UNIX or MTA0: on VMS).'>
  collection := self species new: bufSize
     ]
 
+    initialize [
+        "Initialize the receiver's instance variables"
+
+        <category: 'initialize-release'>
+        super initialize.
+        collection := self newBuffer.
+        ptr := 1.
+        endPtr := 0.
+    ]
+
     newBuffer [
  "Private - Answer a String to be used as the receiver's buffer"
 
  <category: 'buffering'>
- ^String new: 1024
+ ^self species new: 1024
     ]
 
     flush [
diff --git a/kernel/PosStream.st b/kernel/PosStream.st
index a10469a..1f9d78b 100644
--- a/kernel/PosStream.st
+++ b/kernel/PosStream.st
@@ -81,6 +81,13 @@ or ReadWriteStream instead of me to create and use streams.'>
  ^element
     ]
 
+    nextPutAllOn: aStream [
+ "Write all the objects in the receiver to aStream."
+
+ (access bitAnd: 1) = 0 ifTrue: [^self shouldNotImplement].
+ aStream next: endPtr putAll: collection startingAt: 1.
+    ]
+
     peek [
  "Returns the next element of the stream without moving the pointer.
  Returns nil when at end of stream."
@@ -177,22 +184,6 @@ or ReadWriteStream instead of me to create and use streams.'>
     ifFalse: [endPtr := ptr - 1]
     ]
 
-    skipSeparators [
- "Advance the receiver until we find a character that is not a
- separator.  Answer false if we reach the end of the stream,
- else answer true; in this case, sending #next will return the
- first non-separator character (possibly the same to which the
- stream pointed before #skipSeparators was sent)."
-
- <category: 'positioning'>
- | ch |
-
- [(ch := self peek) isNil ifTrue: [^false].
- ch isSeparator]
- whileTrue: [self next].
- ^true
-    ]
-
     position [
  "Answer the current value of the stream pointer"
 
diff --git a/kernel/StreamOps.st b/kernel/StreamOps.st
index 118bfe5..20ec748 100644
--- a/kernel/StreamOps.st
+++ b/kernel/StreamOps.st
@@ -655,6 +655,22 @@ Stream extend [
  ^self peek
     ]
 
+    skipSeparators [
+ "Advance the receiver until we find a character that is not a
+ separator.  Answer false if we reach the end of the stream,
+ else answer true; in this case, sending #next will return the
+ first non-separator character (possibly the same to which the
+ stream pointed before #skipSeparators was sent)."
+
+ <category: 'positioning'>
+ | ch |
+
+ [(ch := self peek) isNil ifTrue: [^false].
+ ch isSeparator]
+ whileTrue: [self next].
+ ^true
+    ]
+
     peekFor: aCharacter [
  "Returns true and gobbles the next element from the stream of it is
  equal to anObject, returns false and doesn't gobble the next element
diff --git a/libgst/dict.c b/libgst/dict.c
index 0f6f59e..4dbe30d 100644
--- a/libgst/dict.c
+++ b/libgst/dict.c
@@ -617,13 +617,13 @@ static const class_definition class_info[] = {
    GST_ISP_FIXED, false, 0,
    "ReadWriteStream", NULL, NULL, NULL },
 
-  {&_gst_file_descriptor_class, &_gst_read_write_stream_class,
-   GST_ISP_FIXED, true, 5,
-   "FileDescriptor", "fd file isPipe atEnd peek", "AllOpenFiles", NULL },
+  {&_gst_file_descriptor_class, &_gst_stream_class,
+   GST_ISP_FIXED, true, 6,
+   "FileDescriptor", "access fd file isPipe atEnd peek", "AllOpenFiles", NULL },
 
   {&_gst_file_stream_class, &_gst_file_descriptor_class,
-   GST_ISP_FIXED, true, 2,
-   "FileStream", "writePtr writeEnd", "Verbose Record Includes", NULL },
+   GST_ISP_FIXED, true, 5,
+   "FileStream", "collection ptr endPtr writePtr writeEnd", "Verbose Record Includes", NULL },
 
   {&_gst_undefined_object_class, &_gst_object_class,
    GST_ISP_FIXED, true, 0,
@@ -2174,15 +2174,9 @@ _gst_set_file_stream_file (OOP fileStreamOOP,
       fileStream->writePtr = _gst_nil_oop;
       fileStream->writeEnd = _gst_nil_oop;
     }
-  else
-    {
-      fileStream->collection = _gst_nil_oop;
-      fileStream->ptr = _gst_nil_oop;
-      fileStream->endPtr = _gst_nil_oop;
-    }
 
-  fileStream->file = FROM_INT (fd);
-  fileStream->name = fileNameOOP;
+  fileStream->fd = FROM_INT (fd);
+  fileStream->file = fileNameOOP;
   fileStream->isPipe =
     isPipe == -1 ? _gst_nil_oop :
     isPipe ? _gst_true_oop : _gst_false_oop;
diff --git a/libgst/dict.h b/libgst/dict.h
index 0d65948..3596685 100644
--- a/libgst/dict.h
+++ b/libgst/dict.h
@@ -69,14 +69,15 @@
 typedef struct gst_file_stream
 {
   OBJ_HEADER;
-  OOP collection;
-  OOP ptr;
-  OOP endPtr;
   OOP access;
+  OOP fd;
   OOP file;
-  OOP name;
   OOP isPipe;
+  OOP atEnd;
   OOP peek;
+  OOP collection;
+  OOP ptr;
+  OOP endPtr;
   OOP writePtr;
   OOP writeEnd;
 }
diff --git a/libgst/prims.def b/libgst/prims.def
index 60a8a82..abaa668 100644
--- a/libgst/prims.def
+++ b/libgst/prims.def
@@ -5357,10 +5357,10 @@ primitive VMpr_FileDescriptor_fileOp [succeed,fail]
   }
 
   fileStream = (gst_file_stream) OOP_TO_OBJ (oop1);
-  if (!IS_INT (fileStream->file))
+  if (!IS_INT (fileStream->fd))
     goto fail;
 
-  fd = TO_INT (fileStream->file);
+  fd = TO_INT (fileStream->fd);
   switch (arg1)
     {
     case PRIM_CLOSE_FILE: /* FileDescriptor close */
@@ -5658,10 +5658,10 @@ primitive VMpr_FileDescriptor_socketOp [succeed,fail]
 
   arg1 = TO_INT (oopVec[0]);
   fileStream = (gst_file_stream) OOP_TO_OBJ (oop1);
-  if (IS_NIL (fileStream->file))
+  if (IS_NIL (fileStream->fd))
     goto fail;
 
-  fd = TO_INT (fileStream->file);
+  fd = TO_INT (fileStream->fd);
   switch (arg1)
     {
 

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk