--- 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.
]
].