
org.monte.media.io.SeekableByteArrayOutputStream Maven / Gradle / Ivy
/*
* @(#)SeekableByteArrayOutputStream.java
*
* Copyright © 2010-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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import static java.lang.Math.*;
/**
* {@code SeekableByteArrayOutputStream}.
*
* @author Werner Randelshofer
* @version $Id: SeekableByteArrayOutputStream.java 299 2013-01-03 07:40:18Z werner $
*/
public class SeekableByteArrayOutputStream extends ByteArrayOutputStream {
/**
* The current stream position.
*/
private int pos;
/**
* Creates a new byte array output stream. The buffer capacity is
* initially 32 bytes, though its size increases if necessary.
*/
public SeekableByteArrayOutputStream() {
this(32);
}
/**
* Creates a new byte array output stream, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @exception IllegalArgumentException if size is negative.
*/
public SeekableByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
/**
* Creates a new byte array output stream, which reuses the supplied buffer.
*/
public SeekableByteArrayOutputStream(byte[] buf) {
this.buf = buf;
}
/**
* Writes the specified byte to this byte array output stream.
*
* @param b the byte to be written.
*/
@Override
public synchronized void write(int b) {
int newcount = max(pos + 1, count);
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
buf[pos++] = (byte)b;
count = newcount;
}
/**
* Writes len
bytes from the specified byte array
* starting at offset off
to this byte array output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
*/
@Override
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
int newcount = max(pos+len,count);
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
System.arraycopy(b, off, buf, pos, len);
pos+=len;
count = newcount;
}
/**
* Resets the count
field of this byte array output
* stream to zero, so that all currently accumulated output in the
* output stream is discarded. The output stream can be used again,
* reusing the already allocated buffer space.
*
* @see java.io.ByteArrayInputStream#count
*/
@Override
public synchronized void reset() {
count = 0;
pos=0;
}
/**
* Sets the current stream position to the desired location. The
* next read will occur at this location. The bit offset is set
* to 0.
*
* An IndexOutOfBoundsException
will be thrown if
* pos
is smaller than the flushed position (as
* returned by getflushedPosition
).
*
*
It is legal to seek past the end of the file; an
* EOFException
will be thrown only if a read is
* performed.
*
* @param pos a long
containing the desired file
* pointer position.
*
* @exception IndexOutOfBoundsException if pos
is smaller
* than the flushed position.
* @exception java.io.IOException if any other I/O error occurs.
*/
public void seek(long pos) throws IOException {
this.pos = (int)pos;
}
/**
* Returns the current byte position of the stream. The next write
* will take place starting at this offset.
*
* @return a long containing the position of the stream.
*
* @exception java.io.IOException if an I/O error occurs.
*/
public long getStreamPosition() throws IOException {
return pos;
}
/** Writes the contents of the byte array into the specified output
* stream.
* @param out
*/
public void toOutputStream(OutputStream out) throws IOException {
out.write(buf, 0, count);
}
/** Returns the underlying byte buffer. */
public byte[] getBuffer() {
return buf;
}
}