/*
 * Copyright 2003 Federal Chancellery Austria
 * MOA-ID has been developed in a cooperation between BRZ, the Federal
 * Chancellery Austria - ICT staff unit, and Graz University of Technology.
 *
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 * the European Commission - subsequent versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 * http://www.osor.eu/eupl/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and
 * limitations under the Licence.
 *
 * This product combines work with different licenses. See the "NOTICE" text
 * file for details on the various modules and licenses.
 * The "NOTICE" text file is part of the distribution. Any derivative works
 * that you distribute must include a readable copy of the "NOTICE" text file.
 */
package at.gv.egovernment.moa.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import iaik.utils.Base64InputStream;
import iaik.utils.Base64OutputStream;
/**
 * Utitility functions for encoding/decoding Base64 strings.
 * 
 * @author Patrick Peck
 * @version $Id$
 */
public class Base64Utils {
  /**
   * Read the bytes encoded in a Base64 encoded String. 
   * 
   * @param base64String The String containing the Base64 encoded
   * bytes.
   * @param ignoreInvalidChars Whether to ignore invalid Base64 characters.
   * @return byte[] The raw bytes contained in the base64String.
   * @throws IOException Failed to read the Base64 data.
   */
  public static byte[] decode(String base64String, boolean ignoreInvalidChars)
    throws IOException {
    Base64InputStream in =
      new Base64InputStream(
        new ByteArrayInputStream(base64String.getBytes("UTF-8")),
        ignoreInvalidChars);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte[] bytes = new byte[256];
    int bytesRead;
    while ((bytesRead = in.read(bytes)) > 0) {
      out.write(bytes, 0, bytesRead);
    }
    return out.toByteArray();
  }
  /**
   * Read the bytes encoded in a Base64 encoded String and provide
   * them via an InputStream.
   * 
   * @param base64String The String containing the Base64 encoded
   * bytes.
   * @param ignoreInvalidChars Whether to ignore invalid Base64 characters.
   * @return The InputStream from which the binary content of the
   * base64String can be read.
   */
  public static InputStream decodeToStream(
    String base64String,
    boolean ignoreInvalidChars) {
    try {
      ByteArrayInputStream bin = 
        new ByteArrayInputStream(base64String.getBytes("UTF-8"));
      Base64InputStream in = new Base64InputStream(bin, ignoreInvalidChars);
      
      return in;
    } catch (UnsupportedEncodingException e) {
      // cannot occur, since UTF-8 is required to be supported by every JRE
      return null; 
    }
  }
  /**
   * Convert a byte array to a Base64 encoded String.
   * 
   * @param bytes The bytes to encode.
   * @return String The Base64 encoded representation of the bytes.
   * @throws IOException Failed to write the bytes as Base64 data.
   */
  public static String encode(byte[] bytes) throws IOException {
    return encode(new ByteArrayInputStream(bytes));
  }
  /**
   * Convert the data contained in the given stream to a Base64 encoded
   * String.
   * 
   * @param inputStream The stream containing the data to encode.
   * @return The Base64 encoded data of inputStream, as a 
   * String.
   * @throws IOException Failed to convert the data in the stream.
   */
  public static String encode(InputStream inputStream) throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    Base64OutputStream base64Stream = new Base64OutputStream(byteStream, "\n".getBytes());
    byte[] bytes = new byte[256];
    int bytesRead;
    while ((bytesRead = inputStream.read(bytes)) > 0) {
      base64Stream.write(bytes, 0, bytesRead);
    }
    base64Stream.flush();
    base64Stream.close();
    inputStream.close();
    return byteStream.toString("UTF-8");
  }
}