/*
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.OutputStream;
import java.io.Writer;

/**
 * Filtre encodant en base64, étendant OutputStream et prenant un Writer en paramètre.
 * Attention à ne pas oublier de fermer (close()) l'encodeur à la fin !
 * 
 * Merci à Carlo Pelliccia pour son "Java base64" dont je me suis inspiré.
 */
public class EncodeurBase64 extends OutputStream {

	private static final int longueurLigneMax = 76;
	private static final String cars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	private static final String finDeLigne = "\n";
	private Writer writer = null;
	private int buffer = 0;
	private int nboctets = 0;
	private int nbcarsligne = 0;
	private char[] buffcars = new char[4];
    
	public EncodeurBase64(Writer w) {
		this.writer = w;
	}
    
    @Override
	public void write(int b) throws IOException {
		buffer = buffer | ((b & 0xFF) << (16 - (nboctets * 8)));
		nboctets++;
		if (nboctets == 3)
			envoyer();
	}
    
    @Override
	public void close() throws IOException {
		if (nboctets != 0)
			envoyer();
		writer.close();
	}
    
	/**
	 * Envoit 4 caractères au writer
	 */
	private void envoyer() throws IOException {
		if (longueurLigneMax > 0 && nbcarsligne == longueurLigneMax) {
			writer.write(finDeLigne);
			nbcarsligne = 0;
		}
		buffcars[0] = cars.charAt((buffer << 8) >>> 26);
		buffcars[1] = cars.charAt((buffer << 14) >>> 26);
		buffcars[2] = (nboctets < 2) ? '=' : cars.charAt((buffer << 20) >>> 26);
		buffcars[3] = (nboctets < 3) ? '=' : cars.charAt((buffer << 26) >>> 26);
		writer.write(buffcars);
		nbcarsligne += 4;
		nboctets = 0;
		buffer = 0;
	}

}
