/*** * 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.InputStream; /** * This class is a clean room implementation * of the ByteArrayInputStream, 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 (wimpi) * @version @version@ (@date@) */ public class FastByteArrayInputStream extends InputStream { protected int count; protected int pos; protected int mark; protected byte[] buf; protected int readlimit = -1; /** * Creates a new <tt>FastByteArrayInputStream</tt> instance * that allows to read from the given byte array. * * @param buffer the data to be read. */ public FastByteArrayInputStream(byte[] buffer) { buf = buffer; count = buf.length; pos = 0; mark = 0; }// constructor /** * Creates a new <tt>FastByteArrayInputStream</tt> instance * that allows to read from the given byte array. * * @param buffer the data to read. * @param offset the byte offset at which to begin reading. * @param length the number of bytes to read. */ public FastByteArrayInputStream(byte[] buffer, int offset, int length) { buf = buffer; pos = offset; count = length; }// constructor /** * Reads the next byte of data from this input stream. The value byte * is returned as an int in the range 0 to 255. If no byte is available * because the end of the stream has been reached, the value -1 is returned. * <p/> * This read method cannot block. * </p> * * @return the next byte of data, or -1 if the end of the stream has been reached. * @throws IOException */ @Override public int read() throws IOException { if ((pos < count)) { return (buf[pos++] & 0xff); } else { return (-1); } }// read /** * Reads up to len bytes of data into an array of bytes from this input stream. * If pos equals count, then -1 is returned to indicate end of file. * Otherwise, the number k of bytes read is equal to the smaller of * len and count-pos. If k is positive, then bytes buf[pos] through buf[pos+k-1] * are copied into b[off] through b[off+k-1] in the manner performed by * System.arraycopy. The value k is added into pos and k is returned. * * @param toBuf the buffer into which the data is read. * @param offset the start offset of the data. * @param length the max number of bytes read. * @return the total number of bytes read into the buffer, or -1 if there is no * more data because the end of the stream has been reached. * @throws IOException */ @Override public int read(byte[] toBuf, int offset, int length) throws IOException { int avail = count - pos; if (avail <= 0) { return -1; } if (length > avail) { length = avail; } System.arraycopy(buf, pos, toBuf, offset, length); pos += length; return length; }// read @Override public int read(byte[] toBuf) throws IOException { return read(toBuf, 0, toBuf.length); }// read /** * Skips over and discards n bytes of data from this input stream. * The skip method may skip over some smaller number of bytes. * The actual number of bytes skipped is returned, or a number <=0 * if none was skipped. * <p/> * The maximum number of bytes that can be skipped is defined by * <tt>Integer.MAX_VALUE</tt>. * </p> * * @param n the number of bytes to be skipped. * @return the actual number of bytes skipped. */ @Override public long skip(long n) { int skip = this.count - this.pos - (int) n; if (skip > 0) { pos += skip; } return skip; }// skip /** * The close method for this <tt>FastByteArrayInputStream</tt> * does nothing. */ @Override public void close() { return; }// close /** * Returns the number of bytes that can be read (or skipped over) from this * <tt>FastByteArrayInputStream</tt>. * * @return the number of bytes that can be skipped. */ @Override public int available() { return count - pos; }// available /** * Marks the current position in this <tt>FastByteArrayInputStream</tt>. * A subsequent call to{@link #reset()} will re-postition this <tt>FastByteArrayInputStream</tt> * at the last marked position so that subsequent reads re-read the same bytes. * * @param limit a read limit that invalidates the mark if passed. */ @Override public void mark(int limit) { mark = pos; readlimit = limit; }// mark /** * Tests if this <tt>FastByteArrayInputStream</tt> * supports the mark and reset methods. * * @return true if supported, false otherwise. */ @Override public boolean markSupported() { return true; }// markSupported /** * Re-positions this stream to the position at * the time the mark method was last called this <tt>FastByteArrayInputStream</tt>. * * @throws IOException if the readlimit was exceeded. */ @Override public void reset() throws IOException { if (readlimit < 0 || pos > mark + readlimit) { pos = mark; readlimit = -1; } else { mark = pos; readlimit = -1; throw new IOException("Readlimit exceeded."); } }// reset /** * Returns the underlying data being read. * * @return the underlying data. */ public byte[] getBuffer() { return buf; }// getBuffer /** * Returns the offset at which data is being read from the buffer. * * @return the offset at which data is being read. */ public int getPosition() { return pos; }// getPosition /** * Returns the size of the buffer being read. * * @return the size of the buffer. */ public int size() { return count; }// size }// class FastByteArrayInputStream