/*** * Copyright 2002-2010 jamod development team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***/ package net.wimpi.modbus.io; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; /** * This class is a clean room implementation * of the ByteArrayOutputStream, with enhancements for * speed (no synchronization for example). * <p/> * The idea for such an implementation was originally * obtained from Berkeley DB JE, however, this represents a * clean-room implementation that is <em>NOT</em> derived * from their implementation for license reasons and differs * in implementation considerably. For compatibility reasons * we have tried to conserve the interface as much as possible. * * @author Dieter Wimberger * @version @version@ (@date@) */ public class FastByteArrayOutputStream extends OutputStream { protected int count; protected byte[] buf; /** * Create a new <tt>FastByteArrayOutputStream</tt>. * The default value {@link #DEFAULT_SIZE} will be used. */ public FastByteArrayOutputStream() { buf = new byte[DEFAULT_SIZE]; }// constructor /** * Create a new <tt>FastByteArrayOutputStream</tt> with a given * initial buffer size. * * @param bufferSize the initial size of the buffer as <tt>int</tt>. */ public FastByteArrayOutputStream(int bufferSize) { buf = new byte[bufferSize]; }// constructor /** * Create a new <tt>FastByteArrayOutputStream</tt> with a given * initial buffer. * * @param buf the buffer as <tt>byte[]</tt>. */ public FastByteArrayOutputStream(byte[] buf) { this.buf = buf; }// constructor /** * Closing a <tt>FastByteArrayOutputStream</tt> has no effect. * The methods in this class can be called after the stream has * been closed without generating an IOException. */ @Override public void close() { }// close /** * Resets the count of this <tt>FastByteArrayOutputStream</tt> * to zero, so that all currently accumulated output in the * ouput stream is discarded when overwritten. */ public void reset() { count = 0; }// reset /** * Returns the current number of bytes in the buffer of this * <tt>FastByteArrayOutputStream</tt>. * * @return the amount of bytes in the buffer. */ public int size() { return count; }// size /** * Returns a newly allocated <tt>byte[]</tt> with the actual content * of the buffer of this <tt>FastByteArrayOutputStream</tt>. * * @return the current contents of this output stream, as a <tt>byte[]</tt>. * @see #size() */ public byte[] toByteArray() { byte[] buf = new byte[count]; System.arraycopy(this.buf, 0, buf, 0, count); return buf; }// toByteArray /** * Converts the buffer's contents into a string, translating bytes into * characters according to the platform's default character encoding. * * @return String translated from the buffer's contents. */ @Override public String toString() { return new String(buf, 0, count); }// toString /** * Converts the buffer's contents into a string, translating bytes into * characters according to the specified character encoding. * * @param enc a character-encoding name. * @return String translated from the buffer's contents. * @throws UnsupportedEncodingException If the named encoding is not supported. */ public String toString(String enc) throws UnsupportedEncodingException { return new String(buf, 0, count, enc); }// toString /** * Writes len bytes from the specified byte array starting at offset off * to this <tt>FastByteArrayOutputStream</tt>. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. */ @Override public void write(byte[] b, int off, int len) { ensureCapacity(count + len); System.arraycopy(b, off, buf, count, len); count += len; }// write /** * Writes the specified byte to this byte array output stream. * * @param b the byte to be written. */ @Override public void write(int b) { ensureCapacity(count + 1); buf[count++] = (byte) b; }// write /** * Writes the complete contents of this <tt>FastByteArrayOutputStream</tt> to * the specified output stream argument. * * @param out the output stream to which to write the data. * @throws IOException if an I/O error occurs. */ public void writeTo(OutputStream out) throws IOException { out.write(buf, 0, count); }// writeTo /** * Convenience method that writes all bytes from the specified byte * array to this <tt>FastByteArrayOutputStream</tt>. * * @param buf * @throws IOException */ @Override public void write(byte[] buf) throws IOException { write(buf, 0, buf.length); }// write /** * Increases the capacity of this <tt>FastByteArrayOutputStream</tt>s buffer, * if necessary, to ensure that it can hold at least the number of * bytes specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity. */ public final void ensureCapacity(int minCapacity) { if (minCapacity < buf.length) { return; } else { byte[] newbuf = new byte[minCapacity]; System.arraycopy(buf, 0, newbuf, 0, count); buf = newbuf; } }// ensureCapacity /** * Copies the content of this <tt>FastByteArrayOutputStream</tt> * into the given byte array, starting from the given offset. * * @param b the buffer to hold a copy of the data. * @param offset the offset at which to start copying. */ public void toByteArray(byte[] b, int offset) { if (offset >= b.length) { throw new IndexOutOfBoundsException(); } int len = count - offset; if (len > b.length) { System.arraycopy(buf, offset, b, offset, b.length); // just copy what is there } else { System.arraycopy(buf, offset, b, offset, len); } }// toByteArray /** * Returns a reference to the buffer of this * <tt>FastByteArrayOutputStream</tt>. * * @return the buffer. */ public byte[] getBuffer() { return buf; }// getBuffer public static final int DEFAULT_SIZE = 512; }// class FastByteArrayOutputStream