singrdk/base/Services/Smb/Shared/ByteReader.sg

332 lines
9.3 KiB
Plaintext
Raw Permalink Normal View History

2008-11-17 18:29:00 -05:00
// ----------------------------------------------------------------------------
2008-03-05 09:52:00 -05:00
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
2008-11-17 18:29:00 -05:00
// ----------------------------------------------------------------------------
2008-03-05 09:52:00 -05:00
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
namespace Smb.Shared
{
public class ExByteReader
{
private int _start;
private int _length;
private int _pos;
public ExByteReader(int start, int length)
{
_start = start;
_length = length;
_pos = 0;
}
#if false
public ByteReader(ArraySpan<byte> span)
: this(span.ContainingArray, span.Offset, span.Length)
{
}
#endif
public int Position
{
get { return _pos; }
set
{
if (value < 0)
throw new ArgumentException("Position cannot be negative");
if (value > _length)
throw new ArgumentException("Position cannot exceed length of data");
_pos = value;
}
}
public int Length
{
get { return _length; }
}
public byte ReadByte(byte[]! in ExHeap buffer)
{
if (_pos < _length)
return buffer[_start + _pos++];
else
throw new Exception("The buffer has ended. Cannot read more data.");
}
public byte[]! ReadBytes(byte[]! in ExHeap buffer, int count)
{
if (count < 0)
throw new ArgumentException("Count cannot be negative.");
if (_pos + count > _length)
throw new InvalidOperationException("Attempt to read beyond end of buffer.");
if (count == 0)
return new byte[0];
byte[] result = new byte[count];
Bitter.ToByteArray(buffer, _pos, count, result, 0);
_pos += count;
return result;
}
public ulong ReadUInt64Le(byte[]! in ExHeap buffer)
{
byte b0 = ReadByte(buffer);
byte b1 = ReadByte(buffer);
byte b2 = ReadByte(buffer);
byte b3 = ReadByte(buffer);
byte b4 = ReadByte(buffer);
byte b5 = ReadByte(buffer);
byte b6 = ReadByte(buffer);
byte b7 = ReadByte(buffer);
return (ulong)b0
| (ulong)b1 << 8
| (ulong)b2 << 0x10
| (ulong)b3 << 0x18
| (ulong)b4 << 0x20
| (ulong)b5 << 0x28
| (ulong)b6 << 0x30
| (ulong)b7 << 0x38;
}
public long ReadInt64Le(byte[]! in ExHeap buffer)
{
byte b0 = ReadByte(buffer);
byte b1 = ReadByte(buffer);
byte b2 = ReadByte(buffer);
byte b3 = ReadByte(buffer);
byte b4 = ReadByte(buffer);
byte b5 = ReadByte(buffer);
byte b6 = ReadByte(buffer);
byte b7 = ReadByte(buffer);
return (long)b0
| (long)b1 << 8
| (long)b2 << 0x10
| (long)b3 << 0x18
| (long)b4 << 0x20
| (long)b5 << 0x28
| (long)b6 << 0x30
| (long)b7 << 0x38;
}
// Reads a zero-terminated string.
public string! ReadStringUnicode(byte[]! in ExHeap buffer)
{
StringBuilder str = new StringBuilder();
for (;;)
{
// Not too happy with this.
if (_pos + 2 > _length)
return str.ToString();
char c = (char)ReadUInt16Le(buffer);
if (c == 0)
return str.ToString();
str.Append(c);
}
}
public uint ReadUInt32Le(byte[]! in ExHeap buffer)
{
byte b0 = ReadByte(buffer);
byte b1 = ReadByte(buffer);
byte b2 = ReadByte(buffer);
byte b3 = ReadByte(buffer);
return (UInt32)(b0 | (b1 << 8) | (b2 << 0x10) | (b3 << 0x18));
}
public int ReadInt32Le(byte[]! in ExHeap buffer)
{
return (int)ReadUInt32Le(buffer);
}
public ushort ReadUInt16Le(byte[]! in ExHeap buffer)
{
byte b0 = ReadByte(buffer);
byte b1 = ReadByte(buffer);
return (UInt16)(b0 | (b1 << 8));
}
public void Skip(int count)
{
if (_pos + count > _length)
throw new Exception("Cannot seek to requested position.");
_pos += count;
}
public Guid ReadGuid(byte[]! in ExHeap buffer)
{
byte[]! data = ReadBytes(buffer, 16);
return new Guid(data);
}
}
public class ByteReader
{
private byte[]! _buffer;
private int _start;
private int _length;
private int _pos;
public ByteReader(byte[]! buffer, int start, int length)
{
_buffer = buffer;
_start = start;
_length = length;
_pos = 0;
}
public ByteReader(byte[]! buffer)
{
this(buffer, 0, buffer.Length);
}
#if false
public ByteReader(ArraySpan<byte> span)
: this(span.ContainingArray, span.Offset, span.Length)
{
}
#endif
public int Position
{
get { return _pos; }
set
{
if (value < 0)
throw new ArgumentException("Position cannot be negative");
if (value > _length)
throw new ArgumentException("Position cannot exceed length of data");
_pos = value;
}
}
public int Length
{
get { return _length; }
}
public byte ReadByte()
{
if (_pos < _length)
return _buffer[_start + _pos++];
else
throw new Exception("The buffer has ended. Cannot read more data.");
}
public byte[]! ReadBytes(int count)
{
if (count < 0)
throw new ArgumentException("Count cannot be negative.");
if (_pos + count > _length)
throw new InvalidOperationException("Attempt to read beyond end of buffer.");
if (count == 0)
return new byte[0];
byte[] result = new byte[count];
Buffer.BlockCopy(_buffer, _pos, result, 0, count);
_pos += count;
return result;
}
public ulong ReadUInt64Le()
{
byte b0 = ReadByte();
byte b1 = ReadByte();
byte b2 = ReadByte();
byte b3 = ReadByte();
byte b4 = ReadByte();
byte b5 = ReadByte();
byte b6 = ReadByte();
byte b7 = ReadByte();
return (ulong)b0
| (ulong)b1 << 8
| (ulong)b2 << 0x10
| (ulong)b3 << 0x18
| (ulong)b4 << 0x20
| (ulong)b5 << 0x28
| (ulong)b6 << 0x30
| (ulong)b7 << 0x38;
}
public long ReadInt64Le()
{
byte b0 = ReadByte();
byte b1 = ReadByte();
byte b2 = ReadByte();
byte b3 = ReadByte();
byte b4 = ReadByte();
byte b5 = ReadByte();
byte b6 = ReadByte();
byte b7 = ReadByte();
return (long)b0
| (long)b1 << 8
| (long)b2 << 0x10
| (long)b3 << 0x18
| (long)b4 << 0x20
| (long)b5 << 0x28
| (long)b6 << 0x30
| (long)b7 << 0x38;
}
public uint ReadUInt32Le()
{
byte b0 = ReadByte();
byte b1 = ReadByte();
byte b2 = ReadByte();
byte b3 = ReadByte();
return (UInt32)(b0 | (b1 << 8) | (b2 << 0x10) | (b3 << 0x18));
}
public int ReadInt32Le()
{
return (int)ReadUInt32Le();
}
public ushort ReadUInt16Le()
{
byte b0 = ReadByte();
byte b1 = ReadByte();
return (UInt16)(b0 | (b1 << 8));
}
public void Skip(int count)
{
if (_pos + count > _length)
throw new Exception("Cannot seek to requested position.");
_pos += count;
}
// Reads a zero-terminated string.
public string! ReadStringUnicode()
{
StringBuilder str = new StringBuilder();
for (;;)
{
// Not too happy with this.
if (_pos + 2 > _length)
return str.ToString();
char c = (char)ReadUInt16Le();
if (c == 0)
return str.ToString();
str.Append(c);
}
}
public Guid ReadGuid()
{
byte[]! data = ReadBytes(16);
return new Guid(data);
}
}
}