/*
* 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
{
/// Abstract base class for input from a file in a {@link Directory}. A
/// random-access input stream. Used for all Lucene index input operations.
///
///
///
public abstract class IndexInput : System.ICloneable
{
private byte[] bytes; // used by readString()
private char[] chars; // used by readModifiedUTF8String()
private bool preUTF8Strings; // true if we are reading old (modified UTF8) string format
/// Reads and returns a single byte.
///
///
public abstract byte ReadByte();
/// Reads a specified number of bytes into an array at the specified offset.
/// the array to read bytes into
///
/// the offset in the array to start storing bytes
///
/// the number of bytes to read
///
///
///
public abstract void ReadBytes(byte[] b, int offset, int len);
/// Reads a specified number of bytes into an array at the
/// specified offset with control over whether the read
/// should be buffered (callers who have their own buffer
/// should pass in "false" for useBuffer). Currently only
/// {@link BufferedIndexInput} respects this parameter.
///
/// the array to read bytes into
///
/// the offset in the array to start storing bytes
///
/// the number of bytes to read
///
/// set to false if the caller will handle
/// buffering.
///
///
///
public virtual void ReadBytes(byte[] b, int offset, int len, bool useBuffer)
{
// Default to ignoring useBuffer entirely
ReadBytes(b, offset, len);
}
/// Reads four bytes and returns an int.
///
///
public virtual int ReadInt()
{
return ((ReadByte() & 0xFF) << 24) | ((ReadByte() & 0xFF) << 16) | ((ReadByte() & 0xFF) << 8) | (ReadByte() & 0xFF);
}
/// Reads an int stored in variable-length format. Reads between one and
/// five bytes. Smaller values take fewer bytes. Negative numbers are not
/// supported.
///
///
///
public virtual int ReadVInt()
{
byte b = ReadByte();
int i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7)
{
b = ReadByte();
i |= (b & 0x7F) << shift;
}
return i;
}
/// Reads eight bytes and returns a long.
///
///
public virtual long ReadLong()
{
return (((long) ReadInt()) << 32) | (ReadInt() & 0xFFFFFFFFL);
}
/// Reads a long stored in variable-length format. Reads between one and
/// nine bytes. Smaller values take fewer bytes. Negative numbers are not
/// supported.
///
public virtual long ReadVLong()
{
byte b = ReadByte();
long i = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7)
{
b = ReadByte();
i |= (b & 0x7FL) << shift;
}
return i;
}
/// Call this if readString should read characters stored
/// in the old modified UTF8 format (length in java chars
/// and java's modified UTF8 encoding). This is used for
/// indices written pre-2.4 See LUCENE-510 for details.
///
public virtual void SetModifiedUTF8StringsMode()
{
preUTF8Strings = true;
}
/// Reads a string.
///
///
public virtual System.String ReadString()
{
if (preUTF8Strings)
return ReadModifiedUTF8String();
int length = ReadVInt();
if (bytes == null || length > bytes.Length)
{
bytes = new byte[(int) (length * 1.25)];
}
ReadBytes(bytes, 0, length);
return System.Text.Encoding.UTF8.GetString(bytes, 0, length);
}
private System.String ReadModifiedUTF8String()
{
int length = ReadVInt();
if (chars == null || length > chars.Length)
chars = new char[length];
ReadChars(chars, 0, length);
return new System.String(chars, 0, length);
}
/// Reads Lucene's old "modified UTF-8" encoded
/// characters into an array.
///
/// the array to read characters into
///
/// the offset in the array to start storing characters
///
/// the number of characters to read
///
///
///
/// -- please use readString or readBytes
/// instead, and construct the string
/// from those utf8 bytes
///
[Obsolete("-- please use ReadString or ReadBytes instead, and construct the string from those utf8 bytes")]
public virtual void ReadChars(char[] buffer, int start, int length)
{
int end = start + length;
for (int i = start; i < end; i++)
{
byte b = ReadByte();
if ((b & 0x80) == 0)
buffer[i] = (char) (b & 0x7F);
else if ((b & 0xE0) != 0xE0)
{
buffer[i] = (char) (((b & 0x1F) << 6) | (ReadByte() & 0x3F));
}
else
buffer[i] = (char) (((b & 0x0F) << 12) | ((ReadByte() & 0x3F) << 6) | (ReadByte() & 0x3F));
}
}
/// Expert
///
/// Similar to {@link #ReadChars(char[], int, int)} but does not do any conversion operations on the bytes it is reading in. It still
/// has to invoke {@link #ReadByte()} just as {@link #ReadChars(char[], int, int)} does, but it does not need a buffer to store anything
/// and it does not have to do any of the bitwise operations, since we don't actually care what is in the byte except to determine
/// how many more bytes to read
///
/// The number of chars to read
///
/// this method operates on old "modified utf8" encoded
/// strings
///
[Obsolete("this method operates on old \"modified utf8\" encoded strings")]
public virtual void SkipChars(int length)
{
for (int i = 0; i < length; i++)
{
byte b = ReadByte();
if ((b & 0x80) == 0)
{
//do nothing, we only need one byte
}
else if ((b & 0xE0) != 0xE0)
{
ReadByte(); //read an additional byte
}
else
{
//read two additional bytes.
ReadByte();
ReadByte();
}
}
}
/// Closes the stream to futher operations.
public abstract void Close();
/// Returns the current position in this file, where the next read will
/// occur.
///
///
///
public abstract long GetFilePointer();
/// Sets current position in this file, where the next read will occur.
///
///
public abstract void Seek(long pos);
/// The number of bytes in the file.
public abstract long Length();
/// Returns a clone of this stream.
///
/// Clones of a stream access the same data, and are positioned at the same
/// point as the stream they were cloned from.
///
/// Expert: Subclasses must ensure that clones may be positioned at
/// different points in the input from each other and from the stream they
/// were cloned from.
///
public virtual System.Object Clone()
{
IndexInput clone = null;
try
{
clone = (IndexInput) base.MemberwiseClone();
}
catch (System.Exception e)
{
}
clone.bytes = null;
clone.chars = null;
return clone;
}
// returns Map
public virtual System.Collections.Generic.IDictionary ReadStringStringMap()
{
System.Collections.Generic.Dictionary map = new System.Collections.Generic.Dictionary();
int count = ReadInt();
for (int i = 0; i < count; i++)
{
System.String key = ReadString();
System.String val = ReadString();
map[key] = val;
}
return map;
}
}
}