BufferedIndexInput.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:4k
- /*
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed 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>Base implementation class for buffered {@link IndexInput}. </summary>
- public abstract class BufferedIndexInput : IndexInput, System.ICloneable
- {
- internal static readonly int BUFFER_SIZE;
-
- private byte[] buffer;
-
- private long bufferStart = 0; // position in file of buffer
- private int bufferLength = 0; // end of valid bytes
- private int bufferPosition = 0; // next byte to read
-
- public override byte ReadByte()
- {
- if (bufferPosition >= bufferLength)
- Refill();
- return buffer[bufferPosition++];
- }
-
- public override void ReadBytes(byte[] b, int offset, int len)
- {
- if (len < BUFFER_SIZE)
- {
- for (int i = 0; i < len; i++)
- // read byte-by-byte
- b[i + offset] = (byte) ReadByte();
- }
- else
- {
- // read all-at-once
- long start = GetFilePointer();
- SeekInternal(start);
- ReadInternal(b, offset, len);
-
- bufferStart = start + len; // adjust stream variables
- bufferPosition = 0;
- bufferLength = 0; // trigger refill() on read
- }
- }
-
- private void Refill()
- {
- long start = bufferStart + bufferPosition;
- long end = start + BUFFER_SIZE;
- if (end > Length())
- // don't read past EOF
- end = Length();
- bufferLength = (int) (end - start);
- if (bufferLength <= 0)
- throw new System.IO.IOException("read past EOF");
-
- if (buffer == null)
- buffer = new byte[BUFFER_SIZE]; // allocate buffer lazily
- ReadInternal(buffer, 0, bufferLength);
-
- bufferStart = start;
- bufferPosition = 0;
- }
-
- /// <summary>Expert: implements buffer refill. Reads bytes from the current position
- /// in the input.
- /// </summary>
- /// <param name="b">the array to read bytes into
- /// </param>
- /// <param name="offset">the offset in the array to start storing bytes
- /// </param>
- /// <param name="length">the number of bytes to read
- /// </param>
- public abstract void ReadInternal(byte[] b, int offset, int length);
-
- public override long GetFilePointer()
- {
- return bufferStart + bufferPosition;
- }
-
- public override void Seek(long pos)
- {
- if (pos >= bufferStart && pos < (bufferStart + bufferLength))
- bufferPosition = (int) (pos - bufferStart);
- // seek within buffer
- else
- {
- bufferStart = pos;
- bufferPosition = 0;
- bufferLength = 0; // trigger refill() on read()
- SeekInternal(pos);
- }
- }
-
- /// <summary>Expert: implements seek. Sets current position in this file, where the
- /// next {@link #ReadInternal(byte[],int,int)} will occur.
- /// </summary>
- /// <seealso cref="ReadInternal(byte[],int,int)">
- /// </seealso>
- public abstract void SeekInternal(long pos);
-
- public override System.Object Clone()
- {
- BufferedIndexInput clone = (BufferedIndexInput) base.Clone();
-
- if (buffer != null)
- {
- clone.buffer = new byte[BUFFER_SIZE];
- Array.Copy(buffer, 0, clone.buffer, 0, bufferLength);
- }
-
- return clone;
- }
- static BufferedIndexInput()
- {
- BUFFER_SIZE = BufferedIndexOutput.BUFFER_SIZE;
- }
- }
- }