/* ==================================================================
* RFC1924InputStream.java - May 15, 2013 7:29:54 AM
*
* Copyright 2007-2013 SolarNetwork.net Dev Team
*
* Adapted from libxjava original source.
*
* Copyright (c) 2010 Marcel Patzlaff (marcel.patzlaff@gmail.com)
*
* This library is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
* ==================================================================
*/
package net.solarnetwork.io;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Decode RFC 1924 encoded stream back to its original form.
*
* @author matt
* @version 1.0
*/
public class RFC1924InputStream extends FilterInputStream {
private static final byte[] DECODABET;
static {
DECODABET = new byte[256];
for ( int i = 0; i < DECODABET.length; ++i ) {
DECODABET[i] = -1;
}
for ( int i = 0; i < RFC1924OutputStream.ENCODABET.length; ++i ) {
DECODABET[(RFC1924OutputStream.ENCODABET[i] & 0xFF)] = (byte) i;
}
}
private int factor = 5;
private long sum = 0;
private int e = 24;
private boolean eof = false;
/**
* Construct with InputStream to filter.
*
* @param in
* the input stream
*/
public RFC1924InputStream(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
int b;
while ( eof == false && factor > 0 ) {
b = super.read();
if ( b == -1 ) {
eof = true;
break;
}
sum += DECODABET[b] * RFC1924OutputStream.FACTORS[--factor];
}
if ( factor == 0 && eof == false ) {
int result = (int) ((sum >>> e) & 0xFF);
e -= 8;
if ( e < 0 ) {
e = 24;
factor = 5;
sum = 0;
}
return result;
} else if ( factor < 5 && e >= 0 ) {
if ( e == 24 ) {
sum /= RFC1924OutputStream.FACTORS[factor];
e = (3 - factor) * 8;
}
int result = (int) ((sum >>> e) & 0xFF);
e -= 8;
return result;
}
return -1;
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if ( eof == true ) {
return -1;
}
int i, d, stop;
for ( i = off, stop = off + len; i < b.length && i < stop; i++ ) {
d = read();
if ( d == -1 ) {
break;
}
b[i] = (byte) d;
}
return (i - off);
}
}