KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lucene > store > BufferedIndexInput


1 package org.apache.lucene.store;
2
3 /**
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.io.IOException JavaDoc;
20
21 /** Base implementation class for buffered {@link IndexInput}. */
22 public abstract class BufferedIndexInput extends IndexInput {
23   static final int BUFFER_SIZE = BufferedIndexOutput.BUFFER_SIZE;
24
25   private byte[] buffer;
26
27   private long bufferStart = 0; // position in file of buffer
28
private int bufferLength = 0; // end of valid bytes
29
private int bufferPosition = 0; // next byte to read
30

31   public byte readByte() throws IOException JavaDoc {
32     if (bufferPosition >= bufferLength)
33       refill();
34     return buffer[bufferPosition++];
35   }
36
37   public void readBytes(byte[] b, int offset, int len)
38        throws IOException JavaDoc {
39     if (len < BUFFER_SIZE) {
40       for (int i = 0; i < len; i++) // read byte-by-byte
41
b[i + offset] = (byte)readByte();
42     } else { // read all-at-once
43
long start = getFilePointer();
44       seekInternal(start);
45       readInternal(b, offset, len);
46
47       bufferStart = start + len; // adjust stream variables
48
bufferPosition = 0;
49       bufferLength = 0; // trigger refill() on read
50
}
51   }
52
53   private void refill() throws IOException JavaDoc {
54     long start = bufferStart + bufferPosition;
55     long end = start + BUFFER_SIZE;
56     if (end > length()) // don't read past EOF
57
end = length();
58     bufferLength = (int)(end - start);
59     if (bufferLength <= 0)
60       throw new IOException JavaDoc("read past EOF");
61
62     if (buffer == null)
63       buffer = new byte[BUFFER_SIZE]; // allocate buffer lazily
64
readInternal(buffer, 0, bufferLength);
65
66     bufferStart = start;
67     bufferPosition = 0;
68   }
69
70   /** Expert: implements buffer refill. Reads bytes from the current position
71    * in the input.
72    * @param b the array to read bytes into
73    * @param offset the offset in the array to start storing bytes
74    * @param length the number of bytes to read
75    */

76   protected abstract void readInternal(byte[] b, int offset, int length)
77        throws IOException JavaDoc;
78
79   public long getFilePointer() { return bufferStart + bufferPosition; }
80
81   public void seek(long pos) throws IOException JavaDoc {
82     if (pos >= bufferStart && pos < (bufferStart + bufferLength))
83       bufferPosition = (int)(pos - bufferStart); // seek within buffer
84
else {
85       bufferStart = pos;
86       bufferPosition = 0;
87       bufferLength = 0; // trigger refill() on read()
88
seekInternal(pos);
89     }
90   }
91
92   /** Expert: implements seek. Sets current position in this file, where the
93    * next {@link #readInternal(byte[],int,int)} will occur.
94    * @see #readInternal(byte[],int,int)
95    */

96   protected abstract void seekInternal(long pos) throws IOException JavaDoc;
97
98   public Object JavaDoc clone() {
99     BufferedIndexInput clone = (BufferedIndexInput)super.clone();
100
101     if (buffer != null) {
102       clone.buffer = new byte[BUFFER_SIZE];
103       System.arraycopy(buffer, 0, clone.buffer, 0, bufferLength);
104     }
105
106     return clone;
107   }
108
109 }
110
Popular Tags