/*
* `gnu.iou'
* Copyright (C) 2006 John Pritchard.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package gnu.iou.fil ;
/**
* {@link gnu.iou.b64 Base64 } encoder and decoder establishes the
* pattern of <code>coder.enc</code> and <code>coder.dec</code>.
*
* @author jdp
*/
public class base64
implements coder.format
{
public final static java.lang.String NAME = "base64";
/**
* <p> Decode stream from {@link gnu.iou.b64 Base64 }. </p>
*
* @author Robert Harder
* @author John Pritchard
*/
public static class dec
extends fii
implements producer
{
private final static int bufferLength = 3;
private int position = -1;
private byte[] buffer = new byte[bufferLength];
private int numSigBytes;
public dec( java.io.InputStream in){
super(in);
}
public dec( gnu.iou.bbuf buf){
super(buf);
}
/**
* <p> Reads enough of the input stream to convert
* from Base64 and returns the next byte.</p>
*/
public int read() throws java.io.IOException {
if ( 0 > this.position){
byte[] b4 = new byte[4];
int cc = 0;
for ( cc = 0; cc < 4; cc++ ){
// Read four "meaningful" bytes
int b = 0;
do {
b = this.in.read();
}
while( b >= 0 && gnu.iou.b64.DECODABET[ b & 0x7f ] <= gnu.iou.b64.WHITE_SPACE_ENC );
if ( b < 0 )
break;
else
b4[cc] = (byte)b;
}
if ( cc == 4 ){
this.numSigBytes = gnu.iou.b64.decode4to3( b4, 0, this.buffer, 0);
this.position = 0;
}
else if (0 == cc)
return -1;
else
throw new java.io.IOException( "Improperly padded Base64 input." );
}
//
if ( -1 < this.position){
if ( this.numSigBytes <= this.position)
return -1;
else {
int b = this.buffer[this.position++];
if ( this.position >= this.bufferLength )
this.position = -1;
return (b & 0xff);
}
}
else
throw new java.io.IOException( "Error in Base64 code reading stream." );
}
/**
* <p> Calls {@link #read()} repeatedly until the end of
* stream is reached or <var>len</var> bytes are read.</p>
*
* @param dest array to hold values
* @param off offset for array
* @param len max number of bytes to read into array
* @return bytes read into array or -1 if end of stream is encountered.
*/
public int read( byte[] dest, int off, int len ) throws java.io.IOException {
int cc;
int ch;
for( cc = 0; cc < len; cc++ ){
ch = read();
if(-1 < ch)
dest[off+cc] = (byte)ch;
else if (0 == cc)
return -1;
else
break;
}
return cc;
}
}
/**
* <p> Encode stream to {@link gnu.iou.b64 Base64 }. </p>
*
* @author Robert Harder
* @author John Pritchard
*/
public static class enc
extends foo
implements consumer
{
private final static int bufferLength = 3;
private int position = 0;
private byte[] buffer = new byte[ bufferLength ];
private int linelen = 0;
private byte[] b4 = new byte[4];
public enc( java.io.OutputStream out){
super(out);
}
public enc( gnu.iou.bbuf buf){
super(buf);
}
/**
* <p> Three bytes are buffered for encoding, before the
* target stream actually gets a <code>write()</code>
* call.</p>
*/
public void write(int bb) throws java.io.IOException {
this.buffer[this.position++] = (byte)bb;
if ( bufferLength <= this.position){
this.out.write( gnu.iou.b64.encode3to4( this.b4, this.buffer, bufferLength));
this.linelen += 4;
if( linelen >= gnu.iou.b64.MAX_LINE_LENGTH ){
this.out.write( gnu.iou.b64.NEW_LINE );
this.linelen = 0;
}
this.position = 0;
}
}
/**
* <p> Calls {@link #write(int)} repeatedly until
* <var>len</var> bytes are written.</p>
*/
public void write( byte[] bbs, int off, int len ) throws java.io.IOException {
for( int cc = 0; cc < len; cc++)
this.write( bbs[off+cc]);
}
/**
* <p> Pads the buffer without closing the stream.</p>
*/
public void flush() throws java.io.IOException {
if (0 < this.position){
this.out.write( gnu.iou.b64.encode3to4( this.b4, this.buffer, this.position));
this.position = 0;
}
super.flush();
}
}
public base64(){
super();
}
public java.lang.String getName(){
return NAME;
}
public fii decoder( java.io.InputStream in){
return new dec(in);
}
public fii decoder( gnu.iou.bbuf buf){
return new dec(buf);
}
public foo encoder( java.io.OutputStream out){
return new enc(out);
}
public foo encoder( gnu.iou.bbuf buf){
return new enc(buf);
}
}