Java Base64 Decode decodeBASE64(InputStream in, OutputStream out)

Here you can find the source of decodeBASE64(InputStream in, OutputStream out)

Description

This implements a BASE64 character decoder as specified in RFC1521.

License

Open Source License

Return

number of bytes written to the output stream

Declaration

public static int decodeBASE64(InputStream in, OutputStream out)
        throws IOException 

Method Source Code

//package com.java2s;
/*// w  w w . java  2  s  .co  m
 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description: 
 *
 */

import java.io.IOException;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class Main {
    private static final byte base64DecodeMap[] = new byte[256];

    /**
     * This implements a BASE64 character decoder as specified
     * in RFC1521.
     *
     * @return number of bytes written to the output stream
     */
    public static int decodeBASE64(InputStream in, OutputStream out)
            throws IOException {
        int written = 0;
        byte[] chunk = new byte[4];

        while (base64ReadChunk(in, chunk)) {
            byte a = -1, b = -1, c = -1, d = -1;
            int rem = ((chunk[3] == '=') ? ((chunk[2] == '=') ? 2 : 3) : 4);
            try {
                switch (rem) {
                case 4:
                    d = base64DecodeMap[chunk[3]];
                    // NOBREAK
                case 3:
                    c = base64DecodeMap[chunk[2]];
                    // NOBREAK
                case 2:
                    b = base64DecodeMap[chunk[1]];
                    a = base64DecodeMap[chunk[0]];
                    break;
                }
            } catch (ArrayIndexOutOfBoundsException x) {
                throw new IOException("BASE64Decoder: invalid atom: 0x"
                        + Integer.toHexString(a) + ", 0x"
                        + Integer.toHexString(b) + ", 0x"
                        + Integer.toHexString(c) + ", 0x"
                        + Integer.toHexString(d));
            }

            switch (rem) {
            case 2:
                out.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
                break;
            case 3:
                out.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
                out.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)));
                break;
            case 4:
                out.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
                out.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)));
                out.write((byte) (((c << 6) & 0xc0) | (d & 0x3f)));
                break;
            }
            written += rem - 1;
        }
        return written;
    }

    /**
     * Decodes BASE64 encoded binary data
     * @exception IOException if the input string does not conform to BASE64
     * specification
     */
    public static byte[] decodeBASE64(String text) throws IOException {
        if (text == null || text.length() == 0) {
            return new byte[0];
        } else {
            int size = text.length() * 3 / 4;
            ByteArrayOutputStream out = new ByteArrayOutputStream(size);
            decodeBASE64(new ByteArrayInputStream(text.getBytes()), out);
            return out.toByteArray();
        }
    }

    /**
     * Fully reads a chunk of data from an IO stream.
     * Returns <code>true</code> if the chunk of data has been read, or
     * <code>false</code> if end of file has been reached.
     *
     * This code does not handle empty characters in the middle of
     * BASE64 stream which is OK for the purposes of XRPC.
     *
     * @exception IOException of end of file has been reached before
     * the chunk od data has been fully read
     */
    private static boolean base64ReadChunk(InputStream in, byte[] chunk)
            throws IOException {
        int count = in.read(chunk);
        if (count < 0) {
            return false; // normal end of file condition
        } else if (count == chunk.length) {
            return true; // got the whole chunk in one shot
        } else {
            throw new IOException(
                    "BASE64Decoder: Not enough bytes for an atom.");
        }
    }
}

Related

  1. base64Decoder(char[] src, int start)
  2. base64decodeString(String inputString)
  3. decode(String base64)
  4. decode(String base64Code)
  5. decodeBase64(char[] data)
  6. decodeBase64(InputStream is, OutputStream os)
  7. decodeBase64(String base64Data)
  8. decodeBase64(String data)
  9. decodeBase64(String data)