[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-smalltalk] NetClients.ESMTP package
From: |
Joachim Jaeckel |
Subject: |
Re: [Help-smalltalk] NetClients.ESMTP package |
Date: |
Mon, 29 Jun 2009 13:32:42 +0200 |
User-agent: |
Mozilla-Thunderbird 2.0.0.19 (X11/20090103) |
Hello again,
I currently "finished" the work on the Base64 class and here it is.
If I have time or you recommend it as an important part, I'll enhance it
with base64 after MIME, base 64 after PEM and base64 with the URL-save
alphabet.
(The changes are only CRLF after 76 or 64 Bytes of data and for URLs,
using another alphabet which differs in using the character '-' and '_'
instead of '+' and '/'.)
But the current implementation would be enough for my current needs.
Best regards,
Joachim.
"======================================================================
|
| Base64 class declarations
|
|
======================================================================"
"======================================================================
|
| Copyright 2009
| Written by Joachim Jaeckel
|
| This file is part of the GNU Smalltalk class library.
|
| The GNU Smalltalk class library is free software; you can redistribute it
| and/or modify it under the terms of the GNU Lesser General Public License
| as published by the Free Software Foundation; either version 2.1, or (at
| your option) any later version.
|
| The GNU Smalltalk class library is distributed in the hope that it will be
| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
| General Public License for more details.
|
| You should have received a copy of the GNU Lesser General Public License
| along with the GNU Smalltalk class library; see the file COPYING.LIB.
| If not, write to the Free Software Foundation, 59 Temple Place - Suite
| 330, Boston, MA 02110-1301, USA.
|
======================================================================"
Namespace current: NetClients.MIME [
Object subclass: Base64 [
Base64 class >> encode: aString [
| chars i j copyTo triple c1 c2 c3 c4 aStringSize b64SizeMultiplier
b64String |
chars :=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.
aStringSize := aString size.
b64SizeMultiplier := aStringSize // 3.
(aStringSize \\ 3 ~= 0) ifTrue: [b64SizeMultiplier := b64SizeMultiplier
+1].
b64String := String new: (b64SizeMultiplier * 4) withAll: $=.
i := j := 1.
[i <= aStringSize] whileTrue: [
copyTo := i +2.
(copyTo > aStringSize) ifTrue: [copyTo := aStringSize].
triple := aString copyFrom: i to: copyTo.
triple growBy: 1.
triple at: (triple size) put: Character nul.
c1 := (triple at: 1) asInteger bitShift: -2.
b64String at: j put: (chars at: c1 +1).
j := j +1.
c2 := (((triple at: 1) asInteger bitAnd: 3) bitShift: 4) bitOr:
((triple at: 2) asInteger bitShift: -4).
b64String at: j put: (chars at: c2 +1).
j := j +1.
(triple size > 2) ifTrue: [
c3 := (((triple at: 2) asInteger bitAnd: 15) bitShift: 2)
bitOr: ((triple at: 3) asInteger bitShift: -6).
b64String at: j put: (chars at: c3 +1).
j := j +1.
].
(triple size > 3) ifTrue: [
c4 := (triple at: 3) asInteger bitAnd: 63.
b64String at: j put: (chars at: c4 +1).
j := j +1.
].
i := i +3.
].
^b64String
]
Base64 class >> decode: aString [
| chars b64StringSize i j quad padding string c1 c2 c3 |
chars :=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.
b64StringSize := aString size.
"Size should be a multiple of 4"
(b64StringSize \\ 4 ~= 0)
ifTrue: [
^NotBase64Encoded new signal: ('String: ''%1'' is not base64
encoded' bindWith: aString)
].
"and should contain only defined character"
aString do: [:char |
(chars indexOf: char) = 0 & (char ~= $=) ifTrue: [
^NotBase64Encoded new signal: ('String: ''%1'' is not base64
encoded' bindWith: aString)
]
].
padding := 0.
i := b64StringSize.
[(aString at: i) = $=] whileTrue: [
padding := padding +1.
i := i -1.
].
string := String new: (b64StringSize // 4 * 3 - padding) withAll:
Character nul.
i := j := 1.
[i <= b64StringSize] whileTrue: [
quad := aString copyFrom: i to: i +3.
c1 := ((chars indexOf: (quad at: 1)) asInteger -1 bitShift: 2)
bitOr: ((chars indexOf: (quad at: 2)) asInteger -1 bitShift: -4).
string at: j put: c1 asCharacter.
j := j +1.
(quad at: 3) ~= $= ifTrue: [
c2 := (((chars indexOf: (quad at: 2)) asInteger -1 bitAnd: 15)
bitShift: 4) bitOr: ((chars indexOf: (quad at: 3)) asInteger -1 bitShift: -2).
string at: j put: c2 asCharacter.
j := j +1.
].
(quad at: 4) ~= $= ifTrue: [
c3 := (((chars indexOf: (quad at: 3)) asInteger -1 bitAnd: 3)
bitShift: 6) bitOr: ((chars indexOf: (quad at: 4)) asInteger -1).
string at: j put: c3 asCharacter.
j := j +1.
].
i := i +4.
].
^string
]
]
Notification subclass: NotBase64Encoded [
description [
^'String is not Base64 encoded'
]
]
]