annotate src/ca/randelshofer/SeekableByteArrayOutputStream.java @ 32:4d7ceab67ed0

closing clicky branch
author Robert McIntyre <rlm@mit.edu>
date Sun, 30 Oct 2011 10:41:58 -0700
parents 4c5fc53778c1
children 302d5e9ad120
rev   line source
rlm@10 1 /*
rlm@10 2 * @(#)SeekableByteArrayOutputStream.java 1.0 2010-12-27
rlm@10 3 *
rlm@10 4 * Copyright © 2010 Werner Randelshofer, Immensee, Switzerland.
rlm@10 5 * All rights reserved.
rlm@10 6 *
rlm@10 7 * You may not use, copy or modify this file, except in compliance with the
rlm@10 8 * license agreement you entered into with Werner Randelshofer.
rlm@10 9 * For details see accompanying license terms.
rlm@10 10 */
rlm@10 11
rlm@10 12 package ca.randelshofer;
rlm@10 13
rlm@10 14 import java.io.ByteArrayOutputStream;
rlm@10 15 import java.io.IOException;
rlm@10 16 import java.io.OutputStream;
rlm@10 17 import java.util.Arrays;
rlm@10 18 import static java.lang.Math.*;
rlm@10 19 /**
rlm@10 20 * {@code SeekableByteArrayOutputStream}.
rlm@10 21 *
rlm@10 22 * @author Werner Randelshofer
rlm@10 23 * @version 1.0 2010-12-27 Created.
rlm@10 24 */
rlm@10 25 public class SeekableByteArrayOutputStream extends ByteArrayOutputStream {
rlm@10 26
rlm@10 27 /**
rlm@10 28 * The current stream position.
rlm@10 29 */
rlm@10 30 private int pos;
rlm@10 31
rlm@10 32 /**
rlm@10 33 * Creates a new byte array output stream. The buffer capacity is
rlm@10 34 * initially 32 bytes, though its size increases if necessary.
rlm@10 35 */
rlm@10 36 public SeekableByteArrayOutputStream() {
rlm@10 37 this(32);
rlm@10 38 }
rlm@10 39
rlm@10 40 /**
rlm@10 41 * Creates a new byte array output stream, with a buffer capacity of
rlm@10 42 * the specified size, in bytes.
rlm@10 43 *
rlm@10 44 * @param size the initial size.
rlm@10 45 * @exception IllegalArgumentException if size is negative.
rlm@10 46 */
rlm@10 47 public SeekableByteArrayOutputStream(int size) {
rlm@10 48 if (size < 0) {
rlm@10 49 throw new IllegalArgumentException("Negative initial size: "
rlm@10 50 + size);
rlm@10 51 }
rlm@10 52 buf = new byte[size];
rlm@10 53 }
rlm@10 54
rlm@10 55 /**
rlm@10 56 * Writes the specified byte to this byte array output stream.
rlm@10 57 *
rlm@10 58 * @param b the byte to be written.
rlm@10 59 */
rlm@10 60 @Override
rlm@10 61 public synchronized void write(int b) {
rlm@10 62 int newcount = max(pos + 1, count);
rlm@10 63 if (newcount > buf.length) {
rlm@10 64 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
rlm@10 65 }
rlm@10 66 buf[pos++] = (byte)b;
rlm@10 67 count = newcount;
rlm@10 68 }
rlm@10 69
rlm@10 70 /**
rlm@10 71 * Writes <code>len</code> bytes from the specified byte array
rlm@10 72 * starting at offset <code>off</code> to this byte array output stream.
rlm@10 73 *
rlm@10 74 * @param b the data.
rlm@10 75 * @param off the start offset in the data.
rlm@10 76 * @param len the number of bytes to write.
rlm@10 77 */
rlm@10 78 @Override
rlm@10 79 public synchronized void write(byte b[], int off, int len) {
rlm@10 80 if ((off < 0) || (off > b.length) || (len < 0) ||
rlm@10 81 ((off + len) > b.length) || ((off + len) < 0)) {
rlm@10 82 throw new IndexOutOfBoundsException();
rlm@10 83 } else if (len == 0) {
rlm@10 84 return;
rlm@10 85 }
rlm@10 86 int newcount = max(pos+len,count);
rlm@10 87 if (newcount > buf.length) {
rlm@10 88 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
rlm@10 89 }
rlm@10 90 System.arraycopy(b, off, buf, pos, len);
rlm@10 91 pos+=len;
rlm@10 92 count = newcount;
rlm@10 93 }
rlm@10 94
rlm@10 95 /**
rlm@10 96 * Resets the <code>count</code> field of this byte array output
rlm@10 97 * stream to zero, so that all currently accumulated output in the
rlm@10 98 * output stream is discarded. The output stream can be used again,
rlm@10 99 * reusing the already allocated buffer space.
rlm@10 100 *
rlm@10 101 * @see java.io.ByteArrayInputStream#count
rlm@10 102 */
rlm@10 103 @Override
rlm@10 104 public synchronized void reset() {
rlm@10 105 count = 0;
rlm@10 106 pos=0;
rlm@10 107 }
rlm@10 108
rlm@10 109 /**
rlm@10 110 * Sets the current stream position to the desired location. The
rlm@10 111 * next read will occur at this location. The bit offset is set
rlm@10 112 * to 0.
rlm@10 113 *
rlm@10 114 * <p> An <code>IndexOutOfBoundsException</code> will be thrown if
rlm@10 115 * <code>pos</code> is smaller than the flushed position (as
rlm@10 116 * returned by <code>getflushedPosition</code>).
rlm@10 117 *
rlm@10 118 * <p> It is legal to seek past the end of the file; an
rlm@10 119 * <code>EOFException</code> will be thrown only if a read is
rlm@10 120 * performed.
rlm@10 121 *
rlm@10 122 * @param pos a <code>long</code> containing the desired file
rlm@10 123 * pointer position.
rlm@10 124 *
rlm@10 125 * @exception IndexOutOfBoundsException if <code>pos</code> is smaller
rlm@10 126 * than the flushed position.
rlm@10 127 * @exception IOException if any other I/O error occurs.
rlm@10 128 */
rlm@10 129 public void seek(long pos) throws IOException {
rlm@10 130 this.pos = (int)pos;
rlm@10 131 }
rlm@10 132
rlm@10 133 /**
rlm@10 134 * Returns the current byte position of the stream. The next write
rlm@10 135 * will take place starting at this offset.
rlm@10 136 *
rlm@10 137 * @return a long containing the position of the stream.
rlm@10 138 *
rlm@10 139 * @exception IOException if an I/O error occurs.
rlm@10 140 */
rlm@10 141 public long getStreamPosition() throws IOException {
rlm@10 142 return pos;
rlm@10 143 }
rlm@10 144
rlm@10 145 /** Writes the contents of the byte array into the specified output
rlm@10 146 * stream.
rlm@10 147 * @param out
rlm@10 148 */
rlm@10 149 public void toOutputStream(OutputStream out) throws IOException {
rlm@10 150 out.write(buf, 0, count);
rlm@10 151 }
rlm@10 152
rlm@10 153 }