add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / store / RAMInputStream.java
1 package org.apache.lucene.store;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22 /** A memory-resident {@link IndexInput} implementation. 
23  *  
24  *  @lucene.internal */
25 public class RAMInputStream extends IndexInput implements Cloneable {
26   static final int BUFFER_SIZE = RAMOutputStream.BUFFER_SIZE;
27
28   private RAMFile file;
29   private long length;
30
31   private byte[] currentBuffer;
32   private int currentBufferIndex;
33   
34   private int bufferPosition;
35   private long bufferStart;
36   private int bufferLength;
37
38   public RAMInputStream(RAMFile f) throws IOException {
39     file = f;
40     length = file.length;
41     if (length/BUFFER_SIZE >= Integer.MAX_VALUE) {
42       throw new IOException("Too large RAMFile! "+length); 
43     }
44
45     // make sure that we switch to the
46     // first needed buffer lazily
47     currentBufferIndex = -1;
48     currentBuffer = null;
49   }
50
51   @Override
52   public void close() {
53     // nothing to do here
54   }
55
56   @Override
57   public long length() {
58     return length;
59   }
60
61   @Override
62   public byte readByte() throws IOException {
63     if (bufferPosition >= bufferLength) {
64       currentBufferIndex++;
65       switchCurrentBuffer(true);
66     }
67     return currentBuffer[bufferPosition++];
68   }
69
70   @Override
71   public void readBytes(byte[] b, int offset, int len) throws IOException {
72     while (len > 0) {
73       if (bufferPosition >= bufferLength) {
74         currentBufferIndex++;
75         switchCurrentBuffer(true);
76       }
77
78       int remainInBuffer = bufferLength - bufferPosition;
79       int bytesToCopy = len < remainInBuffer ? len : remainInBuffer;
80       System.arraycopy(currentBuffer, bufferPosition, b, offset, bytesToCopy);
81       offset += bytesToCopy;
82       len -= bytesToCopy;
83       bufferPosition += bytesToCopy;
84     }
85   }
86
87   private final void switchCurrentBuffer(boolean enforceEOF) throws IOException {
88     bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
89     if (currentBufferIndex >= file.numBuffers()) {
90       // end of file reached, no more buffers left
91       if (enforceEOF)
92         throw new IOException("Read past EOF");
93       else {
94         // Force EOF if a read takes place at this position
95         currentBufferIndex--;
96         bufferPosition = BUFFER_SIZE;
97       }
98     } else {
99       currentBuffer = file.getBuffer(currentBufferIndex);
100       bufferPosition = 0;
101       long buflen = length - bufferStart;
102       bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int) buflen;
103     }
104   }
105
106   @Override
107   public void copyBytes(IndexOutput out, long numBytes) throws IOException {
108     assert numBytes >= 0: "numBytes=" + numBytes;
109     
110     long left = numBytes;
111     while (left > 0) {
112       if (bufferPosition == bufferLength) {
113         ++currentBufferIndex;
114         switchCurrentBuffer(true);
115       }
116       
117       final int bytesInBuffer = bufferLength - bufferPosition;
118       final int toCopy = (int) (bytesInBuffer < left ? bytesInBuffer : left);
119       out.writeBytes(currentBuffer, bufferPosition, toCopy);
120       bufferPosition += toCopy;
121       left -= toCopy;
122     }
123     
124     assert left == 0: "Insufficient bytes to copy: numBytes=" + numBytes + " copied=" + (numBytes - left);
125   }
126   
127   @Override
128   public long getFilePointer() {
129     return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition;
130   }
131
132   @Override
133   public void seek(long pos) throws IOException {
134     if (currentBuffer==null || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE) {
135       currentBufferIndex = (int) (pos / BUFFER_SIZE);
136       switchCurrentBuffer(false);
137     }
138     bufferPosition = (int) (pos % BUFFER_SIZE);
139   }
140 }