001: package org.apache.lucene.store;
002:
003: import java.io.IOException;
004:
005: /**
006: * Licensed to the Apache Software Foundation (ASF) under one or more
007: * contributor license agreements. See the NOTICE file distributed with
008: * this work for additional information regarding copyright ownership.
009: * The ASF licenses this file to You under the Apache License, Version 2.0
010: * (the "License"); you may not use this file except in compliance with
011: * the License. You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing, software
016: * distributed under the License is distributed on an "AS IS" BASIS,
017: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018: * See the License for the specific language governing permissions and
019: * limitations under the License.
020: */
021:
022: /**
023: * A memory-resident {@link IndexInput} implementation.
024: *
025: * @version $Id: RAMInputStream.java 598693 2007-11-27 17:01:21Z mikemccand $
026: */
027:
028: class RAMInputStream extends IndexInput implements Cloneable {
029: static final int BUFFER_SIZE = RAMOutputStream.BUFFER_SIZE;
030:
031: private RAMFile file;
032: private long length;
033:
034: private byte[] currentBuffer;
035: private int currentBufferIndex;
036:
037: private int bufferPosition;
038: private long bufferStart;
039: private int bufferLength;
040:
041: RAMInputStream(RAMFile f) throws IOException {
042: file = f;
043: length = file.length;
044: if (length / BUFFER_SIZE >= Integer.MAX_VALUE) {
045: throw new IOException("Too large RAMFile! " + length);
046: }
047:
048: // make sure that we switch to the
049: // first needed buffer lazily
050: currentBufferIndex = -1;
051: currentBuffer = null;
052: }
053:
054: public void close() {
055: // nothing to do here
056: }
057:
058: public long length() {
059: return length;
060: }
061:
062: public byte readByte() throws IOException {
063: if (bufferPosition >= bufferLength) {
064: currentBufferIndex++;
065: switchCurrentBuffer();
066: }
067: return currentBuffer[bufferPosition++];
068: }
069:
070: public void readBytes(byte[] b, int offset, int len)
071: throws IOException {
072: while (len > 0) {
073: if (bufferPosition >= bufferLength) {
074: currentBufferIndex++;
075: switchCurrentBuffer();
076: }
077:
078: int remainInBuffer = bufferLength - bufferPosition;
079: int bytesToCopy = len < remainInBuffer ? len
080: : remainInBuffer;
081: System.arraycopy(currentBuffer, bufferPosition, b, offset,
082: bytesToCopy);
083: offset += bytesToCopy;
084: len -= bytesToCopy;
085: bufferPosition += bytesToCopy;
086: }
087: }
088:
089: private final void switchCurrentBuffer() throws IOException {
090: if (currentBufferIndex >= file.numBuffers()) {
091: // end of file reached, no more buffers left
092: throw new IOException("Read past EOF");
093: } else {
094: currentBuffer = (byte[]) file.getBuffer(currentBufferIndex);
095: bufferPosition = 0;
096: bufferStart = (long) BUFFER_SIZE
097: * (long) currentBufferIndex;
098: long buflen = length - bufferStart;
099: bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE
100: : (int) buflen;
101: }
102: }
103:
104: public long getFilePointer() {
105: return currentBufferIndex < 0 ? 0 : bufferStart
106: + bufferPosition;
107: }
108:
109: public void seek(long pos) throws IOException {
110: if (currentBuffer == null || pos < bufferStart
111: || pos >= bufferStart + BUFFER_SIZE) {
112: currentBufferIndex = (int) (pos / BUFFER_SIZE);
113: switchCurrentBuffer();
114: }
115: bufferPosition = (int) (pos % BUFFER_SIZE);
116: }
117: }
|