mirror of
https://github.com/thebreaddev/Supercell.GUT.git
synced 2024-11-14 09:24:37 +00:00
298 lines
6.6 KiB
C#
298 lines
6.6 KiB
C#
|
using Supercell.GUT.Titan.Logic.Debug;
|
|||
|
using Supercell.GUT.Titan.Logic.Math;
|
|||
|
using Supercell.GUT.Titan.Logic.Util;
|
|||
|
|
|||
|
namespace Supercell.GUT.Titan.Logic.DataStream;
|
|||
|
|
|||
|
public class ByteStream : ChecksumEncoder
|
|||
|
{
|
|||
|
public int Offset { get; set; }
|
|||
|
public int Length { get; set; }
|
|||
|
public int BitIndex { get; set; }
|
|||
|
|
|||
|
public byte[]? ByteArray { get; set; }
|
|||
|
|
|||
|
public ByteStream() : base()
|
|||
|
{
|
|||
|
this.Offset = 0;
|
|||
|
this.Length = 0;
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
this.ByteArray = new byte[10];
|
|||
|
}
|
|||
|
|
|||
|
public void ResetOffset()
|
|||
|
{
|
|||
|
this.Offset = 0;
|
|||
|
this.BitIndex = 0;
|
|||
|
}
|
|||
|
|
|||
|
public int GetLength()
|
|||
|
{
|
|||
|
if (this.Offset < this.Length)
|
|||
|
return this.Length;
|
|||
|
|
|||
|
return this.Offset;
|
|||
|
}
|
|||
|
|
|||
|
public override bool IsCheckSumOnlyMode()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public void SetOffset(int offset)
|
|||
|
{
|
|||
|
this.Offset = offset;
|
|||
|
this.BitIndex = 0;
|
|||
|
}
|
|||
|
|
|||
|
public int GetOffset()
|
|||
|
{
|
|||
|
return this.Offset;
|
|||
|
}
|
|||
|
|
|||
|
public override void WriteString(string? value)
|
|||
|
{
|
|||
|
base.WriteString(value);
|
|||
|
|
|||
|
if (value == null)
|
|||
|
{
|
|||
|
this.WriteIntToByteArray(-1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
byte[] bytes = LogicStringUtil.GetBytes(value);
|
|||
|
int length = bytes.Length;
|
|||
|
|
|||
|
if (length <= 900000)
|
|||
|
{
|
|||
|
this.EnsureCapacity(length + 4);
|
|||
|
this.WriteIntToByteArray(length);
|
|||
|
|
|||
|
Buffer.BlockCopy(bytes, 0, this.ByteArray!, this.Offset, length);
|
|||
|
|
|||
|
this.Offset += length;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debugger.Warning("ByteStream::writeString invalid string length " + length);
|
|||
|
this.WriteIntToByteArray(-1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void WriteIntToByteArray(int value)
|
|||
|
{
|
|||
|
this.EnsureCapacity(4);
|
|||
|
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
this.ByteArray![this.Offset++] = (byte)(value >> 24);
|
|||
|
this.ByteArray![this.Offset++] = (byte)(value >> 16);
|
|||
|
this.ByteArray![this.Offset++] = (byte)(value >> 8);
|
|||
|
this.ByteArray![this.Offset++] = (byte)value;
|
|||
|
}
|
|||
|
|
|||
|
public string? ReadString()
|
|||
|
{
|
|||
|
int length = this.ReadInt();
|
|||
|
if (length > -1)
|
|||
|
{
|
|||
|
if (length >= 900001)
|
|||
|
{
|
|||
|
Debugger.Error("Too long String encountered.");
|
|||
|
}
|
|||
|
|
|||
|
string result = LogicStringUtil.CreateString(this.ByteArray!, this.Offset, length);
|
|||
|
|
|||
|
this.Offset += length;
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (length != -1)
|
|||
|
Debugger.Error("Negative String length encountered.");
|
|||
|
}
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
public override void WriteBoolean(bool value)
|
|||
|
{
|
|||
|
base.WriteBoolean(value);
|
|||
|
|
|||
|
if (this.BitIndex == 0)
|
|||
|
{
|
|||
|
this.EnsureCapacity(1);
|
|||
|
this.ByteArray![this.Offset++] = 0;
|
|||
|
}
|
|||
|
|
|||
|
if (value)
|
|||
|
this.ByteArray![this.Offset - 1] |= (byte)(1 << this.BitIndex);
|
|||
|
|
|||
|
this.BitIndex = (this.BitIndex + 1) & 7;
|
|||
|
}
|
|||
|
|
|||
|
public bool ReadBoolean()
|
|||
|
{
|
|||
|
if (this.BitIndex == 0)
|
|||
|
++this.Offset;
|
|||
|
|
|||
|
bool value = (this.ByteArray![this.Offset - 1] & (1 << this.BitIndex)) != 0;
|
|||
|
this.BitIndex = (this.BitIndex + 1) & 7;
|
|||
|
return value;
|
|||
|
}
|
|||
|
|
|||
|
public override void WriteInt(int value)
|
|||
|
{
|
|||
|
base.WriteInt(value);
|
|||
|
this.WriteIntToByteArray(value);
|
|||
|
}
|
|||
|
|
|||
|
public override void WriteByte(byte value)
|
|||
|
{
|
|||
|
base.WriteByte(value);
|
|||
|
this.EnsureCapacity(1);
|
|||
|
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
this.ByteArray![this.Offset++] = (byte)value;
|
|||
|
}
|
|||
|
|
|||
|
public override void WriteShort(short value)
|
|||
|
{
|
|||
|
base.WriteShort(value);
|
|||
|
this.EnsureCapacity(2);
|
|||
|
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
this.ByteArray![this.Offset++] = (byte)(value >> 8);
|
|||
|
this.ByteArray[this.Offset++] = (byte)value;
|
|||
|
}
|
|||
|
|
|||
|
public int ReadInt()
|
|||
|
{
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
return (this.ByteArray![this.Offset++] << 24) |
|
|||
|
(this.ByteArray[this.Offset++] << 16) |
|
|||
|
(this.ByteArray[this.Offset++] << 8) |
|
|||
|
this.ByteArray[this.Offset++];
|
|||
|
}
|
|||
|
|
|||
|
public byte ReadByte()
|
|||
|
{
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
return this.ByteArray![this.Offset++];
|
|||
|
}
|
|||
|
|
|||
|
public short ReadShort()
|
|||
|
{
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
return (short)((this.ByteArray![this.Offset++] << 8) |
|
|||
|
this.ByteArray[this.Offset++]);
|
|||
|
}
|
|||
|
|
|||
|
public LogicLong ReadLong()
|
|||
|
{
|
|||
|
return this.ReadLong(null);
|
|||
|
}
|
|||
|
|
|||
|
public LogicLong ReadLong(LogicLong? logicLong)
|
|||
|
{
|
|||
|
LogicLong? v2 = logicLong;
|
|||
|
if (logicLong == null)
|
|||
|
v2 = new LogicLong();
|
|||
|
|
|||
|
v2!.Decode(this);
|
|||
|
|
|||
|
return v2;
|
|||
|
}
|
|||
|
|
|||
|
public override void WriteBytes(byte[]? value, int length)
|
|||
|
{
|
|||
|
base.WriteBytes(value, length);
|
|||
|
|
|||
|
if (value == null)
|
|||
|
{
|
|||
|
this.WriteIntToByteArray(-1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
this.EnsureCapacity(length + 4);
|
|||
|
this.WriteIntToByteArray(length);
|
|||
|
|
|||
|
Buffer.BlockCopy(value, 0, this.ByteArray!, this.Offset, length);
|
|||
|
|
|||
|
this.Offset += length;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public int ReadBytesLength()
|
|||
|
{
|
|||
|
return this.ReadInt();
|
|||
|
}
|
|||
|
|
|||
|
public byte[]? ReadBytes(int length)
|
|||
|
{
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
if (length > -1)
|
|||
|
{
|
|||
|
byte[] array = new byte[length];
|
|||
|
Buffer.BlockCopy(this.ByteArray!, this.Offset, array, 0, length);
|
|||
|
this.Offset += length;
|
|||
|
return array;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (length != -1)
|
|||
|
Debugger.Error("Negative readBytes length encountered.");
|
|||
|
}
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
public void SetByteArray(byte[] byteArray, int length)
|
|||
|
{
|
|||
|
this.Offset = 0;
|
|||
|
this.Length = length;
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
this.ByteArray = byteArray;
|
|||
|
}
|
|||
|
|
|||
|
public override void Destruct()
|
|||
|
{
|
|||
|
this.Offset = 0;
|
|||
|
this.Length = 0;
|
|||
|
this.BitIndex = 0;
|
|||
|
|
|||
|
this.ByteArray = null;
|
|||
|
}
|
|||
|
|
|||
|
public bool IsAtEnd()
|
|||
|
{
|
|||
|
return this.Offset >= this.Length;
|
|||
|
}
|
|||
|
|
|||
|
public byte GetDataPointer()
|
|||
|
{
|
|||
|
return this.ByteArray![this.Offset];
|
|||
|
}
|
|||
|
|
|||
|
private void EnsureCapacity(int capacity)
|
|||
|
{
|
|||
|
int bufferLength = this.ByteArray!.Length;
|
|||
|
|
|||
|
if (this.Offset + capacity > bufferLength)
|
|||
|
{
|
|||
|
byte[] tmpBuffer = new byte[this.ByteArray.Length + capacity + 100];
|
|||
|
Buffer.BlockCopy(this.ByteArray, 0, tmpBuffer, 0, bufferLength);
|
|||
|
this.ByteArray = tmpBuffer;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|