This patch adds another important set of methods, that allows to
eliminate useless creation of collections when stream-to-stream operation is not possible. These are #nextAvailable:into:startingAt: and #next:into:startingAt:. This patch also cleans up the file code, because #nextAvailable:into:startingAt: can replace the old method #read:from:to:. Paolo diff --git a/ChangeLog b/ChangeLog index 786a934..d896ec0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2008-08-05 Paolo Bonzini <[hidden email]> + * kernel/FileDescr.st: Remove #read:... methods, except + #read:from:to: which becomes #nextAvailable:into:startingAt:. + Remove #write:... methods except #write:from:to: which becomes + #next:putAll:startingAt:. Remove #next:, #nextAvailable:, + #nextHunk, #nextHunkPutAllOn: to use the superclass version, + change #next:into: to #next:into:startingAt:. + * kernel/FileStream.st: Change calls to #read:form:to: + and #write:from:to: to super sends. Change #nextAvailable: + to #nextAvailable:into:startingAt:, #next:into: to + #next:into:startingAt:. + * kernel/PosStream.st: Add #nextAvailable:into:startingAt:. + * kernel/Stream.st: Add #next:into:startingAt: and + #nextAvailable:into:startingAt:, use them in #next:, + #nextAvailable:, #nextHunk. + +2008-08-05 Paolo Bonzini <[hidden email]> + * kernel/Stream.st: Do not use Streams in the default implementation of #nextAvailable:. diff --git a/kernel/FileDescr.st b/kernel/FileDescr.st index 340b6e6..043f204 100644 --- a/kernel/FileDescr.st +++ b/kernel/FileDescr.st @@ -342,7 +342,7 @@ do arbitrary processing on the files.'> result := 1] ifTrue: [data := self species new: 1. - result := self read: data from: 1 to: 1. + result := self nextAvailable: 1 into: data startingAt: 1. data := data at: 1]. ^result > 0 ifTrue: [data] @@ -368,7 +368,7 @@ do arbitrary processing on the files.'> | result data | peek isNil ifFalse: [^peek]. data := self species new: 1. - result := self read: data from: 1 to: 1. + result := self nextAvailable: 1 into: data startingAt: 1. ^result > 0 ifTrue: [peek := data at: 1] ifFalse: [self pastEnd] @@ -387,7 +387,7 @@ do arbitrary processing on the files.'> "Store aCharacter on the file" <category: 'basic'> - self write: aCharacter numBytes: 1 + self next: 1 putAll: (String with: aCharacter) startingAt: 1 ] nextPutByte: anInteger [ @@ -675,59 +675,17 @@ do arbitrary processing on the files.'> bufSize = 0 ifTrue: [ ^self ]. buf := String new: bufSize. [ - n := self read: buf from: 1 to: bufSize. + n := self nextAvailable: bufSize into: buf startingAt: 1. aStream next: n putAll: buf startingAt: 1. n = 1024 ] whileTrue ] - next: n putAll: aCollection startingAt: position [ - "Put the characters in the supplied range of aCollection in the file" - - <category: 'overriding inherited methods'> - ^self - write: aCollection - from: position - to: position + n - 1 - ] - nextByteArray: anInteger [ "Return the next 'anInteger' bytes from the stream, as a ByteArray." <category: 'overriding inherited methods'> - ^self next: anInteger into: (ByteArray new: anInteger) - ] - - next: anInteger [ - "Return the next 'anInteger' characters from the stream, as a String." - - <category: 'overriding inherited methods'> - ^self next: anInteger into: (self species new: anInteger) - ] - - next: anInteger into: result [ - "Return the next 'anInteger' characters from the stream, as a String." - - <category: 'overriding inherited methods'> - | read | - read := 0. - [ read = anInteger ] whileFalse: [ - self atEnd ifTrue: [ - ^SystemExceptions.NotEnoughElements signalOn: anInteger - read]. - read := read + (self read: result from: read + 1 to: anInteger). - ]. - ^result - ] - - nextAvailable: anInteger [ - "Return up to anInteger objects in the receiver, stopping if - the end of the stream is reached" - - <category: 'accessing-reading'> - | result n | - result := self species new: anInteger. - n := self read: result. - ^n < anInteger ifTrue: [result copyFrom: 1 to: n] ifFalse: [result] + ^self next: anInteger into: (ByteArray new: anInteger) startingAt: 1 ] atEnd [ @@ -815,28 +773,6 @@ do arbitrary processing on the files.'> ^true ] - nextHunkPutAllOn: aStream [ - "Copy the next buffers worth of stuff from the receiver to aStream." - - <category: 'low-level access'> - | count coll | - count := self read: (coll := self species new: 1024). - count = 0 ifTrue: [^self pastEnd]. - aStream next: count putAll: coll startingAt: 1 - ] - - nextHunk [ - "Answer the next buffers worth of stuff in the Stream represented - by the receiver. Do at most one actual input operation." - - <category: 'low-level access'> - | count answer | - count := self read: (answer := self species new: 1024). - count < answer size ifTrue: [answer := answer copyFrom: 1 to: count]. - count = 0 ifTrue: [^self pastEnd]. - ^answer - ] - pastEnd [ "The end of the stream has been reached. Signal a Notification." @@ -845,115 +781,44 @@ do arbitrary processing on the files.'> super pastEnd ] - read: byteArray [ - "Ignoring any buffering, try to fill byteArray with the - contents of the file" - - <category: 'low-level access'> - | count available | - self ensureReadable. - available := peek isNil ifTrue: [0] ifFalse: [1]. - peek isNil - ifFalse: - [byteArray byteAt: 1 put: peek value. - peek := nil]. - self isOpen ifFalse: [^available]. - count := self - fileOp: 3 - with: byteArray - with: available + 1 - with: byteArray size - ifFail: [self checkError]. - count := count + available. - count = 0 ifTrue: [atEnd := true]. - ^count - ] - - read: byteArray numBytes: anInteger [ - "Ignoring any buffering, try to fill anInteger bytes of byteArray + nextAvailable: n into: aCollection startingAt: position [ + "Ignoring any buffering, try to fill the given range of aCollection with the contents of the file" <category: 'low-level access'> | count available | + n = 0 ifTrue: [ ^self ]. self ensureReadable. available := peek isNil ifTrue: [0] ifFalse: [1]. peek isNil ifFalse: - [byteArray byteAt: 1 put: peek value. + [aCollection byteAt: position put: peek value. peek := nil]. self isOpen ifFalse: [^available]. count := self fileOp: 3 - with: byteArray - with: 1 + available - with: (anInteger min: byteArray size) - ifFail: [self checkError]. - count := count + available. - count = 0 ifTrue: [atEnd := true]. - ^count - ] - - read: byteArray from: position to: end [ - "Ignoring any buffering, try to fill the given range of byteArray - with the contents of the file" - - <category: 'low-level access'> - | count available | - self ensureReadable. - available := peek isNil ifTrue: [0] ifFalse: [1]. - peek isNil - ifFalse: - [byteArray byteAt: position put: peek value. - peek := nil]. - self isOpen ifFalse: [^available]. - count := self - fileOp: 3 - with: byteArray + with: aCollection with: position + available - with: (end min: byteArray size) + with: (position + n - 1 min: aCollection size) ifFail: [self checkError]. count := count + available. count = 0 ifTrue: [atEnd := true]. ^count ] - write: byteArray [ - "Ignoring any buffering, try to write the contents of byteArray in the - file" - - <category: 'low-level access'> - ^self - write: byteArray - from: 1 - to: byteArray size - ] - - write: byteArray numBytes: anInteger [ - "Ignoring any buffering, try to write to the file the first anInteger - bytes of byteArray" - - <category: 'low-level access'> - ^self - write: byteArray - from: 1 - to: anInteger - ] - - write: byteArray from: position to: end [ - "Ignoring any buffering, try to write to the file the given range - of byteArray, starting at the position-th element and ending - at the end-th." + next: n putAll: aCollection startingAt: position [ + "Put the characters in the supplied range of aCollection in the file" <category: 'low-level access'> | cur last soFar result | cur := position. - last := end min: byteArray size. + last := position + n - 1 min: aCollection size. [cur <= last] whileTrue: [self ensureWriteable. self isOpen ifFalse: [^cur - position]. result := self fileOp: 2 - with: byteArray + with: aCollection with: cur with: last ifFail: [self checkError]. diff --git a/kernel/FileStream.st b/kernel/FileStream.st index 1156e16..827cf5e 100644 --- a/kernel/FileStream.st +++ b/kernel/FileStream.st @@ -382,10 +382,10 @@ file object, such as /dev/rmt0 on UNIX or MTA0: on VMS).'> bufferAll: aCollection startingAt: pos + written] ifFalse: - [self - write: aCollection asString - from: pos + written - to: pos + n - 1] + [super + next: n - written + putAll: aCollection asString + startingAt: pos + written] ] upTo: aCharacter [ @@ -477,21 +477,71 @@ file object, such as /dev/rmt0 on UNIX or MTA0: on VMS).'> ^resultStream contents ] - nextAvailable: anInteger [ - "Private - Read up to anInteger bytes from the stream and store them - into answer. Return `answer' itself, or raise an exception if we - could not read the full amount of data." + next: anInteger into: answer startingAt: pos [ + "Read up to anInteger bytes from the stream and store them + into answer. Return the number of bytes that were read, raising + an exception if we could not read the full amount of data." + + <category: 'buffering'> + | read last | + writePtr notNil ifTrue: [self flush]. + read := 0. + + "Exhaust the remaining contents of the buffer if they cannot satisfy + the whole request." + ptr + anInteger - 1 > endPtr + ifTrue: + [answer + replaceFrom: pos + to: endPtr - ptr + pos + with: collection + startingAt: ptr. + read := endPtr - ptr + 1. + ptr := endPtr + 1]. + + "If we did not read everything, but what's left is less than the size of + the buffer, try once more filling it..." + anInteger - read < collection size + ifTrue: + [ptr > endPtr ifTrue: [self fill]. + last := read + endPtr - ptr + pos min: answer size. + answer + replaceFrom: read + pos + to: last + with: collection + startingAt: ptr. + ptr := ptr + (last - read - pos + 1). + read := last - pos + 1]. + + "Anything more? We read it from the file. We can come here only if the + buffer cannot be filled completely, or if we want to read really a + lot of data." + [ read = anInteger ] whileFalse: [ + self atEnd ifTrue: [ + ^SystemExceptions.NotEnoughElements signalOn: anInteger - read]. + read := read + (super + nextAvailable: anInteger - read + into: answer + startingAt: 1) + ]. + ^answer + ] + + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Read up to anInteger bytes from the stream and store them + into aCollection. Return the number of bytes read." <category: 'buffering'> - | answer last | + | last n | writePtr notNil ifTrue: [self flush]. ptr > endPtr ifTrue: [self fill]. "Fetch data from the buffer, without doing more than one I/O operation." last := endPtr min: ptr + anInteger - 1. - answer := collection copyFrom: ptr to: last. - ptr := ptr + answer size. - ^answer + n := last - ptr + 1. + aCollection replaceFrom: pos to: pos + n - 1 with: collection startingAt: ptr. + ptr := ptr + n. + ^n ] nextPutAllOn: aStream [ @@ -568,10 +618,10 @@ file object, such as /dev/rmt0 on UNIX or MTA0: on VMS).'> ifTrue: [(self isPipe or: [writePtr - 1 = endPtr]) ifFalse: [super skip: writePtr - 1 - endPtr]. - self - write: collection - from: writePtr - to: writeEnd]] + super + next: writeEnd - writePtr + 1 + putAll: collection + startingAt: writePtr]] ifFalse: [writePtr notNil ifTrue: @@ -659,63 +709,16 @@ file object, such as /dev/rmt0 on UNIX or MTA0: on VMS).'> writeEnd := ptr - 1 ] - next: anInteger into: answer [ - "Private - Read up to anInteger bytes from the stream and store them - into answer. Return `answer' itself, or raise an exception if we - could not read the full amount of data." - - <category: 'buffering'> - | read last | - writePtr notNil ifTrue: [self flush]. - read := 0. - - "Exhaust the remaining contents of the buffer if they cannot satisfy - the whole request." - ptr + anInteger - 1 > endPtr - ifTrue: - [answer - replaceFrom: 1 - to: endPtr - ptr + 1 - with: collection - startingAt: ptr. - read := endPtr - ptr + 1. - ptr := endPtr + 1]. - - "If we did not read everything, but what's left is less than the size of - the buffer, try once more filling it..." - anInteger - read < collection size - ifTrue: - [ptr > endPtr ifTrue: [self fill]. - last := read + endPtr - ptr + 1 min: answer size. - answer - replaceFrom: read + 1 - to: last - with: collection - startingAt: ptr. - ptr := ptr + last - read. - read := last]. - - "Anything more? We read it from the file. We can come here only if the - buffer cannot be filled completely, or if we want to read really a - lot of data." - [ read = anInteger ] whileFalse: [ - self atEnd ifTrue: [ - ^SystemExceptions.NotEnoughElements signalOn: anInteger - read]. - read := read + (self read: answer from: read + 1 to: anInteger) - ]. - ^answer - ] - fill [ "Private - Fill the input buffer" <category: 'buffering'> (access bitAnd: 1) = 0 ifTrue: [^self shouldNotImplement]. ptr > endPtr ifTrue: [self flush]. - endPtr := endPtr + (self - read: collection - from: endPtr + 1 - to: collection size) + endPtr := endPtr + (super + nextAvailable: collection size - endPtr + into: collection + startingAt: endPtr + 1) ] ] diff --git a/kernel/PosStream.st b/kernel/PosStream.st index 1f9d78b..1788d69 100644 --- a/kernel/PosStream.st +++ b/kernel/PosStream.st @@ -88,6 +88,23 @@ or ReadWriteStream instead of me to create and use streams.'> aStream next: endPtr putAll: collection startingAt: 1. ] + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Place up to anInteger objects from the receiver into + aCollection, starting from position pos and stopping if + no more data is available." + + <category: 'accessing-reading'> + | n | + n := anInteger min: endPtr - ptr + 1. + aCollection + replaceFrom: pos + to: pos + n - 1 + with: collection + startingAt: ptr. + ptr := ptr + n. + ^n + ] + peek [ "Returns the next element of the stream without moving the pointer. Returns nil when at end of stream." diff --git a/kernel/Stream.st b/kernel/Stream.st index 081cd2b..802aa35 100644 --- a/kernel/Stream.st +++ b/kernel/Stream.st @@ -59,16 +59,31 @@ provide for writing collections sequentially.'> "Return the next anInteger objects in the receiver" <category: 'accessing-reading'> - | data i item | - data := self species new: anInteger. - - [i := 0. - [i < anInteger] whileTrue: - [item := self next. - data at: (i := i + 1) put: item]] - on: SystemExceptions.EndOfStream - do: [:ex | SystemExceptions.NotEnoughElements signalOn: anInteger - i]. - ^data + | answer | + self + next: anInteger + into: (answer := self species new: anInteger) + startingAt: 1. + ^answer + ] + + next: anInteger into: answer startingAt: pos [ + "Read up to anInteger bytes from the stream and store them + into answer. Return the number of bytes that were read, raising + an exception if we could not read the full amount of data." + + <category: 'buffering'> + | read | + read := 0. + [ read = anInteger ] whileFalse: [ + self atEnd ifTrue: [ + ^SystemExceptions.NotEnoughElements signalOn: anInteger - read]. + read := read + (self + nextAvailable: anInteger - read + into: answer + startingAt: 1) + ]. + ^answer ] nextAvailable: anInteger [ @@ -79,14 +94,32 @@ provide for writing collections sequentially.'> operation." <category: 'accessing-reading'> - | answer | - answer := self species new: anInteger. - 1 to: anInteger do: - [:i | self atEnd ifTrue: [^answer copyFrom: 1 to: i - 1]. - answer at: i put: self next]. + | n answer | + n := self + nextAvailable: anInteger + into: (answer := self species new: anInteger) + startingAt: 1. + n < anInteger ifTrue: [ answer := answer copyFrom: 1 to: n ]. ^answer ] + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Place the next anInteger objects from the receiver into aCollection, + starting at position pos. Return the number of items stored. + Besides stopping if the end of the stream is reached, this may + return less than this number of bytes for various reasons. + For example, on files and sockets this operation could be + non-blocking, or could do at most one I/O operation." + + <category: 'accessing-reading'> + | i | + i := -1. + [(i := i + 1) = anInteger] whileFalse: [ + self atEnd ifTrue: [^i]. + aCollection at: i + pos put: self next]. + ^anInteger + ] + nextMatchFor: anObject [ "Answer whether the next object is equal to anObject. Even if it does not, anObject is lost" @@ -527,14 +560,7 @@ provide for writing collections sequentially.'> Smalltalk (including zlib streams)." <category: 'positioning'> - | s | - s := self species new: 1024. - 1 to: 1024 - do: - [:i | - self atEnd ifTrue: [^s copyFrom: 1 to: i - 1]. - s at: i put: self next]. - ^s + ^self nextAvailable: 1024 ] prefixTableFor: aCollection [ diff --git a/packages/iconv/ChangeLog b/packages/iconv/ChangeLog index 9bc08be..5e59995 100644 --- a/packages/iconv/ChangeLog +++ b/packages/iconv/ChangeLog @@ -1,5 +1,9 @@ 2008-08-05 Paolo Bonzini <[hidden email]> + * Sets.st: Use #nextInputAvailable:into:startingAt: instead. + +2008-08-05 Paolo Bonzini <[hidden email]> + * Sets.st: Add #nextInputAvailable: and use it to refill the buffer. 2008-01-17 Paolo Bonzini <[hidden email]> diff --git a/packages/iconv/Sets.st b/packages/iconv/Sets.st index 35c1cfe..6045b27 100644 --- a/packages/iconv/Sets.st +++ b/packages/iconv/Sets.st @@ -379,13 +379,13 @@ encodings.'> ^origin next ] - nextInputAvailable: n [ - "Return up to N characters from the origin. This method is for + nextInputAvailable: n into: aCollection startingAt: pos [ + "Place up to N characters from the origin in aCollection. This method is for private use by encoders, calling it outside may corrupt the internal state of the encoder." <category: 'stream operations'> - ^origin nextAvailable: n + ^origin nextAvailable: n into: aCollection startingAt: pos ] species [ @@ -966,6 +966,22 @@ Iconv is skipped altogether and only Smalltalk converters are used.'> ^answer ] + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Answer the next buffer's worth of data from the receiver." + + <category: 'stream operation'> + | n | + (self atEndOfBuffer and: [self convertMore]) + ifTrue: [^self pastEnd]. + n := anInteger min: recodedEnd - recodedPos + 1. + aCollection + replaceFrom: pos to: pos + n - 1 + with: recodedBuffer + startingAt: recodedPos. + recodedPos := recodedPos + n. + ^n + ] + nextHunkPutAllOn: aStream [ "Copy the next buffer's worth of data from the receiver onto aStream." @@ -985,12 +1001,7 @@ Iconv is skipped altogether and only Smalltalk converters are used.'> "Answer the next buffer's worth of data from the receiver." <category: 'stream operation'> - | answer | - (self atEndOfBuffer and: [self convertMore]) - ifTrue: [^self pastEnd]. - answer := recodedBuffer copyFrom: recodedPos to: recodedEnd. - recodedPos := recodedEnd + 1. - ^answer + ^self nextAvailable: recodedEnd - recodedPos + 1 ] release [ @@ -1043,13 +1054,10 @@ Iconv is skipped altogether and only Smalltalk converters are used.'> readEnd := readEnd - readPos + 1. readPos := 1]. - data := self nextInputAvailable: self bufferSize - readEnd. - readBuffer - replaceFrom: readEnd + 1 to: readEnd + data size - with: data - startingAt: 1. - - readEnd := readEnd + data size. + readEnd := readEnd + (self + nextInputAvailable: self bufferSize - readEnd + into: readBuffer + startingAt: readEnd + 1). ] initializeFrom: fromEncoding to: toEncoding origin: aStringOrStream [ diff --git a/packages/sockets/Buffers.st b/packages/sockets/Buffers.st index b822b96..fc2e498 100644 --- a/packages/sockets/Buffers.st +++ b/packages/sockets/Buffers.st @@ -124,7 +124,7 @@ evaluates an user defined block to try to get some more data.'> "Copy a buffer's worth of data from the receiver to aStream, doing at most one call to the fill block." - <category: 'buffer handling'> + <category: 'accessing-reading'> self atEnd ifTrue: [^super pastEnd]. aStream next: endPtr - ptr + 1 putAll: self collection startingAt: ptr. endPtr := ptr - 1. "Empty the buffer" @@ -134,20 +134,27 @@ evaluates an user defined block to try to get some more data.'> "Answer a buffer's worth of data, doing at most one call to the fill block." - <category: 'buffer handling'> - | contents | - self atEnd ifTrue: [^super pastEnd]. - contents := self collection copyFrom: ptr to: endPtr. - endPtr := ptr - 1. "Empty the buffer" - ^contents + <category: 'accessing-reading'> + ^self nextAvailable: endPtr - ptr + 1 ] availableBytes [ "Answer how many bytes are available in the buffer." + <category: 'buffer handling'> + self isEmpty ifTrue: [ self fill ]. ^endPtr + 1 - ptr ] + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Place the next anInteger objects from the receiver into aCollection, + starting at position pos. Return the number of items stored." + + <category: 'accessing-reading'> + self isEmpty ifTrue: [ self fill ]. + ^super nextAvailable: anInteger into: aCollection startingAt: pos + ] + fill [ "Fill the buffer with more data if it is empty, and answer true if the fill block was able to read more data." diff --git a/packages/sockets/ChangeLog b/packages/sockets/ChangeLog index f7450dc..f10dbb5 100644 --- a/packages/sockets/ChangeLog +++ b/packages/sockets/ChangeLog @@ -1,5 +1,12 @@ 2008-08-05 Paolo Bonzini <[hidden email]> + * Buffers.st: Add #nextAvailable:into:startingAt:. + * Sockets.st: Change #nextAvailable: into + #nextAvailable:into:startingAt:. Change the fill + blocks to not use #read:from:to: and #write:from:to:. + +2008-08-05 Paolo Bonzini <[hidden email]> + * Buffers.st: Add #nextHunk and #nextHunkPutAllOn:. * Sockets.st: Remove the lookahead instance variable. Delegate more stuff to the readBuffer, including #nextHunk. Implement diff --git a/packages/sockets/Sockets.st b/packages/sockets/Sockets.st index b2c11f2..11de715 100644 --- a/packages/sockets/Sockets.st +++ b/packages/sockets/Sockets.st @@ -1164,7 +1164,6 @@ This class adds a read buffer to the basic model of AbstractSocket.'> <category: 'stream protocol'> self canRead ifFalse: [ ^0 ]. - self readBuffer isEmpty ifTrue: [ self readBuffer fill ]. ^self readBuffer availableBytes ] @@ -1208,30 +1207,24 @@ This class adds a read buffer to the basic model of AbstractSocket.'> ^self readBuffer next ] - nextAvailable: anInteger [ - "Return up to anInteger objects in the receiver, stopping if - the end of the stream is reached" + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Place up to anInteger objects from the receiver into + aCollection, starting from position pos and stopping if + no more data is available." <category: 'accessing-reading'> - | buffer available stream | + | available read | readBuffer isNil ifTrue: [ ^self pastEnd ]. - self ensureReadable. - available := self availableBytes. - available >= anInteger ifTrue: [ ^self next: anInteger ]. - - "Try filling the first buffer." - buffer := self next: available. - available := self availableBytes min: anInteger - available. - available = 0 ifTrue: [ ^buffer ]. - "Streams have extra costs because of copying, use them only if - needed." - stream := WriteStream with: buffer. - [ (available := self availableBytes min: anInteger - stream size) > 0 ] - whileTrue: [ stream nextPutAll: (self readBuffer next: available) ]. + read := 0. + [ (available := self availableBytes) > 0 ] whileTrue: [ + read := read + (self readBuffer + nextAvailable: available + into: aCollection + startingAt: pos + read) ]. - ^stream contents + ^read ] nextHunkPutAllOn: aStream [ @@ -1256,16 +1249,6 @@ This class adds a read buffer to the basic model of AbstractSocket.'> ^self readBuffer nextHunk ] - next: count [ - "Read `count' bytes from the socket. This might yield control to other - Smalltalk Processes." - - <category: 'stream protocol'> - | result | - readBuffer isNil ifTrue: [ ^self pastEnd ]. - ^self readBuffer next: count - ] - peek [ "Read a byte from the socket, without advancing the buffer; answer nil if no more data is available. This might yield control to other @@ -1329,7 +1312,7 @@ This class adds a read buffer to the basic model of AbstractSocket.'> [:data :size | self implementation ensureReadable. self implementation isOpen - ifTrue: [self implementation read: data numBytes: size] + ifTrue: [self implementation nextAvailable: size into: data startingAt: 1] ifFalse: [self deleteBuffers. 0]] @@ -1470,7 +1453,7 @@ This class adds read and write buffers to the basic model of AbstractSocket.'> | alive | self implementation ensureWriteable. alive := self implementation isOpen - and: [(self implementation write: data numBytes: size) > -1]. + and: [(self implementation next: size putAll: data startingAt: 1) > -1]. alive ifFalse: [self deleteBuffers]] ] diff --git a/packages/sport/ChangeLog b/packages/sport/ChangeLog index 3599bbb..ba15e8d 100644 --- a/packages/sport/ChangeLog +++ b/packages/sport/ChangeLog @@ -1,3 +1,8 @@ +2008-08-05 Paolo Bonzini <[hidden email]> + + * sport.st: At last use native Socket methods for #read: and + #readInto:startingAt:for:. + 2008-08-04 Paolo Bonzini <[hidden email]> * sport.st: Use StreamSocket>>#nextAvailable:. diff --git a/packages/sport/sport.st b/packages/sport/sport.st index 6ed8633..957f5f3 100644 --- a/packages/sport/sport.st +++ b/packages/sport/sport.st @@ -1205,10 +1205,11 @@ Object subclass: SpSocket [ If the targetNumberOfBytes are not available, I return what I can get." <category: 'services-io'> - "FIXME: this needs #nextAvailable:into: to avoid a copy in #asByteArray" - ^(self underlyingSocket - ensureReadable; - nextAvailable: targetNumberOfBytes) asByteArray + | answer n | + answer := ByteArray new: targetNumberOfBytes. + n := self underlyingSocket nextAvailable: targetNumberOfBytes into: answer startingAt: 1. + n < targetNumberOfBytes ifTrue: [ answer := answer copyFrom: 1 to: n ]. + ^answer ] readInto: aByteArray startingAt: startIndex for: aNumberOfBytes [ @@ -1217,13 +1218,7 @@ Object subclass: SpSocket [ number of bytes to be read. We get what its there no matter how much their is!!" <category: 'services-io'> - | buffer | - buffer := self underlyingSocket - ensureReadable; - nextAvailable: aNumberOfBytes. - aByteArray replaceFrom: startIndex to: startIndex + buffer size - 1 - with: buffer startingAt: 1. - ^buffer size + ^self underlyingSocket nextAvailable: aNumberOfBytes into: aByteArray startingAt: startIndex ] readyForRead [ diff --git a/packages/zlib/ChangeLog b/packages/zlib/ChangeLog index a9c3914..9e8bfb5 100644 --- a/packages/zlib/ChangeLog +++ b/packages/zlib/ChangeLog @@ -1,5 +1,9 @@ 2008-08-05 Paolo Bonzini <[hidden email]> + * ZLibReadStream.st: Add #nextAvailable:into:startingAt:. + +2008-08-05 Paolo Bonzini <[hidden email]> + * ZLibReadStream.st: Add #nextHunkPutAllOn:. * zlibtests.st: Test it. diff --git a/packages/zlib/ZLibReadStream.st b/packages/zlib/ZLibReadStream.st index 17fbea5..8684ab5 100644 --- a/packages/zlib/ZLibReadStream.st +++ b/packages/zlib/ZLibReadStream.st @@ -89,11 +89,24 @@ used for communication with zlib.'> operation." <category: 'streaming'> - | result | - self atEnd ifTrue: [^self pastEnd]. - result := outBytes copyFrom: ptr + 1 to: endPtr. - ptr := endPtr. - ^result + ^self nextAvailable: endPtr - ptr + ] + + nextAvailable: anInteger into: aCollection startingAt: pos [ + "Place up to anInteger objects from the receiver into + aCollection, starting from position pos and stopping if + no more data is available." + + <category: 'accessing-reading'> + | n | + n := anInteger min: endPtr - ptr. + aCollection + replaceFrom: pos + to: pos + n - 1 + with: outBytes + startingAt: ptr + 1. + ptr := ptr + n. + ^n ] peek [ _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |