'From Squeak3.8beta of ''2 November 2004'' [latest update: #6461] on 5 December 2004 at 5:53:24 pm'! "Change Set: positionOfSubcollection-fix-avi Date: 5 December 2004 Author: Avi Bryant This fixes an off-by-one error that caused #positionOfSubCollection: to return the position of the last character before the subcollection rather than the first character of the subcollection itself. For example, before this fix, 'xyz' readStream positionOfSubCollection: 'x' and 'xyz' readStream positionOfSubCollection: 'q' would *both* return 0, whereas now the first returns 1 and the second returns 0. This changset also modifies the only sender, SocketStream>>upToAll:, which had previously tried to compensate for the off-by-one error (although only in one of two places it should have, which was what brought the bug to my attention). With this fix, Comanche/Seaside/etc (and presumably many other network clients and servers) should work properly again."! !PositionableStream methodsFor: 'positioning' stamp: 'avi 12/5/2004 17:41'! positionOfSubCollection: subCollection ifAbsent: exceptionBlock "Return a position such that that element at the new position equals the first element of sub, and the next elements equal the rest of the elements of sub. Begin the search at the current position. If no such match is found, answer the result of evaluating argument, exceptionBlock." | pattern startPosition currentPosition | pattern _ ReadStream on: subCollection. startPosition := self position. [pattern atEnd] whileFalse: [self atEnd ifTrue: [^exceptionBlock value]. self next = pattern next ifFalse: [pattern reset]]. currentPosition := self position. self position: startPosition. ^pattern atEnd ifTrue: [currentPosition + 1 - subCollection size] ifFalse: [exceptionBlock value]! ! !SocketStream methodsFor: 'stream in' stamp: 'avi 12/5/2004 17:42'! upToAll: delims "Answer a subcollection from the current access position to the occurrence (if any, but not inclusive) of aCollection. If aCollection is not in the stream, answer the entire rest of the stream." "Optimized version using the positionOfSubCollection:. Based on a suggestion by miso" | searchBuffer index nextStartOfSearch currentContents | searchBuffer _ ReadWriteStream on: (String new: 1000). [nextStartOfSearch _ (searchBuffer position - delims size) max: 0. searchBuffer nextPutAll: self inStream upToEnd. self resetInStream. searchBuffer position: nextStartOfSearch. index _ searchBuffer positionOfSubCollection: delims. index = 0 and: [self atEnd not]] whileTrue: [self receiveData]. currentContents := searchBuffer contents. ^index = 0 ifTrue: [currentContents] ifFalse: [ self pushBack: (currentContents copyFrom: index + delims size to: currentContents size). currentContents copyFrom: 1 to: (0 max: index-1)]! !