cvsimport
[beagle.git] / beagled / Lucene.Net / Store / BufferedIndexInput.cs
blob7e43d44c2c1eaab45503e0d6849ba7ecf8fcdec8
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 using System;
19 namespace Lucene.Net.Store
22 /// <summary>Base implementation class for buffered {@link IndexInput}. </summary>
23 public abstract class BufferedIndexInput : IndexInput, System.ICloneable
25 internal static readonly int BUFFER_SIZE;
27 private byte[] buffer;
29 private long bufferStart = 0; // position in file of buffer
30 private int bufferLength = 0; // end of valid bytes
31 private int bufferPosition = 0; // next byte to read
33 public override byte ReadByte()
35 if (bufferPosition >= bufferLength)
36 Refill();
37 return buffer[bufferPosition++];
40 public override void ReadBytes(byte[] b, int offset, int len)
42 if (len < BUFFER_SIZE)
44 for (int i = 0; i < len; i++)
45 // read byte-by-byte
46 b[i + offset] = (byte) ReadByte();
48 else
50 // read all-at-once
51 long start = GetFilePointer();
52 SeekInternal(start);
53 ReadInternal(b, offset, len);
55 bufferStart = start + len; // adjust stream variables
56 bufferPosition = 0;
57 bufferLength = 0; // trigger refill() on read
61 private void Refill()
63 long start = bufferStart + bufferPosition;
64 long end = start + BUFFER_SIZE;
65 if (end > Length())
66 // don't read past EOF
67 end = Length();
68 bufferLength = (int) (end - start);
69 if (bufferLength <= 0)
70 throw new System.IO.IOException("read past EOF");
72 if (buffer == null)
73 buffer = new byte[BUFFER_SIZE]; // allocate buffer lazily
74 ReadInternal(buffer, 0, bufferLength);
76 bufferStart = start;
77 bufferPosition = 0;
80 /// <summary>Expert: implements buffer refill. Reads bytes from the current position
81 /// in the input.
82 /// </summary>
83 /// <param name="b">the array to read bytes into
84 /// </param>
85 /// <param name="offset">the offset in the array to start storing bytes
86 /// </param>
87 /// <param name="length">the number of bytes to read
88 /// </param>
89 public abstract void ReadInternal(byte[] b, int offset, int length);
91 public override long GetFilePointer()
93 return bufferStart + bufferPosition;
96 public override void Seek(long pos)
98 if (pos >= bufferStart && pos < (bufferStart + bufferLength))
99 bufferPosition = (int) (pos - bufferStart);
100 // seek within buffer
101 else
103 bufferStart = pos;
104 bufferPosition = 0;
105 bufferLength = 0; // trigger refill() on read()
106 SeekInternal(pos);
110 /// <summary>Expert: implements seek. Sets current position in this file, where the
111 /// next {@link #ReadInternal(byte[],int,int)} will occur.
112 /// </summary>
113 /// <seealso cref="ReadInternal(byte[],int,int)">
114 /// </seealso>
115 public abstract void SeekInternal(long pos);
117 public override System.Object Clone()
119 BufferedIndexInput clone = (BufferedIndexInput) base.Clone();
121 if (buffer != null)
123 clone.buffer = new byte[BUFFER_SIZE];
124 Array.Copy(buffer, 0, clone.buffer, 0, bufferLength);
127 return clone;
130 static BufferedIndexInput()
132 BUFFER_SIZE = BufferedIndexOutput.BUFFER_SIZE;