/*
XPAGES pour WebJaxe

Copyright (C) 2007 Observatoire de Paris-Meudon

Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier conformément aux dispositions de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; version 2 de la licence, ou encore (à votre choix) toute version ultérieure.

Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION A UN OBJET PARTICULIER. Pour plus de détail, voir la Licence Publique Générale GNU .

Vous devez avoir reçu un exemplaire de la Licence Publique Générale GNU en même temps que ce programme ; si ce n'est pas le cas, écrivez à la Free Software Foundation Inc., 675 Mass Ave, Cambridge, MA 02139, Etats-Unis.
*/

package xpages;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

/**
 * Filtre décodant du base64, étendant InputStream et prenant un Reader en paramètre
 * 
 * Merci à Carlo Pelliccia pour son "Java base64" dont je me suis inspiré.
 */
public class DecodeurBase64 extends InputStream {

	private static final String cars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	private Reader reader;
	private int[] buffer;
	private int nboctets = 0;
	private boolean fin = false;

	public DecodeurBase64(Reader reader) {
		this.reader = reader;
	}

    @Override
	public int read() throws IOException {
		if (buffer == null || nboctets == buffer.length) {
			if (fin)
				return(-1);
			lecture();
			if (buffer.length == 0) {
				buffer = null;
				return(-1);
			}
			nboctets = 0;
		}
		return buffer[nboctets++];
	}
    
	private void lecture() throws IOException {
		char[] buffcars = new char[4];
		int i = 0;
		do {
			int b = reader.read();
			if (b == -1) {
				if (i != 0)
					throw new IOException("Mauvais codage base64");
				else {
					buffer = new int[0];
					fin = true;
					return;
				}
			}
			char c = (char) b;
			if (cars.indexOf(c) != -1 || c == '=')
				buffcars[i++] = c;
		} while (i < 4);
		if (buffcars[0] == '=' || buffcars[1] == '=')
			throw new IOException("Mauvais codage base64");
		if (buffcars[2] == '=' && buffcars[3] != '=')
			throw new IOException("Mauvais codage base64");
		int l;
		if (buffcars[3] == '=') {
			if (reader.read() != -1)
				throw new IOException("Mauvais codage base64");
			fin = true;
			if (buffcars[2] == '=')
				l = 1;
			else
				l = 2;
		} else
			l = 3;
		int aux = 0;
		for (i = 0; i < 4; i++) {
			if (buffcars[i] != '=')
				aux = aux | (cars.indexOf(buffcars[i]) << (6 * (3 - i)));
		}
		buffer = new int[l];
		for (i = 0; i < l; i++)
			buffer[i] = (aux >>> (8 * (2 - i))) & 0xFF;
	}

    @Override
	public void close() throws IOException {
		reader.close();
	}
}