/**************************************************************************
* Copyright (c) 2001, 2002, 2003 by Acunia N.V. All rights reserved. *
* *
* This software is copyrighted by and is the sole property of Acunia N.V. *
* and its licensors, if any. All rights, title, ownership, or other *
* interests in the software remain the property of Acunia N.V. and its *
* licensors, if any. *
* *
* This software may only be used in accordance with the corresponding *
* license agreement. Any unauthorized use, duplication, transmission, *
* distribution or disclosure of this software is expressly forbidden. *
* *
* This Copyright notice may not be removed or modified without prior *
* written consent of Acunia N.V. *
* *
* Acunia N.V. reserves the right to modify this software without notice. *
* *
* Acunia N.V. *
* Philips site 5, box 3 info@acunia.com *
* 3001 Leuven http://www.acunia.com *
* Belgium - EUROPE *
**************************************************************************/
package javax.crypto;
import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.IOException;
public class CipherInputStream extends FilterInputStream {
private Cipher cipher;
private byte[] buffer = new byte[512];
private int index = buffer.length;
public CipherInputStream(InputStream in, Cipher c){
super(in);
cipher = c;
}
protected CipherInputStream(InputStream in) {
super(in);
cipher = new NullCipher();
}
public int available() throws IOException {
return cipher.getOutputSize(in.available());
}
public void close() throws IOException {
if(cipher != null){
in.close();
cipher = null;
}
}
public boolean markSupported() {
return false;
}
public int read() throws IOException {
if(cipher == null){
throw new IOException("STREAM IS CLOSED");
}
if(index >= buffer.length && !fillBuffer()){
return -1;
}
return buffer[index++];
}
public int read(byte[] bytes) throws IOException {
return read(bytes , 0, bytes.length);
}
public int read(byte[] bytes, int offset, int length) throws IOException {
if(cipher == null){
throw new IOException("STREAM IS CLOSED");
}
if(bytes.length - length < offset || length < 0 || offset < 0){
throw new IndexOutOfBoundsException();
}
int rd = 0;
if(buffer.length <= index){
int cp = buffer.length - index;
cp = (cp > length ? length : cp);
System.arraycopy(buffer, index, bytes, offset, cp);
length -= cp;
rd += cp;
index += cp;
}
while(length > 0){
if(!fillBuffer()){
if(rd == 0){
return -1;
}
break;
}
int cp = buffer.length;
cp = (cp > length ? length : cp);
System.arraycopy(buffer, index, bytes, offset, cp);
length -= cp;
rd += cp;
index += cp;
}
return rd;
}
public long skip(long n) throws IOException {
if(cipher == null){
throw new IOException("STREAM IS CLOSED");
}
if(n <= 0){
return 0;
}
long toSkip = n;
if(buffer.length <= index){
int cp = buffer.length - index;
cp = (cp > toSkip ? (int)toSkip : cp);
index += cp;
toSkip -= cp;
}
while(n > 0){
if(!fillBuffer()){
break;
}
int cp = buffer.length;
cp = (cp > toSkip ? (int)toSkip : cp);
toSkip -= cp;
index += cp;
}
return n - toSkip;
}
private boolean fillBuffer() throws IOException {
if(buffer.length < 256){
buffer = new byte[512];
}
int rd = in.read(buffer, 0 , buffer.length);
if(rd == -1){
return false;
}
try {
buffer = cipher.update(buffer,0, rd);
index = 0;
}
catch(Exception e){
throw new IOException("WRAPPING EXCEPTION "+e);
}
return true;
}
}