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; } } }