diff options
author | Miguel de Icaza <miguel@gnome.org> | 2015-06-11 19:34:09 +0300 |
---|---|---|
committer | Miguel de Icaza <miguel@gnome.org> | 2015-06-11 19:34:09 +0300 |
commit | 85978b7eb94738f516824341213d5e94060f5284 (patch) | |
tree | 879c92ba9e56a74ae2a0cbbaa802344b9c39e7d0 /src/core/Store/RAMInputStream.cs |
Initial commit of lightweight Lucene.Net to be used in Mono
Diffstat (limited to 'src/core/Store/RAMInputStream.cs')
-rw-r--r-- | src/core/Store/RAMInputStream.cs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/core/Store/RAMInputStream.cs b/src/core/Store/RAMInputStream.cs new file mode 100644 index 0000000..7e97f5f --- /dev/null +++ b/src/core/Store/RAMInputStream.cs @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; + +namespace Lucene.Net.Store +{ + + /// <summary> A memory-resident <see cref="IndexInput" /> implementation. + /// + /// </summary> + public class RAMInputStream : IndexInput + { + internal static readonly int BUFFER_SIZE; + + private RAMFile file; + private long length; + + private byte[] currentBuffer; + private int currentBufferIndex; + + private int bufferPosition; + private long bufferStart; + private int bufferLength; + + public /*internal*/ RAMInputStream(RAMFile f) + { + file = f; + length = file.length; + if (length / BUFFER_SIZE >= System.Int32.MaxValue) + { + throw new System.IO.IOException("Too large RAMFile! " + length); + } + + // make sure that we switch to the + // first needed buffer lazily + currentBufferIndex = - 1; + currentBuffer = null; + } + + protected override void Dispose(bool disposing) + { + // do nothing + } + + public override long Length() + { + return length; + } + + public override byte ReadByte() + { + if (bufferPosition >= bufferLength) + { + currentBufferIndex++; + SwitchCurrentBuffer(true); + } + return currentBuffer[bufferPosition++]; + } + + public override void ReadBytes(byte[] b, int offset, int len) + { + while (len > 0) + { + if (bufferPosition >= bufferLength) + { + currentBufferIndex++; + SwitchCurrentBuffer(true); + } + + int remainInBuffer = bufferLength - bufferPosition; + int bytesToCopy = len < remainInBuffer?len:remainInBuffer; + Array.Copy(currentBuffer, bufferPosition, b, offset, bytesToCopy); + offset += bytesToCopy; + len -= bytesToCopy; + bufferPosition += bytesToCopy; + } + } + + private void SwitchCurrentBuffer(bool enforceEOF) + { + if (currentBufferIndex >= file.NumBuffers()) + { + // end of file reached, no more buffers left + if (enforceEOF) + throw new System.IO.IOException("Read past EOF"); + else + { + // Force EOF if a read takes place at this position + currentBufferIndex--; + bufferPosition = BUFFER_SIZE; + } + } + else + { + currentBuffer = file.GetBuffer(currentBufferIndex); + bufferPosition = 0; + bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; + long buflen = length - bufferStart; + bufferLength = buflen > BUFFER_SIZE?BUFFER_SIZE:(int) buflen; + } + } + + public override long FilePointer + { + get { return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; } + } + + public override void Seek(long pos) + { + if (currentBuffer == null || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE) + { + currentBufferIndex = (int) (pos / BUFFER_SIZE); + SwitchCurrentBuffer(false); + } + bufferPosition = (int) (pos % BUFFER_SIZE); + } + + static RAMInputStream() + { + BUFFER_SIZE = RAMOutputStream.BUFFER_SIZE; + } + } +}
\ No newline at end of file |