Base64 Character decoder as specified in RFC1113. : Base64 Stream « File Input Output « Java






Base64 Character decoder as specified in RFC1113.

   


import java.io.IOException;
import java.io.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:
 * <pre>
 *      byte    data[];
 *      InputStream is = new ByteArrayInputStream(data);
 *      is = new Base64DecodeStream(is);
 * </pre>
 *
 * On errors, this class throws a IOException with the following detail
 * strings:
 * <pre>
 *    "Base64DecodeStream: Bad Padding byte (2)."
 *    "Base64DecodeStream: Bad Padding byte (1)."
 * </pre>
 *
 * @author <a href="mailto:thomas.deweese@kodak.com">Thomas DeWeese</a>
 * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
 * @author      Chuck McManis
 * @version $Id: Base64DecodeStream.java 501495 2007-01-30 18:00:36Z dvholten $
 */
public class Base64DecodeStream extends InputStream {

    InputStream src;

    public Base64DecodeStream(InputStream src) {
        this.src = src;
    }

    private static final byte[] pem_array = new byte[256];

    static {
        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++;
    }

    public boolean markSupported() { return false; }

    public void close()
        throws IOException {
        EOF = true;
    }

    public int available()
        throws IOException {
        return 3-out_offset;
    }

    byte[] decode_buffer = new byte[4];
    byte[] out_buffer = new byte[3];
    int  out_offset = 3;
    boolean EOF = false;

    public int read() throws IOException {

        if (out_offset == 3) {
            if (EOF || getNextAtom()) {
                EOF = true;
                return -1;
            }
        }

        return ((int)out_buffer[out_offset++])&0xFF;
    }

    public int read(byte []out, int offset, int len)
        throws IOException {

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

            out[offset+idx] = out_buffer[out_offset++];

            idx++;
        }
        return idx;
    }

    final boolean getNextAtom() throws IOException {
        int count, a, b, c, d;

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

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

            off = out;
        }

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

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

        if (decode_buffer[3] != '=') {
            // All three bytes are good.
            out_offset=0;
        } else if (decode_buffer[2] == '=') {
            // Only one byte of output.
            out_buffer[2] = out_buffer[0];
            out_offset = 2;
            EOF=true;
        } else {
            // Only two bytes of output.
            out_buffer[2] = out_buffer[1];
            out_buffer[1] = out_buffer[0];
            out_offset = 1;
            EOF=true;
        }

        return false;
    }
}

   
    
    
  








Related examples in the same category

1.BASE64 Decoder Stream
2.BASE64 Encoder Stream from Sun Microsystems
3.Base64 Character encoder as specified in RFC1113.
4.Performs Base-64 decoding on an underlying stream.
5.Class encodes the bytes written to the OutPutStream to a Base64 encoded string.
6.BASE64 Decoder Stream from Sun Microsystems
7.BASE64 Encoder Stream
8.Decode a BASE64 encoded input stream to some output stream
9.Hex dump
10.Dumps data in hexadecimal format
11.Apply a ASCII Hex encoding to the stream
12.Base64 Codec
13.Base64 encoding from DbUnit.org
14.Base64 provides Base64 encoding/decoding of strings and streams
15.Base64 - encode/decode data using the Base64 encoding scheme
16.Base64 from Eric Glass jcifs at samba dot org