001: package it.unimi.dsi.fastutil.io;
002:
003: /*
004: * fastutil: Fast & compact type-specific collections for Java
005: *
006: * Copyright (C) 2003-2008 Sebastiano Vigna
007: *
008: * This library is free software; you can redistribute it and/or modify it
009: * under the terms of the GNU Lesser General Public License as published by the Free
010: * Software Foundation; either version 2.1 of the License, or (at your option)
011: * any later version.
012: *
013: * This library is distributed in the hope that it will be useful, but
014: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
015: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
016: * for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: *
022: */
023:
024: /** Simple, fast and repositionable byte-array input stream.
025: *
026: * <p><strong>Warning</strong>: this class implements the correct semantics
027: * of {@link #read(byte[], int, int)} as described in {@link java.io.InputStream}.
028: * The implementation given in {@link java.io.ByteArrayInputStream} is broken,
029: * but it will never be fixed because it's too late.
030: *
031: * @author Sebastiano Vigna
032: */
033:
034: public class FastByteArrayInputStream extends MeasurableInputStream
035: implements RepositionableStream {
036:
037: /** The array backing the input stream. */
038: public byte[] array;
039:
040: /** The first valid entry. */
041: public int offset;
042:
043: /** The number of valid bytes in {@link #array} starting from {@link #offset}. */
044: public int length;
045:
046: /** The current position as a distance from {@link #offset}. */
047: private int position;
048:
049: /** The current mark as a position, or -1 if no mark exists. */
050: private int mark;
051:
052: /** Creates a new array input stream using a given array fragment.
053: *
054: * @param array the backing array.
055: * @param offset the first valid entry of the array.
056: * @param length the number of valid bytes.
057: */
058: public FastByteArrayInputStream(final byte[] array,
059: final int offset, final int length) {
060: this .array = array;
061: this .offset = offset;
062: this .length = length;
063: }
064:
065: /** Creates a new array input stream using a given array.
066: *
067: * @param array the backing array.
068: */
069: public FastByteArrayInputStream(final byte[] array) {
070: this (array, 0, array.length);
071: }
072:
073: public boolean markSupported() {
074: return true;
075: }
076:
077: public void reset() {
078: position = mark;
079: }
080:
081: /** Closing a fast byte array input stream has no effect. */
082: public void close() {
083: }
084:
085: public void mark(final int dummy) {
086: mark = position;
087: }
088:
089: public int available() {
090: return length - position;
091: }
092:
093: public long skip(long n) {
094: if (n <= length - position) {
095: position += (int) n;
096: return n;
097: }
098: n = length - position;
099: position = length;
100: return n;
101: }
102:
103: public int read() {
104: if (length == position)
105: return -1;
106: return array[offset + position++] & 0xFF;
107: }
108:
109: /** Reads bytes from this byte-array input stream as
110: * specified in {@link java.io.InputStream#read(byte[], int, int)}.
111: * Note that the implementation given in {@link java.io.ByteArrayInputStream#read(byte[], int, int)}
112: * will return -1 on a zero-length read at EOF, contrarily to the specification. We won't.
113: */
114:
115: public int read(final byte b[], final int offset, final int length) {
116: if (this .length == this .position)
117: return length == 0 ? 0 : -1;
118: final int n = Math.min(length, this .length - this .position);
119: System.arraycopy(array, this .offset + this .position, b, offset,
120: n);
121: this .position += n;
122: return n;
123: }
124:
125: public long position() {
126: return position;
127: }
128:
129: public void position(final long newPosition) {
130: position = (int) Math.min(newPosition, length);
131: }
132:
133: @Override
134: public long length() {
135: return length;
136: }
137: }
|