Stream.st
branchjv
changeset 19892 d1aecb538df5
parent 19660 d48041817c55
parent 19889 9d79440bb826
child 20080 093324d7a47c
--- a/Stream.st	Thu May 19 07:07:52 2016 +0200
+++ b/Stream.st	Fri May 20 06:45:01 2016 +0200
@@ -691,15 +691,26 @@
 
 !Stream methodsFor:'misc functions'!
 
-copy:numberOfBytes into:outStream bufferSize:bufferSize
-    "read from the receiver, and write all data up to count or the end to another stream.
-     Return the number of bytes which have been transferred"
-
-    |bufferSpecies buffer bytesWritten readCount writeCount count freeBuffer remaining|
-
-    bytesWritten := 0.
+copy:numberOfBytes into:outStream
+    "read from the receiver, and write numberOfBytes data to another aWriteStream.
+     Return the number of bytes which have been transferred."
+
+    ^ self copy:numberOfBytes into:outStream bufferSize:(128*1024)
+!
+
+copy:numberOfBytes into:aWriteStream bufferSize:bufferSizeArg
+    "read from the receiver, and write numberOfBytes data to another aWriteStream.
+     Return the number of bytes which have been transferred."
+
+    |bufferSpecies bufferSize bytesLeft buffer countWritten freeBuffer|
+
+    countWritten := 0.
     bufferSpecies := self contentsSpecies.
+    bytesLeft := numberOfBytes.
+    bufferSize := bufferSizeArg min:numberOfBytes.
+
     bufferSpecies == ByteArray ifTrue:[
+        "an ExternalBytes buffer is faster when writing to a windows ExternalStream"
         buffer:= ExternalBytes unprotectedNew:bufferSize.
         freeBuffer := true.
     ] ifFalse:[
@@ -707,39 +718,42 @@
         freeBuffer := false.
     ].
 
-    remaining := numberOfBytes.
-    "Note: atEnd will block if reading from an empty pipe or socket"
-    [remaining ~~ 0 and:[self atEnd]] whileFalse:[ 
-        readCount := self nextAvailableBytes:(bufferSize min:remaining) into:buffer startingAt:1.
+    "read loop: read required bytes"
+    [
+        |readCount|
+
+        readCount := self nextAvailable:bytesLeft into:buffer startingAt:1.
+        bytesLeft := bytesLeft - readCount.
+
         readCount > 0 ifTrue:[
+            |writeCount|
+
             writeCount := 0.
+            "write loop: write until all is written"
             [
-                count := outStream nextPutBytes:readCount-writeCount
-                                    from:buffer 
-                                    startingAt:writeCount+1.
-                bytesWritten := bytesWritten + count.
+                |count|
+
+                count := aWriteStream 
+                            nextPutAll:readCount-writeCount
+                            from:buffer 
+                            startingAt:writeCount+1.
                 writeCount := writeCount + count.
                 writeCount < readCount ifTrue:[
-                    outStream writeWait.
+                    aWriteStream writeWait.
                     true.
                 ] ifFalse:[
                     false
                 ].
             ] whileTrue.
-            remaining := remaining - writeCount.
-        ].
-    ].
+            countWritten := countWritten + writeCount.
+        ]. 
+        "Note: atEnd will block if reading from an empty pipe or socket.
+         avoid atEnd if possible, because it reads a single byte."
+        bytesLeft ~~ 0 or:[self atEnd not]
+    ] whileTrue.
+
     freeBuffer ifTrue:[ buffer free ].
-    ^ bytesWritten
-
-    "
-      'hello world' readStream copyToEndInto:'/tmp/mist' asFilename writeStream.
-      'hello world' readStream copyToEndInto:#[] writeStream.
-      ('/tmp/mist' asFilename readStream binary; yourself) copyToEndInto:#[] writeStream
-      #[1 2 3 4 5 6 7] readStream copyToEndInto:'/tmp/mist' asFilename writeStream.
-      #[1 2 3 4 5 6 7] readStream copyToEndInto:'' writeStream.
-
-    "
+    ^ countWritten.
 !
 
 copyToEndFrom:inStream
@@ -3465,7 +3479,7 @@
             (answerStream contents endsWith:aCollection) ifTrue:[
                 |pos|
                 pos := answerStream position.
-                answerStream resetPosition.
+                answerStream reset.
                 ^ answerStream next:pos-aCollection size.
             ]
         ].