Base64Coder.st
changeset 1484 9772f2d67819
parent 1458 0c76da4e4ef5
child 1639 dd7c77c44be6
--- a/Base64Coder.st	Fri Oct 01 09:53:42 2004 +0200
+++ b/Base64Coder.st	Mon Oct 25 14:21:27 2004 +0200
@@ -61,9 +61,9 @@
 examples
 "
                                                                 [exBegin]
-   |coder decoder data encoding decoded|
+   0 to:16 do:[:l |
+        |coder decoder data encoding decoded|
 
-   0 to:16 do:[:l |
         data := (0 to:l) asByteArray copyTo:l.
         coder := Base64Coder on:'' writeStream.
         coder nextPutAll:data.
@@ -151,67 +151,16 @@
 !Base64Coder methodsFor:'accessing'!
 
 lineLimit:something
+    "set the line length of the encoded output.
+     Default is a line length of 76 characters.
+
+     If nil, no line breaks will be done."
+
     lineLimit := something.
 ! !
 
 !Base64Coder methodsFor:'decoding'!
 
-basicNext
-    "answer the next decoded byte"
-
-    |b|
-
-    bits == 0 ifTrue:[
-        self fillBuffer.
-        bits == 0 ifTrue:[
-            ^ stream class endOfStreamSignal raiseRequest.
-        ]
-    ].
-    b := (buffer bitShift:(8 - bits)) bitAnd:16rFF.
-    bits := bits - 8.
-
-    ^ b.
-!
-
-fillBuffer
-    "fill buffer with next 4 characters each representing 6 bits"
-
-    |b shift|
-
-    buffer := 0.
-    bits := 0.
-    [
-        "read next valid Base64 character, skip invalid characters"
-        [
-            b := stream next.
-            b isNil ifTrue:[ "end of stream"
-                b := 64. "/ end-mark
-                "/ atEnd := true.
-                "/ ^ self.
-            ] ifFalse:[
-                b := Base64ReverseMapping at:b codePoint.
-            ]
-        ] doWhile:[b == 255].
-        b == 64 ifTrue:[
-            "got #=, end of Base64 string has been reached"
-            atEnd := true.
-            bits == 12 ifTrue:[
-                "data has been padded to 12, skip 4 bits"
-                shift := -4.
-            ] ifFalse:[
-                "data has been padded to 18, skip 2 bits"
-                shift := -2.
-            ].
-            bits := bits + shift.
-            buffer := buffer bitShift:shift.
-        ] ifFalse:[
-            "got valid Base64 character, append to buffer"
-            buffer := (buffer bitShift:6) bitOr:b.
-            bits := bits + 6.
-        ].
-    ] doWhile:[bits ~~ 24 and:[atEnd not]].
-!
-
 next
     "answer the next decoded byte"
 
@@ -226,7 +175,7 @@
 !
 
 peek
-    "answer the next decoded byte"
+    "answer the next decoded byte. Do not consume this byte"
 
     peekByte isNil ifTrue:[
         peekByte := self basicNext.
@@ -364,6 +313,68 @@
     super reset.
     buffer := bits := charCount := 0.
     atEnd := false.
+    peekByte := nil.
+! !
+
+!Base64Coder methodsFor:'private'!
+
+basicNext
+    "answer the next decoded byte. 
+     Not peekByte handling is done here."
+
+    |b|
+
+    bits == 0 ifTrue:[
+        self fillBuffer.
+        bits == 0 ifTrue:[
+            ^ stream pastEndRead.
+        ]
+    ].
+    b := (buffer bitShift:(8 - bits)) bitAnd:16rFF.
+    bits := bits - 8.
+
+    ^ b.
+!
+
+fillBuffer
+    "fill buffer with next 4 characters each representing 6 bits"
+
+    |b shift tempBuffer "{Class: SmallInteger}"|
+
+    tempBuffer := 0.
+    bits := 0.
+    [
+        "read next valid Base64 character, skip invalid characters"
+        [
+            b := stream next.
+            b isNil ifTrue:[ "end of stream"
+                b := 64. "/ end-mark
+            ] ifFalse:[
+                b := Base64ReverseMapping at:b codePoint.
+            ]
+        ] doWhile:[b == 255].
+        b == 64 ifTrue:[
+            "got $=, end of Base64 string has been reached"
+            atEnd := true.
+            bits == 12 ifTrue:[
+                "data has been padded to 12, skip 4 bits"
+                shift := -4.
+            ] ifFalse:[bits == 18 ifTrue:[
+                "data has been padded to 18, skip 2 bits"
+                shift := -2.
+            ] ifFalse:[
+                shift := 0.
+            ]].
+            tempBuffer := tempBuffer bitShift:shift.
+            bits := bits + shift.
+        ] ifFalse:[
+            "got valid Base64 character, append to buffer"
+            tempBuffer := (tempBuffer bitShift:6) bitOr:b.
+            bits := bits + 6.
+        ].
+    ] doWhile:[bits ~~ 24 and:[atEnd not]].
+
+    buffer := tempBuffer.
 ! !
 
 !Base64Coder methodsFor:'queries'!
@@ -371,19 +382,24 @@
 atEnd
     "answer true, if no more bytes can be read"
 
-    bits <= 0 ifTrue:[
+    bits == 0 ifTrue:[
         atEnd ifTrue:[^ true].
         self fillBuffer.
-        bits <= 0 ifTrue:[^ true].
+        bits == 0 ifTrue:[^ true].
     ].
     ^ false.
 !
 
 binary
+    "switch to binary mode - nothing is done here.
+     Defined for compatibility with ExternalStream."
+
     ^ self
 !
 
 isStream
+    "we simulate a stream"
+
     ^ true
 ! !
 
@@ -403,15 +419,22 @@
 !
 
 upToEnd
-    "return a collection of the elements up-to the end.
-     Return nil if the stream-end is reached before."
+    "return a collection of the elements up-to the end"
 
     |answerStream|
 
     answerStream := WriteStream on:(ByteArray new:128).
-    [self atEnd] whileFalse:[
-        answerStream nextPut:self next
+    peekByte notNil ifTrue:[
+        answerStream nextPut:peekByte.
+        peekByte := nil.
     ].
+    [
+        [bits ~~ 0] whileTrue:[
+            answerStream nextPut:((buffer bitShift:(8 - bits)) bitAnd:16rFF).
+            bits := bits - 8.
+        ].
+        self fillBuffer.
+    ] doWhile:[bits ~~ 0].
 
     ^ answerStream contents
 ! !
@@ -419,7 +442,7 @@
 !Base64Coder class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/Base64Coder.st,v 1.14 2004-06-11 18:08:23 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Base64Coder.st,v 1.15 2004-10-25 12:21:27 stefan Exp $'
 ! !
 
 Base64Coder initialize!