/*
* @(#)AppendableByteArrayInputStream.java 1.0 2011-08-28
*
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
package org.monte.media.io;
import java.io.ByteArrayInputStream;
import java.util.zip.Adler32;
/**
* A {@code ByteArrayInputStream} which allows to replace the byte buffer underneath.
*
* @author Werner Randelshofer
* @version 1.0 2011-08-28 Created.
*/
public class AppendableByteArrayInputStream extends ByteArrayInputStream {
public AppendableByteArrayInputStream(byte[] buf, int offset, int length) {
super(buf, offset, length);
// System.out.println("AppendableByteArrayInputStream pos="+pos+" count="+count);
}
public AppendableByteArrayInputStream(byte[] buf) {
super(buf);
// System.out.println("AppendableByteArrayInputStream pos="+pos+" count="+count);
}
@Override
public synchronized int read() {
int b = super.read();
/*
if (b!=-1) {
String hex="0"+Integer.toHexString(b);
System.out.println(hex.substring(hex.length()-2));
}*/
return b;
}
@Override
public synchronized int read(byte[] b, int off, int len) {
// System.out.println("AppendableByteArrayInputStream.read... pos="+pos+" count="+count);
int count = super.read(b, off, len);
/*
if (count>0) {
for (int i=0;i<count;i++) {
if (i%16==15) System.out.println();
String hex="0"+Integer.toHexString(b[i]);
System.out.print(hex.substring(hex.length()-2));
}
System.out.println(" pos="+pos+" count="+this.count);
}*/
return count;
}
/** Appends new data to the buffer.
*
* @param buf Data.
* @param offset Offset in the data.
* @param length Length of the data.
* @param discard True if data which has already been read can be discarded.
*/
public void appendBuffer(byte[] buf, int offset, int length, boolean discard) {
if (discard) {
if (this.buf.length >= count - pos + length) {
// => the buffer has enough space for the existing data and the new data
System.arraycopy(this.buf, pos, this.buf, 0, count - pos);
System.arraycopy(buf, offset, this.buf, count - pos, length);
this.count = count - pos + length;
this.pos = 0;
this.mark = 0;
} else {
// => the buffer does not have enough space for the new data
byte[] newBuf = new byte[(count - pos + length + 31) / 32 * 32];
System.arraycopy(this.buf, pos, newBuf, 0, count - pos);
System.arraycopy(buf, offset, newBuf, count - pos, length);
this.buf = newBuf;
this.count = count - pos + length;
this.pos = 0;
this.mark = 0;
}
} else {
if (this.buf.length >= count + length) {
// => the buffer has enough space for the existing data and the new data
System.arraycopy(buf, offset, this.buf, count, length);
this.count = count + length;
} else {
// => the buffer does not have enough space for the new data
byte[] newBuf = new byte[(this.buf.length + length + 31) / 32 * 32];
System.arraycopy(this.buf, 0, newBuf, 0, count);
System.arraycopy(buf, offset, newBuf, count, length);
this.buf = newBuf;
this.count = count + length;
}
}
//System.out.println("AppendableByteArrayInputStream.appendBuffer pos="+pos+" count="+count);
}
/** Sets the buffer and resets the stream.
* This will overwrite the data array in the buffer, if it is large enough.
* Otherwise it will create a new data array and copy the data into it.
*
* @param buf Data.
* @param offset Offset in the data.
* @param length Length of the data.
*/
public void setBuffer(byte[] buf, int offset, int length) {
if (this.buf.length >= length) {
// => the buffer has enough space for the existing data and the new data
System.arraycopy(buf, offset, this.buf, 0, length);
this.count = length;
this.pos = 0;
this.mark = 0;
} else {
// => the buffer may not be overwritten or does not have enough space for the new data
this.buf = null;
this.buf = new byte[(length + 31) & ~31];
System.arraycopy(buf, offset, this.buf, 0, length);
this.count = length;
this.pos = 0;
this.mark = 0;
}
}
public static void main(String[] args) {
byte[] b = new byte[5];
int count = 0;
for (int i = 0; i < b.length; i++) {
b[i] = (byte) count++;
}
AppendableByteArrayInputStream in = new AppendableByteArrayInputStream(b);
for (int j = 0; j < 3; j++) {
System.out.println(in.read());
}
b = new byte[4];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) count++;
}
in.appendBuffer(b, 0, b.length, true);
for (int j = 0; j < 3; j++) {
System.out.println(in.read());
}
b = new byte[6];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) count++;
}
in.appendBuffer(b, 0, b.length, true);
for (int d = in.read(); d >= 0; d = in.read()) {
System.out.println(d);
}
}
}