[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] [PATCH] Allow "stream nextPutAll: anotherStream"
From: |
Paolo Bonzini |
Subject: |
[Help-smalltalk] [PATCH] Allow "stream nextPutAll: anotherStream" |
Date: |
Fri, 18 May 2007 13:34:22 +0200 |
User-agent: |
Thunderbird 2.0.0.0 (Macintosh/20070326) |
Various optimizations inhibit this in FileDescriptor and FileStream.
This patch works around them.
Among other things, it allows writing a ZlibStream onto a file just by
doing a #nextPutAll:.
Paolo
2007-05-18 Paolo Bonzini <address@hidden>
* kernel/ByteStream.st: Support #nextPutAll: of Streams into Streams.
* kernel/Collection.st: Add #isSequenceable.
* kernel/FileDescr.st: Add #next:putAll:startingAt:. Support
#nextPutAll: of Streams into Streams. Fix #next:
* kernel/FileStream.st: Support #nextPutAll: of Streams into Streams.
* kernel/SeqCollect.st: Add #isSequenceable.
* kernel/Stream.st: Add #isSequenceable. Support #nextPutAll: of
Streams into Streams.
--- orig/kernel/ByteStream.st
+++ mod/kernel/ByteStream.st
@@ -164,6 +164,9 @@ nextPutByte: anInteger
nextPutAll: aCollection
"Write all the objects in aCollection to the receiver"
| collEnd relative lastCopied |
+ aCollection isSequenceable
+ ifFalse: [ ^super nextPutAll: aCollection ].
+
aCollection isEmpty ifTrue: [ ^self ].
collEnd := ptr + aCollection size - 1.
--- orig/kernel/Collection.st
+++ mod/kernel/Collection.st
@@ -159,6 +159,12 @@ removeAll: aCollection ifAbsent: aBlock
!Collection methodsFor: 'testing collections'!
+isSequenceable
+ "Answer whether the receiver can be accessed by a numeric index with
+ #at:/#at:put:."
+ ^false
+!
+
capacity
"Answer how many elements the receiver can hold before having to grow."
^self basicSize
--- orig/kernel/FileDescr.st
+++ mod/kernel/FileDescr.st
@@ -517,8 +517,21 @@ isEmpty
^self size == 0
!
+next: n putAll: aCollection startingAt: position
+ "Put the characters in the supplied range of aCollection in the file"
+ ^self write: aCollection from: position to: position + n - 1!
+
nextPutAll: aCollection
"Put all the characters in aCollection in the file"
+ | stream |
+ aCollection isSequenceable ifFalse: [
+ [ stream := aCollection readStream ]
+ on: MessageNotUnderstood
+ do: [ :ex | ex return: aCollection asString readStream ].
+
+ [ stream atEnd ] whileFalse: [ self write: stream nextHunk ].
+ ^self ].
+
self write: aCollection asString
!
@@ -543,8 +556,8 @@ next: anInteger
n = 0
ifTrue: [ atEnd := true ].
^n < anInteger
- ifTrue: [ collection copyFrom: 1 to: n ]
- ifFalse: [ collection ].
+ ifTrue: [ result copyFrom: 1 to: n ]
+ ifFalse: [ result ].
! !
--- orig/kernel/FileStream.st
+++ mod/kernel/FileStream.st
@@ -365,7 +365,20 @@ nextPutAllFlush: aCollection
nextPutAll: aCollection
"Put all the characters in aCollection in the file"
| n coll written |
- coll := aCollection asString.
+ "Just do 'coll := aCollection asString', but avoid expensive operations
+ in the common case where aCollection is already a String."
+ coll := aCollection isSequenceable
+ ifTrue: [ aCollection ]
+ ifFalse: [
+ [ aCollection asString ]
+ on: MessageNotUnderstood
+ do: [ :ex |
+ "If we are in a stream, try to facilitate buffering."
+ [ aCollection atEnd ] whileFalse: [
+ coll := aCollection nextHunk.
+ self next: coll size putAll: coll startingAt: 1 ].
+ ^self ] ].
+
n := coll size.
written := collection size - ptr + 1 min: n.
self next: written bufferAll: coll startingAt: 1.
--- orig/kernel/SeqCollect.st
+++ mod/kernel/SeqCollect.st
@@ -105,6 +105,12 @@ inspect
!
+isSequenceable
+ "Answer whether the receiver can be accessed by a numeric index with
+ #at:/#at:put:."
+ ^true
+!
+
= aCollection
"Answer whether the receiver's items match those in aCollection"
--- orig/kernel/Stream.st
+++ mod/kernel/Stream.st
@@ -196,7 +196,9 @@ next: n putAll: aCollection startingAt:
nextPutAll: aCollection
"Write all the objects in aCollection to the receiver"
- aCollection do: [ :element | self nextPut: element ].
+ aCollection isSequenceable
+ ifTrue: [ self next: aCollection size putAll: aCollection startingAt: 1
]
+ ifFalse: [ aCollection do: [ :element | self nextPut: element ] ].
^aCollection
!
@@ -215,6 +217,18 @@ atEnd
self subclassResponsibility
!
+readStream
+ "As a wild guess, return the receiver. WriteStreams should override
+ this method."
+ ^self
+!
+
+isSequenceable
+ "Answer whether the receiver can be accessed by a numeric index with
+ #at:/#at:put:."
+ ^false
+!
+
isExternalStream
"Answer whether the receiver streams on a file or socket.
By default, answer false."
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Help-smalltalk] [PATCH] Allow "stream nextPutAll: anotherStream",
Paolo Bonzini <=