help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [PATCH] Move FileDescriptor under Stream


From: Paolo Bonzini
Subject: [Help-smalltalk] [PATCH] Move FileDescriptor under Stream
Date: Tue, 05 Aug 2008 13:51:16 +0200
User-agent: Thunderbird 2.0.0.16 (Macintosh/20080707)

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  <address@hidden>

        * 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  <address@hidden>

        * 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)
     {
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]