#BUGFIX by stefan
authorStefan Vogel <sv@exept.de>
Wed, 10 Jan 2018 23:01:58 +0100
changeset 22415 769a6b3f0a19
parent 22414 8a15c1e6c4a8
child 22416 3d6e05b588a1
#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
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 <jan.vrany@fit.cvut.cz>"
-!
-
-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 @@
     <resource: #obsolete>
     "to be obsoleted - use position"
 
-    ^ stream position + 1
+    ^ stream position1Based
+
+    "Modified: / 02-01-2018 / 20:00:57 / stefan"
 !
 
 position1Based:newPosition
     <resource: #obsolete>
     "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 <jan.vrany@fit.cvut.cz>"
+    "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 <jan.vrany@fit.cvut.cz>"
 !
 
+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