help-smalltalk
[Top][All Lists]
Advanced

[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'
    ]

]

]

reply via email to

[Prev in Thread] Current Thread [Next in Thread]