|
Class: Base64Coder
Object
|
+--Visitor
|
+--AspectVisitor
|
+--ObjectCoder
|
+--BaseNCoder
|
+--Base64Coder
|
+--Base64UrlCoder
- Package:
- stx:libbasic2
- Category:
- System-Storage
- Version:
- rev:
1.37
date: 2019/03/23 20:49:56
- user: cg
- file: Base64Coder.st directory: libbasic2
- module: stx stc-classLibrary: libbasic2
- Author:
- Stefan Vogel
Instances of this class perform Base64 en- and decoding as defined in RFC 2045
3 bytes are mapped to 4 characters, representing 6 bits each.
The encoded string consists only of characters from the set:
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
Notice: for URLs, a slightly different encoding is used,
where instead of plus and slash, minus and underline are generated (see Base64UrlCoder).
The main entry point API is:
Base64Coder encode:aStringOrBytes
and
Base64Coder decode:aString
Typically, binary data is encoded as base64,
so the natural return value is a byte array.
If the decoder should return a string, use
Base64Coder decodeAsString:aString.
otherwise, a bytearray is returned from the decode: method.
[instance variables:]
[class variables:]
Base64Mapping String Mapping from bytes (with 6 valid bits)
to Base64 characters
Base64ReverseMapping Array Mapping from Base64 characters to 6-bit-Bytes
RFC
[ttps]
decoding
-
decode: aStringOrStream
-
because base64 decoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of decoding a string.
This returns a byteArray.
-
decodeAsString: encodedString
-
because base64 decoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of decoding a string.
This returns a string.
-
encode: aStringOrStream
-
because base64 encoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of encoding a string.
A string is generated with an inserted
newline after every 76 characters (see RFC 2045)
-
fastDecodeString: aString
-
because base64 decoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of decoding a string.
This returns a byteArray
usage example(s):
(Base64Coder encode:'queen%27s%20gambit') => 'cXVlZW4lMjdzJTIwZ2FtYml0'
(Base64Coder decode:'cXVlZW4lMjdzJTIwZ2FtYml0') => #[113 117 101 101 110 37 50 55 115 37 50 48 103 97 109 98 105 116]
(Base64Coder decode:'cXVlZW4lMjdzJTIwZ2FtYml0') asString => 'queen%27s%20gambit'
(Base64Coder decodeAsString:'cXVlZW4lMjdzJTIwZ2FtYml0') => 'queen%27s%20gambit'
(Base64Coder fastDecodeString:'cXVlZW4lMjdzJTIwZ2FtYml0') asString => 'queen%27s%20gambit'
|
-
fastDecodeString: aString asString: asStringBoolean
-
because base64 decoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of decoding a string.
If the argument is true, a string is returned;
otherwise, a bytearray
usage example(s):
(Base64Coder encode:'queen%27s%20gambit') => 'cXVlZW4lMjdzJTIwZ2FtYml0'
(Base64Coder decode:'cXVlZW4lMjdzJTIwZ2FtYml0') asString => 'queen%27s%20gambit'
(Base64Coder fastDecodeString:'cXVlZW4lMjdzJTIwZ2FtYml0') asString => 'queen%27s%20gambit'
(Base64Coder fastDecodeString:'cXVlZW4lMjdzJTIwZ2FtYml0' asString:true) => 'queen%27s%20gambit'
(Base64Coder encode:'a') => 'YQ=='
(Base64Coder fastDecodeString:'YQ==' asString:true) => 'a'
(Base64Coder encode:'aa') => 'YWE='
(Base64Coder fastDecodeString:'YWE=' asString:true) => 'aa'
|data encoded|
data := ByteArray new:100000.
encoded := Base64Coder encode:data.
Time millisecondsToRun:[
10 timesRepeat:[
Base64Coder decode:encoded.
]
]
|data encoded|
data := ByteArray new:100000.
encoded := Base64Coder encode:data.
Time millisecondsToRun:[
10 timesRepeat:[
Base64Coder fastDecodeString:encoded.
]
]
|
-
fastEncode: aStringOrByteArray
-
because base64 encoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of encoding a string or bytearray.
A string is generated with an inserted
newline after every 76 characters (see RFC 2045)
-
fastEncode: aStringOrByteArray asString: asStringBoolean
-
because base64 encoding is used heavily in some protocols,
a specially tuned version is provided here,
for the common case of encoding a string or bytearray.
If asStringBoolean is true, a string is generated; otherwise, a bytearray is returned.
A newline is inserted after every 76 characters (see RFC 2045)
-
fastEncode: aStringOrByteArray asString: asStringBoolean lineLimit: lineLimitOrNil
-
because base64 encoding is used heavily in some protocols,
a specially tuned version is provided here
for the common case of encoding a string.
If asStringBoolean is true, a string is generated; otherwise, a bytearray is returned.
If lineLimitOrNil is non-nil, a newline is inserted after every such number of characters
usage example(s):
(Base64Coder encode:'queen%27s%20gambit') => 'cXVlZW4lMjdzJTIwZ2FtYml0'
(Base64Coder fastEncode:'queen%27s%20gambit' asString:true) => 'cXVlZW4lMjdzJTIwZ2FtYml0'
(Base64Coder decode:'cXVlZW4lMjdzJTIwZ2FtYml0') asString => 'queen%27s%20gambit'
(Base64Coder fastDecodeString:'cXVlZW4lMjdzJTIwZ2FtYml0') asString => 'queen%27s%20gambit'
(Base64Coder fastDecodeString:'cXVlZW4lMjdzJTIwZ2FtYml0' asString:true) => 'queen%27s%20gambit'
(Base64Coder encode:'a') => 'YQ=='
(Base64Coder fastEncode:'a' asString:true) => 'YQ=='
(Base64Coder fastDecodeString:'YQ==' asString:true) => 'a'
(Base64Coder encode:'aa') => 'YWE='
(Base64Coder fastEncode:'aa' asString:true) => 'YWE='
(Base64Coder fastDecodeString:'YWE=' asString:true) => 'aa'
|data|
data := ByteArray new:1000.
Time millisecondsToRun:[
10000 timesRepeat:[self halt.
Base64Coder encode:data.
]
]
|data|
data := ByteArray new:1000.
Base64Coder fastEncode:data asString:true lineLimit:20.
|data|
data := ByteArray new:1000.
Base64Coder fastEncode:data asString:true lineLimit:nil.
|data|
data := ByteArray new:1000.
Time millisecondsToRun:[
10000 timesRepeat:[
Base64Coder fastEncode:data.
]
]
self assert:((Base64Coder fastEncode:'abc' asString:true)
= 'abc' base64Encoded).
self assert:((Base64Coder fastEncode:'a' asString:true)
= 'a' base64Encoded).
self assert:((Base64Coder fastEncode:'ab' asString:true)
= 'ab' base64Encoded).
self assert:((Base64Coder fastEncode:'abcd' asString:true)
= 'abcd' base64Encoded).
self assert:((Base64Coder fastEncode:'abcde' asString:true)
= 'abcde' base64Encoded).
self assert:((Base64Coder fastEncode:'abcdef' asString:true)
= 'abcdef' base64Encoded).
self assert:((Base64Coder fastEncode:#'parseMethod:onError:rememberNodes:nodeGenerationCallback:' asString:true)
= #'parseMethod:onError:rememberNodes:nodeGenerationCallback:' base64Encoded).
self assert:((Base64Coder fastEncode:'_INVOKESTATIC_R:' asString:true)
= '_INVOKESTATIC_R:' base64Encoded).
self assert:((Base64Coder fastEncode:#'_INVOKESTATIC_R:' asString:true)
= #'_INVOKESTATIC_R:' base64Encoded)
self assert:((Base64Coder fastEncode:'_INVOKESTATIC_R:' asString:true)
= (Base64Coder fastEncode:#'_INVOKESTATIC_R:' asString:true)).
self assert:((#'_INVOKESTATIC_R:' base64Encoded)
= ('_INVOKESTATIC_R:' base64Encoded)).
self assert:((Base64Coder fastEncode:'_INVOKESTATIC_R:_:' asString:true)
= '_INVOKESTATIC_R:_:' base64Encoded).
self assert:((Base64Coder fastEncode:#'_INVOKESTATIC_R:_:' asString:true)
= #'_INVOKESTATIC_R:_:' base64Encoded)
self assert:((Base64Coder fastEncode:'_INVOKESTATIC_R:_:' asString:true)
= (Base64Coder fastEncode:#'_INVOKESTATIC_R:_:' asString:true)).
self assert:((#'_INVOKESTATIC_R:_:' base64Encoded)
= ('_INVOKESTATIC_R:_:' base64Encoded)).
Symbol allInstancesDo:[:each |
self assert:((Base64Coder fastEncode:each asString:true)
= (Base64Coder encode:each with:nil))
]
|
initialization
-
initializeMappings
-
initialize class variables
usage example(s):
Base64Mapping := nil.
self initializeMappings
|
-
mapping
-
-
reverseMapping
-
encoding
-
nextPutByte: aByte
-
encode aByte on the output stream
misc
-
flush
-
flush the remaining bits of buffer.
The number of bits in buffer is not a multiple of 6, so we pad
the buffer and signal that padding has been done via $= characters.
private
-
fillBuffer
-
fill buffer with next 4 characters each representing 6 bits.
Used when decoding.
(Base64Coder encode:'queen%27s%20gambit') asString = 'cXVlZW4lMjdzJTIwZ2FtYml0'
|
(Base64Coder decode:'cXVlZW4lMjdzJTIwZ2FtYml0') asString = 'queen%27s%20gambit'
|
|data1 text data2|
data1 := #[0 1 16r7F 16r80 16r81 16rFE 16rFF].
text := Base64Coder encode:data1.
data2 := Base64Coder decode:text.
data2
|
|coder|
coder := Base64Coder on:'' writeStream.
coder nextPutAll:#[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19].
coder flush.
coder contents inspect.
coder reset.
coder nextPut:254.
coder contents inspect.
|
|coder decoder|
coder := Base64Coder on:'' writeStream.
coder nextPutAll:#[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20].
coder flush.
decoder := Base64Coder on:(coder contents readStream).
[decoder atEnd] whileFalse:[
Transcript show:decoder next
].
Transcript cr.
|
|coder|
coder := Base64Coder on:'' writeStream.
coder nextPutAll:(0 to:200) asByteArray.
coder flush.
Transcript showCR:(coder contents).
|
|bytes|
bytes := ByteArray new:100000.
Time millisecondsToRun:[
100 timesRepeat:[
Base64Coder encode:bytes.
].
].
|
|bytes encoded decoded|
bytes := #[0 0 0] copy.
0 to:255 do:[:b1 |
Transcript showCR:b1.
bytes at:1 put:b1.
0 to:255 do:[:b2 |
bytes at:2 put:b2.
0 to:255 do:[:b3 |
bytes at:3 put:b3.
encoded := Base64Coder encode:bytes.
decoded := Base64Coder decode:encoded.
self assert:(decoded = bytes).
]
]
].
|
|