Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/misc/BASE64Decoder.java
38829 views
/*1* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.misc;2526import java.io.OutputStream;27import java.io.PushbackInputStream;28import java.io.PrintStream;2930/**31* This class implements a BASE64 Character decoder as specified in RFC1521.32*33* This RFC is part of the MIME specification which is published by the34* Internet Engineering Task Force (IETF). Unlike some other encoding35* schemes there is nothing in this encoding that tells the decoder36* where a buffer starts or stops, so to use it you will need to isolate37* your encoded data into a single chunk and then feed them this decoder.38* The simplest way to do that is to read all of the encoded data into a39* string and then use:40* <pre>41* byte mydata[];42* BASE64Decoder base64 = new BASE64Decoder();43*44* mydata = base64.decodeBuffer(bufferString);45* </pre>46* This will decode the String in <i>bufferString</i> and give you an array47* of bytes in the array <i>myData</i>.48*49* On errors, this class throws a CEFormatException with the following detail50* strings:51* <pre>52* "BASE64Decoder: Not enough bytes for an atom."53* </pre>54*55* @author Chuck McManis56* @see CharacterEncoder57* @see BASE64Decoder58*/5960public class BASE64Decoder extends CharacterDecoder {6162/** This class has 4 bytes per atom */63protected int bytesPerAtom() {64return (4);65}6667/** Any multiple of 4 will do, 72 might be common */68protected int bytesPerLine() {69return (72);70}7172/**73* This character array provides the character to value map74* based on RFC1521.75*/76private final static char pem_array[] = {77// 0 1 2 3 4 5 6 778'A','B','C','D','E','F','G','H', // 079'I','J','K','L','M','N','O','P', // 180'Q','R','S','T','U','V','W','X', // 281'Y','Z','a','b','c','d','e','f', // 382'g','h','i','j','k','l','m','n', // 483'o','p','q','r','s','t','u','v', // 584'w','x','y','z','0','1','2','3', // 685'4','5','6','7','8','9','+','/' // 786};8788private final static byte pem_convert_array[] = new byte[256];8990static {91for (int i = 0; i < 255; i++) {92pem_convert_array[i] = -1;93}94for (int i = 0; i < pem_array.length; i++) {95pem_convert_array[pem_array[i]] = (byte) i;96}97}9899byte decode_buffer[] = new byte[4];100101/**102* Decode one BASE64 atom into 1, 2, or 3 bytes of data.103*/104@SuppressWarnings("fallthrough")105protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int rem)106throws java.io.IOException107{108int i;109byte a = -1, b = -1, c = -1, d = -1;110111if (rem < 2) {112throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom.");113}114do {115i = inStream.read();116if (i == -1) {117throw new CEStreamExhausted();118}119} while (i == '\n' || i == '\r');120decode_buffer[0] = (byte) i;121122i = readFully(inStream, decode_buffer, 1, rem-1);123if (i == -1) {124throw new CEStreamExhausted();125}126127if (rem > 3 && decode_buffer[3] == '=') {128rem = 3;129}130if (rem > 2 && decode_buffer[2] == '=') {131rem = 2;132}133switch (rem) {134case 4:135d = pem_convert_array[decode_buffer[3] & 0xff];136// NOBREAK137case 3:138c = pem_convert_array[decode_buffer[2] & 0xff];139// NOBREAK140case 2:141b = pem_convert_array[decode_buffer[1] & 0xff];142a = pem_convert_array[decode_buffer[0] & 0xff];143break;144}145146switch (rem) {147case 2:148outStream.write( (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3)) );149break;150case 3:151outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );152outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );153break;154case 4:155outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) );156outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) );157outStream.write( (byte) (((c << 6) & 0xc0) | (d & 0x3f)) );158break;159}160return;161}162}163164165