1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2000-2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9package com.sleepycat.util; 10 11import java.io.InputStream; 12 13/** 14 * A replacement for ByteArrayInputStream that does not synchronize every 15 * byte read. 16 * 17 * <p>This class extends {@link InputStream} and its <code>read()</code> 18 * methods allow it to be used as a standard input stream. In addition, it 19 * provides <code>readFast()</code> methods that are not declared to throw 20 * <code>IOException</code>. <code>IOException</code> is never thrown by this 21 * class.</p> 22 * 23 * @author Mark Hayes 24 */ 25public class FastInputStream extends InputStream { 26 27 protected int len; 28 protected int off; 29 protected int mark; 30 protected byte[] buf; 31 32 /** 33 * Creates an input stream. 34 * 35 * @param buffer the data to read. 36 */ 37 public FastInputStream(byte[] buffer) { 38 39 buf = buffer; 40 len = buffer.length; 41 } 42 43 /** 44 * Creates an input stream. 45 * 46 * @param buffer the data to read. 47 * 48 * @param offset the byte offset at which to begin reading. 49 * 50 * @param length the number of bytes to read. 51 */ 52 public FastInputStream(byte[] buffer, int offset, int length) { 53 54 buf = buffer; 55 off = offset; 56 len = offset + length; 57 } 58 59 // --- begin ByteArrayInputStream compatible methods --- 60 61 @Override 62 public int available() { 63 64 return len - off; 65 } 66 67 @Override 68 public boolean markSupported() { 69 70 return true; 71 } 72 73 @Override 74 public void mark(int readLimit) { 75 76 mark = off; 77 } 78 79 @Override 80 public void reset() { 81 82 off = mark; 83 } 84 85 @Override 86 public long skip(long count) { 87 88 int myCount = (int) count; 89 if (myCount + off > len) { 90 myCount = len - off; 91 } 92 skipFast(myCount); 93 return myCount; 94 } 95 96 @Override 97 public int read() { 98 return readFast(); 99 } 100 101 @Override 102 public int read(byte[] toBuf) { 103 104 return readFast(toBuf, 0, toBuf.length); 105 } 106 107 @Override 108 public int read(byte[] toBuf, int offset, int length) { 109 110 return readFast(toBuf, offset, length); 111 } 112 113 // --- end ByteArrayInputStream compatible methods --- 114 115 /** 116 * Equivalent to <code>skip()<code> but takes an int parameter instead of a 117 * long, and does not check whether the count given is larger than the 118 * number of remaining bytes. 119 * @see #skip(long) 120 */ 121 public final void skipFast(int count) { 122 off += count; 123 } 124 125 /** 126 * Equivalent to <code>read()<code> but does not throw 127 * <code>IOException</code>. 128 * @see #read() 129 */ 130 public final int readFast() { 131 132 return (off < len) ? (buf[off++] & 0xff) : (-1); 133 } 134 135 /** 136 * Equivalent to <code>read(byte[])<code> but does not throw 137 * <code>IOException</code>. 138 * @see #read(byte[]) 139 */ 140 public final int readFast(byte[] toBuf) { 141 142 return readFast(toBuf, 0, toBuf.length); 143 } 144 145 /** 146 * Equivalent to <code>read(byte[],int,int)<code> but does not throw 147 * <code>IOException</code>. 148 * @see #read(byte[],int,int) 149 */ 150 public final int readFast(byte[] toBuf, int offset, int length) { 151 152 int avail = len - off; 153 if (avail <= 0) { 154 return -1; 155 } 156 if (length > avail) { 157 length = avail; 158 } 159 System.arraycopy(buf, off, toBuf, offset, length); 160 off += length; 161 return length; 162 } 163 164 /** 165 * Returns the underlying data being read. 166 * 167 * @return the underlying data. 168 */ 169 public final byte[] getBufferBytes() { 170 171 return buf; 172 } 173 174 /** 175 * Returns the offset at which data is being read from the buffer. 176 * 177 * @return the offset at which data is being read. 178 */ 179 public final int getBufferOffset() { 180 181 return off; 182 } 183 184 /** 185 * Returns the end of the buffer being read. 186 * 187 * @return the end of the buffer. 188 */ 189 public final int getBufferLength() { 190 191 return len; 192 } 193} 194