# HG changeset patch # User Stefan Vogel # Date 1515621718 -3600 # Node ID 769a6b3f0a19dde15c8f278a7ff63759f72cc77b # Parent 8a15c1e6c4a8c86b895c9634b459ee9d481f9553 #BUGFIX by stefan Support real #peak of unicode characters class: EncodedStream class definition removed: #cr #peekFor: #skip: #skipSeparators comment/format in: #contents #isOpen #position changed:15 methods diff -r 8a15c1e6c4a8 -r 769a6b3f0a19 EncodedStream.st --- a/EncodedStream.st Wed Jan 10 23:00:57 2018 +0100 +++ b/EncodedStream.st Wed Jan 10 23:01:58 2018 +0100 @@ -14,7 +14,7 @@ "{ NameSpace: Smalltalk }" PeekableStream subclass:#EncodedStream - instanceVariableNames:'encoder stream' + instanceVariableNames:'encoder stream peekChar' classVariableNames:'' poolDictionaries:'' category:'Collections-Text-Encodings' @@ -131,17 +131,6 @@ !EncodedStream methodsFor:'accessing'! -contentsSpecies - - "Not sure if this is ok" - - ^ stream contentsSpecies. - -"/ ^UnicodeString - - "Created: / 14-06-2005 / 17:11:01 / janfrog" -! - encoder ^ encoder ! @@ -161,7 +150,15 @@ ! lineNumber + "the linenumber doesn't change when characters are decoded" + + stream isNil ifTrue:[ + ^ nil. + ]. ^ stream lineNumber + + "Modified: / 02-01-2018 / 20:12:18 / stefan" + "Modified (comment): / 09-01-2018 / 17:47:20 / stefan" ! pathName @@ -194,34 +191,40 @@ nextChunk "as a side effect, check for an encoding chunk" - |prevEncoder chunk| + |chunk| - chunk := stream nextChunk. - chunk isEmptyOrNil ifTrue:[ - ^ chunk. - ]. + chunk := super nextChunk. - prevEncoder := encoder. - (prevEncoder isNullEncoder and:[stream isPositionable not]) ifTrue:[ - "/ not already checked + (encoder isNullEncoder and:[stream isPositionable not]) ifTrue:[ + "/ encoding not already checked "/ check if we need lazy setup of the encoder "/ (used with non-positionable streams) - (chunk includesString:'{ Encoding:') ifTrue:[ + "/ encoder for PositionableStream is set up in self class decodedStreamFor: + (chunk notNil and:[chunk includesString:'{ Encoding:']) ifTrue:[ |enc| enc := self class encoderFor:(CharacterEncoder guessEncodingOfBuffer:chunk). enc notNil ifTrue:[ - prevEncoder := encoder := enc. + encoder := enc. + ^ encoder decodeString:chunk. ]. - ] + ]. ]. - ^ prevEncoder decodeString:chunk - "Modified: / 16-02-2017 / 14:54:57 / stefan" + ^ chunk. + + "Modified (format): / 04-01-2018 / 00:33:57 / stefan" ! ! !EncodedStream methodsFor:'queries'! +contentsSpecies + ^ String + + "Created: / 14-06-2005 / 17:11:01 / janfrog" + "Modified: / 10-01-2018 / 11:43:57 / stefan" +! + isEncoderFor:encodingString ^ encoder isEncoderFor:encodingString @@ -231,11 +234,16 @@ !EncodedStream methodsFor:'stream protocol'! atEnd - ^ stream atEnd + ^ peekChar isNil and:[stream atEnd] + + "Modified: / 02-01-2018 / 21:47:17 / stefan" ! close + peekChar := nil. stream close + + "Modified: / 09-01-2018 / 18:33:01 / stefan" ! collection @@ -248,9 +256,8 @@ ! contents - - ^String streamContents: [:s| - [ self atEnd ] whileFalse:[ + ^String streamContents:[:s| + [self atEnd] whileFalse:[ |ch| ch := self next. "/ decoder may decide to return nil from #next, even though the @@ -262,10 +269,7 @@ ] "Created: / 25-02-2010 / 23:34:28 / Jan Vrany " -! - -cr - self nextPutAll:(Character cr asString) + "Modified (format): / 02-01-2018 / 19:35:10 / stefan" ! emphasis:anObject @@ -276,29 +280,52 @@ ! flush + peekChar := nil. stream flush + + "Modified: / 02-01-2018 / 19:17:40 / stefan" ! isEmpty - ^ stream isEmpty -! + ^ stream isEmptyOrNil. -isOpen - ^ stream notNil and:[stream isOpen] + "Modified: / 02-01-2018 / 19:59:09 / stefan" ! next - - ^encoder readNextCharacterFrom:stream + peekChar notNil ifTrue:[ + |p| + p := peekChar. + peekChar := nil. + ^ p. + ]. + ^ encoder readNextCharacterFrom:stream "Created: / 14-06-2005 / 17:01:39 / janfrog" + "Modified: / 02-01-2018 / 19:19:29 / stefan" ! -next:charactersToRead +next:nCharactersToRead + |chars| - ^encoder readNext:charactersToRead charactersFrom:stream + nCharactersToRead == 1 ifTrue:[ + ^ self next. + ]. + nCharactersToRead == 0 ifTrue:[ + ^ ''. + ]. + + peekChar isNil ifTrue:[ + ^ encoder readNext:nCharactersToRead charactersFrom:stream. + ]. + + chars := encoder readNext:nCharactersToRead-1 charactersFrom:stream. + chars := chars copyWithFirst:peekChar. + peekChar := nil. + ^ chars. "Created: / 16-06-2005 / 11:43:43 / masca" + "Modified: / 03-01-2018 / 22:22:51 / stefan" ! nextPut:aCharacter @@ -316,19 +343,23 @@ ! peek - - ^stream peek + peekChar isNil ifTrue:[ + peekChar := self next. + ]. + ^ peekChar "Created: / 20-06-2005 / 10:13:03 / masca" "Modified: / 20-06-2005 / 13:06:14 / masca" -! - -peekFor:aCharacter - ^ stream peekFor:aCharacter + "Modified (format): / 02-01-2018 / 19:21:00 / stefan" ! position + "only use #position/#position: to restore a previous position. + Computing relative positions does not work!!" + ^ stream position + + "Modified (comment): / 09-01-2018 / 17:49:55 / stefan" ! position0Based @@ -349,28 +380,44 @@ "to be obsoleted - use position" - ^ stream position + 1 + ^ stream position1Based + + "Modified: / 02-01-2018 / 20:00:57 / stefan" ! position1Based:newPosition "to be obsoleted - use position" - stream position:newPosition-1 + stream position1Based:newPosition + + "Modified: / 02-01-2018 / 20:00:46 / stefan" ! position:newPosition + "only use #position/#position: to restore a previous position. + Computing relative positions does not work!! + Use #skip: to advance forward." + + peekChar := nil. stream position:newPosition + + "Modified (comment): / 09-01-2018 / 17:53:04 / stefan" ! reset + peekChar := nil. stream reset "Created: / 25-02-2010 / 23:37:14 / Jan Vrany " + "Modified: / 02-01-2018 / 19:34:20 / stefan" ! setToEnd + peekChar := nil. stream setToEnd + + "Modified (comment): / 09-01-2018 / 17:50:27 / stefan" ! size @@ -384,18 +431,6 @@ "Created: / 31-08-2012 / 16:52:40 / cg" ! -skip: anInteger - - "/ Should skip on character basis, not on bytes. This works for XML reader - ^stream skip: anInteger - - "Created: / 20-06-2005 / 13:06:06 / masca" -! - -skipSeparators - ^ stream skipSeparators -! - sync stream sync ! @@ -412,6 +447,15 @@ "Created: / 04-02-2014 / 20:27:36 / Jan Vrany " ! +isOpen + "for compatibility with externalStream: + return true, if this stream is open." + + ^ stream notNil and:[stream isOpen]. + + "Modified (comment): / 09-01-2018 / 18:34:47 / stefan" +! + isPositionable ^ stream isPositionable