// Copyright (c) 2001 Dustin Sallings <dustin@spy.net> package net.spy.util; import java.io.IOException; import java.io.InputStream; /** * A filter stream for decoding Base64 data on an InputStream. */ public class Base64InputStream extends ByteConverionInputStream { private final Base64 base64; // Properly initialized, this will be zero private int currentOut=9; private byte[] outbuffer=null; /** * Get a new Base64InputStream decoding the given InputStream. */ public Base64InputStream(InputStream is) { super(is); base64=new Base64(); } /** * Get the next decoded byte in this stream. */ @Override public int read() throws IOException { int rv=-1; if(outbuffer==null || currentOut>=outbuffer.length) { decodeMore(); } if(outbuffer.length>0) { rv=outbuffer[currentOut++] & 0xff; } return(rv); } private void decodeMore() throws IOException { byte[] tmp=new byte[4]; boolean more=true; int bytesread=0; for(bytesread=0; bytesread<4 && more; bytesread++) { int input=in.read(); if(input<0) { more=false; } else { if(base64.isValidBase64Char( (char)input) ) { tmp[bytesread]=(byte)input; } else { // Skip this byte bytesread--; } // Deal with the read character } // Got input } // Getting input String todecode=null; if(bytesread<4) { byte[] tmptmp=new byte[bytesread]; System.arraycopy(tmp, 0, tmptmp, 0, bytesread); todecode=new String(tmptmp); } else { todecode=new String(tmp); } outbuffer=base64.decode(todecode); currentOut=0; } /** * Return the number of bytes that may be read without blocking. * This is kind of a guess based on the number of bytes available. It * probably works. */ @Override public int available() throws IOException { int rv=in.available(); rv=(rv*3)/4; return(rv); } }