001 /*
002 * This file is part of muCommander, http://www.mucommander.com
003 * Copyright (C) 2002-2008 Maxence Bernard
004 *
005 * muCommander is free software; you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation; either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * muCommander is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 */
018
019 package com.mucommander.io.base64;
020
021 import java.io.*;
022
023 /**
024 * <code>Base64Decoder</code> provides methods to ease the decoding of strings and byte arrays in base64.
025 * The {@link Base64InputStream} class is used under the hood to perform the actual base64 decoding.
026 *
027 * @see Base64InputStream
028 * @author Maxence Bernard
029 */
030 public abstract class Base64Decoder {
031
032 /**
033 * Decodes the given Base64-encoded string and returns the result as a byte array.
034 * Throws an <code>IOException</code> if the String isn't properly Base64-encoded.
035 *
036 * @param s a Base64-encoded String
037 * @return the decoded string as a byte array
038 * @throws java.io.IOException if the given String isn't properly Base64-encoded
039 */
040 public static byte[] decodeAsBytes(String s) throws IOException {
041 byte[] b = s.getBytes();
042
043 if(b.length%4 != 0) {
044 // Base64 encoded data must come in a multiple of 4 bytes, throw an IOException if it's not the case
045 throw new IOException("Byte array length is not a multiple of 4");
046 }
047
048 Base64InputStream bin = new Base64InputStream(new ByteArrayInputStream(b));
049 ByteArrayOutputStream bout = new ByteArrayOutputStream();
050 int i;
051
052 try {
053 while((i=bin.read())!=-1)
054 bout.write(i);
055
056 return bout.toByteArray();
057 }
058 finally {
059 bin.close();
060 }
061 }
062
063 /**
064 * Decodes the given Base64-encoded string and returns the result as a String. The specified encoding is used for
065 * transforming the decoded bytes into a String. Throws an <code>IOException</code> if the String isn't properly
066 * Base64-encoded, or if the encoding is not supported by the Java runtime.
067 *
068 * @param s a Base64-encoded String
069 * @param encoding the character encoding to use for transforming the decoded bytes into a String
070 * @return the decoded String
071 * @throws UnsupportedEncodingException if the specified encoding is not supported by the Java runtime
072 * @throws java.io.IOException if the given String isn't properly Base64-encoded
073 */
074 public static String decode(String s, String encoding) throws UnsupportedEncodingException, IOException {
075 InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(decodeAsBytes(s)), encoding);
076 StringBuffer sb = new StringBuffer();
077 int i;
078
079 try {
080 while((i=isr.read())!=-1)
081 sb.append((char)i);
082
083 return sb.toString();
084 }
085 finally {
086 isr.close();
087 }
088 }
089
090 /**
091 * Shorthand for {@link #decode(String, String)} invoked with UTF-8 encoding.
092 *
093 * @param s a Base64-encoded String
094 * @return the decoded String
095 * @throws java.io.IOException if the given String isn't properly Base64-encoded
096 */
097 public static String decode(String s) throws IOException {
098 return decode(s, "UTF-8");
099 }
100 }