151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1995, 2000, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.misc; 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.OutputStream; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.PushbackInputStream; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.PrintStream; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class implements a BASE64 Character decoder as specified in RFC1521. 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This RFC is part of the MIME specification which is published by the 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Internet Engineering Task Force (IETF). Unlike some other encoding 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * schemes there is nothing in this encoding that tells the decoder 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * where a buffer starts or stops, so to use it you will need to isolate 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * your encoded data into a single chunk and then feed them this decoder. 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The simplest way to do that is to read all of the encoded data into a 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * string and then use: 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte mydata[]; 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * BASE64Decoder base64 = new BASE64Decoder(); 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * mydata = base64.decodeBuffer(bufferString); 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This will decode the String in <i>bufferString</i> and give you an array 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of bytes in the array <i>myData</i>. 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * On errors, this class throws a CEFormatException with the following detail 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * strings: 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "BASE64Decoder: Not enough bytes for an atom." 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Chuck McManis 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see CharacterEncoder 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see BASE64Decoder 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class BASE64Decoder extends CharacterDecoder { 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** This class has 4 bytes per atom */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int bytesPerAtom() { 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (4); 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Any multiple of 4 will do, 72 might be common */ 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int bytesPerLine() { 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (72); 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This character array provides the character to value map 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * based on RFC1521. 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final static char pem_array[] = { 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 0 1 2 3 4 5 6 7 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'A','B','C','D','E','F','G','H', // 0 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'I','J','K','L','M','N','O','P', // 1 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'Q','R','S','T','U','V','W','X', // 2 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'Y','Z','a','b','c','d','e','f', // 3 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'g','h','i','j','k','l','m','n', // 4 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'o','p','q','r','s','t','u','v', // 5 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 'w','x','y','z','0','1','2','3', // 6 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski '4','5','6','7','8','9','+','/' // 7 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }; 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final static byte pem_convert_array[] = new byte[256]; 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < 255; i++) { 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pem_convert_array[i] = -1; 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; i < pem_array.length; i++) { 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pem_convert_array[pem_array[i]] = (byte) i; 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte decode_buffer[] = new byte[4]; 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Decode one BASE64 atom into 1, 2, or 3 bytes of data. 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int rem) 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws java.io.IOException 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int i; 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte a = -1, b = -1, c = -1, d = -1; 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rem < 2) { 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom."); 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i = inStream.read(); 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i == -1) { 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CEStreamExhausted(); 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while (i == '\n' || i == '\r'); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski decode_buffer[0] = (byte) i; 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski i = readFully(inStream, decode_buffer, 1, rem-1); 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (i == -1) { 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new CEStreamExhausted(); 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rem > 3 && decode_buffer[3] == '=') { 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rem = 3; 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (rem > 2 && decode_buffer[2] == '=') { 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rem = 2; 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (rem) { 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 4: 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski d = pem_convert_array[decode_buffer[3] & 0xff]; 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // NOBREAK 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 3: 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski c = pem_convert_array[decode_buffer[2] & 0xff]; 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // NOBREAK 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 2: 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski b = pem_convert_array[decode_buffer[1] & 0xff]; 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski a = pem_convert_array[decode_buffer[0] & 0xff]; 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (rem) { 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 2: 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outStream.write( (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3)) ); 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 3: 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) ); 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) ); 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 4: 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) ); 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) ); 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski outStream.write( (byte) (((c << 6) & 0xc0) | (d & 0x3f)) ); 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 163