blob: 562355ef52a3fdf6dc7eae1372bbfcec2d48f8d9 [file] [log] [blame]
using System;
namespace Lucene.Net.Store
{
/*
* 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 BytesRef = Lucene.Net.Util.BytesRef;
/// <summary>
/// DataInput backed by a byte array.
/// <b>WARNING:</b> this class omits all low-level checks.
/// <para/>
/// @lucene.experimental
/// </summary>
public sealed class ByteArrayDataInput : DataInput
{
private byte[] bytes;
private int pos;
private int limit;
public ByteArrayDataInput(byte[] bytes)
{
Reset(bytes);
}
public ByteArrayDataInput(byte[] bytes, int offset, int len)
{
Reset(bytes, offset, len);
}
public ByteArrayDataInput()
{
Reset(BytesRef.EMPTY_BYTES);
}
public void Reset(byte[] bytes)
{
Reset(bytes, 0, bytes.Length);
}
/// <summary>
/// NOTE: sets pos to 0, which is not right if you had
/// called reset w/ non-zero offset!!
/// </summary>
public void Rewind()
{
pos = 0;
}
public int Position
{
get => pos;
set => this.pos = value;
}
public void Reset(byte[] bytes, int offset, int len)
{
this.bytes = bytes;
pos = offset;
limit = offset + len;
}
public int Length => limit;
public bool Eof => pos == limit;
public override void SkipBytes(long count)
{
pos += (int)count;
}
/// <summary>
/// LUCENENET NOTE: Important - always cast to ushort (System.UInt16) before using to ensure
/// the value is positive!
/// <para/>
/// NOTE: this was readShort() in Lucene
/// </summary>
public override short ReadInt16()
{
return (short)(((bytes[pos++] & 0xFF) << 8) | (bytes[pos++] & 0xFF));
}
/// <summary>
/// NOTE: this was readInt() in Lucene
/// </summary>
public override int ReadInt32()
{
return ((bytes[pos++] & 0xFF) << 24) | ((bytes[pos++] & 0xFF) << 16)
| ((bytes[pos++] & 0xFF) << 8) | (bytes[pos++] & 0xFF);
}
/// <summary>
/// NOTE: this was readLong() in Lucene
/// </summary>
public override long ReadInt64()
{
int i1 = ((bytes[pos++] & 0xff) << 24) | ((bytes[pos++] & 0xff) << 16)
| ((bytes[pos++] & 0xff) << 8) | (bytes[pos++] & 0xff);
int i2 = ((bytes[pos++] & 0xff) << 24) | ((bytes[pos++] & 0xff) << 16)
| ((bytes[pos++] & 0xff) << 8) | (bytes[pos++] & 0xff);
return (((long)i1) << 32) | (i2 & 0xFFFFFFFFL);
}
/// <summary>
/// NOTE: this was readVInt() in Lucene
/// </summary>
public override int ReadVInt32()
{
byte b = bytes[pos++];
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return b;
}
int i = b & 0x7F;
b = bytes[pos++];
i |= (b & 0x7F) << 7;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7F) << 14;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7F) << 21;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
// Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors:
i |= (b & 0x0F) << 28;
if ((b & 0xF0) == 0)
{
return i;
}
throw new Exception("Invalid VInt32 detected (too many bits)");
}
/// <summary>
/// NOTE: this was readVLong() in Lucene
/// </summary>
public override long ReadVInt64()
{
byte b = bytes[pos++];
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return b;
}
long i = b & 0x7FL;
b = bytes[pos++];
i |= (b & 0x7FL) << 7;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 14;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 21;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 28;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 35;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 42;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 49;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
b = bytes[pos++];
i |= (b & 0x7FL) << 56;
if (b <= sbyte.MaxValue) // LUCENENET: Optimized equivalent of "if ((sbyte)b >= 0)"
{
return i;
}
throw new Exception("Invalid VInt64 detected (negative values disallowed)");
}
// NOTE: AIOOBE not EOF if you read too much
public override byte ReadByte()
{
return bytes[pos++];
}
// NOTE: AIOOBE not EOF if you read too much
public override void ReadBytes(byte[] b, int offset, int len)
{
Buffer.BlockCopy(bytes, pos, b, offset, len);
pos += len;
}
}
}