FileDocCategorySizeDatePackage
Base64DecodeStream.javaAPI DocphoneME MR2 API (J2ME)7237Wed May 02 18:00:34 BST 2007com.sun.perseus.util

Base64DecodeStream

public class Base64DecodeStream extends InputStream
This class implements a Base64 Character decoder as specified in RFC1113. Unlike some other encoding schemes there is nothing in this encoding that tells the decoder where a buffer starts or stops, so to use it you will need to isolate your encoded data into a single chunk and then feed them this decoder. The simplest way to do that is to read all of the encoded data into a string and then use:
byte data[];
InputStream is = new ByteArrayInputStream(data);
is = new Base64DecodeStream(is);
On errors, this class throws a IOException with the following detail strings:
"Base64DecodeStream: Bad Padding byte (2)."
"Base64DecodeStream: Bad Padding byte (1)."
author
Thomas DeWeese
author
Chuck McManis
version
$Id: Base64DecodeStream.java,v 1.2 2006/04/21 06:35:45 st125089 Exp $

Fields Summary
protected InputStream
src
The stream to be decoded
private static final byte[]
PEM_ARRAY
Decode table
protected byte[]
decodeBuffer
Encoded data buffer
protected byte[]
outBuffer
Output buffer
protected int
outOffset
Offset in the out buffer
protected boolean
eof
Controls whether the end of the input stream has been reached
Constructors Summary
public Base64DecodeStream(InputStream src)

param
src the Base64 encoded input stream

        this.src = src;
    
Methods Summary
public intavailable()

return
the number of available bytes
throws
IOException if an I/O error occurs

        return 3 - outOffset;
    
public voidclose()
Closes the stream. Note that this does not close the associated InputStream

     
        for (int i = 0; i < PEM_ARRAY.length; i++) {
            PEM_ARRAY[i] = -1;
        }

        int idx = 0;
        for (char c = 'A"; c <= 'Z"; c++) {
            PEM_ARRAY[c] = (byte) idx++;
        }
        for (char c = 'a"; c <= 'z"; c++) {
            PEM_ARRAY[c] = (byte) idx++;
        }

        for (char c = '0"; c <= '9"; c++) {
            PEM_ARRAY[c] = (byte) idx++;
        }

        PEM_ARRAY['+"] = (byte) idx++;
        PEM_ARRAY['/"] = (byte) idx++;
    
        eof = true;
    
final booleangetNextAtom()

return
true if the next atom has been read
throws
IOException if an I/O error happens

        int count, a, b, c, d;

        int off = 0;
        while (off != 4) {
            count = src.read(decodeBuffer, off, 4 - off);
            if (count == -1) {
                return true;
            }

            int in = off, out = off;
            while (in < off + count) {
                if ((decodeBuffer[in] != '\n") 
                    && (decodeBuffer[in] != '\r")
                    && (decodeBuffer[in] != ' ")) {
                    decodeBuffer[out++] = decodeBuffer[in];
                }
                in++;
            }

            off = out;
        }

        a = PEM_ARRAY[((int) decodeBuffer[0]) & 0xFF];
        b = PEM_ARRAY[((int) decodeBuffer[1]) & 0xFF];
        c = PEM_ARRAY[((int) decodeBuffer[2]) & 0xFF];
        d = PEM_ARRAY[((int) decodeBuffer[3]) & 0xFF];

        outBuffer[0] = (byte) ((a << 2) | (b >>> 4));
        outBuffer[1] = (byte) ((b << 4) | (c >>> 2));
        outBuffer[2] = (byte) ((c << 6) |  d);

        if (decodeBuffer[3] != '=") {
            // All three bytes are good.
            outOffset = 0;
        } else if (decodeBuffer[2] == '=") {
            // Only one byte of output.
            outBuffer[2] = outBuffer[0];
            outOffset = 2;
            eof = true;
        } else {
            // Only two bytes of output.
            outBuffer[2] = outBuffer[1];
            outBuffer[1] = outBuffer[0];
            outOffset = 1;
            eof = true;
        }
            
        return false;
    
public intread()

return
the next byte of data or -1 if the end of the stream is reached.
throws
IOException if an I/O error occurs.


                                         
         

        if (outOffset == 3) {
            if (eof || getNextAtom()) {
                eof = true;
                return -1;
            }
        }

        return ((int) outBuffer[outOffset++]) & 0xFF;
    
public intread(byte[] out, int offset, int len)

param
out where the decoded content should go
param
offset in the out array
param
len the number of atoms to read
return
the number of atoms that were actually read
throws
IOException if an I/O error happens


        int idx = 0;
        while (idx < len) {
            if (outOffset == 3) {
                if (eof || getNextAtom()) {
                    eof = true;
                    if (idx == 0) {
                        return -1;
                    } else {
                        return idx;
                    }
                }
            }

            out[offset + idx] = outBuffer[outOffset++];

            idx++;
        }
        return idx;