using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace InABox.DigitalMatter { public class DMBuffer { public byte[] Buffer { get => _buffer.ToArray(); set => _buffer = value.ToList(); } public ushort BufferSize => (ushort)_buffer.Count; public virtual void Reset() { _buffer = new List(); } public ushort AddByte(byte value) { return Add(new[] { value }); } public ushort AddBytes(byte[] value) { return Add(value); } public ushort AddInt8(sbyte value) { return Add(BitConverter.GetBytes(value)); } public ushort AddUInt16(ushort value) { return Add(BitConverter.GetBytes(value)); } public ushort AddInt16(short value) { return Add(BitConverter.GetBytes(value)); } public ushort AddUInt32(uint value) { return Add(BitConverter.GetBytes(value)); } public ushort AddInt32(int value) { return Add(BitConverter.GetBytes(value)); } public ushort AddString(string value, int length) { return Add(FixedLengthString(value, length)); } public ushort InsertByte(int index, byte value) { return Insert(index, new[] { value }); } public ushort InsertBytes(int index, byte[] value) { return Insert(index, value); } public ushort InsertInt8(int index, sbyte value) { return Insert(index, BitConverter.GetBytes(value)); } public ushort InsertUInt16(int index, ushort value) { return Insert(index, BitConverter.GetBytes(value)); } public ushort InsertInt16(int index, short value) { return Insert(index, BitConverter.GetBytes(value)); } public ushort InsertUInt32(int index, uint value) { return Insert(index, BitConverter.GetBytes(value)); } public ushort InsertInt32(int index, int value) { return Insert(index, BitConverter.GetBytes(value)); } public ushort InsertString(int index, string value, int length) { return Insert(index, FixedLengthString(value, length)); } public byte PeekByte(int index) { return Peek(index, sizeof(byte)).First(); } public byte[] PeekBytes(int index, int length) { return Peek(index, length); } public sbyte PeekInt8(int index) { return unchecked((sbyte)PeekByte(index)); //hmmm... } public ushort PeekUInt16(int index) { return BitConverter.ToUInt16(Peek(index, sizeof(ushort)), 0); } public short PeekInt16(int index) { return BitConverter.ToInt16(Peek(index, sizeof(short)), 0); } public uint PeekUInt32(int index) { return BitConverter.ToUInt32(Peek(index, sizeof(uint)), 0); } public int PeekInt32(int index) { return BitConverter.ToInt32(Peek(index, sizeof(int)), 0); } public string PeekString(int index, int length) { return Encoding.Default.GetString(Peek(index, length)).Trim(); } public byte TakeByte(int index) { return Take(index, sizeof(byte)).First(); } public byte[] TakeBytes(int index, int length) { return Take(index, length); } public sbyte TakeInt8(int index) { return unchecked((sbyte)TakeByte(index)); //hmmm... } public ushort TakeUInt16(int index) { return BitConverter.ToUInt16(Take(index, sizeof(ushort)), 0); } public short TakeInt16(int index) { return BitConverter.ToInt16(Take(index, sizeof(short)), 0); } public uint TakeUInt32(int index) { return BitConverter.ToUInt32(Take(index, sizeof(uint)), 0); } public int TakeInt32(int index) { return BitConverter.ToInt32(Take(index, sizeof(int)), 0); } public string TakeString(int index, int length) { return Encoding.Default.GetString(Take(index, length)).Trim(); } public byte TakeByte() { return TakeByte(0); } public byte[] TakeBytes(int length) { return TakeBytes(0, length); } public sbyte TakeInt8() { return TakeInt8(0); //hmmm... } public ushort TakeUInt16() { return TakeUInt16(0); } public short TakeInt16() { return TakeInt16(0); } public uint TakeUInt32() { return TakeUInt32(0); } public int TakeInt32() { return TakeInt32(0); } public string TakeString(int length) { return TakeString(0, length); } #region Private Members private List _buffer = new(); private ushort Add(byte[] bytes) { _buffer.AddRange(bytes); return BufferSize; } private ushort Insert(int index, byte[] bytes) { _buffer.InsertRange(index, bytes); return BufferSize; } private byte[] Peek(int index, int length) { return _buffer.Skip(index).Take(length).ToArray(); } private byte[] Take(int index, int length) { var result = Peek(index, length); _buffer.RemoveRange(index, length); return result; } private byte[] FixedLengthString(string value, int length) { var result = Encoding.Default.GetBytes(value).ToList(); while (result.Count < length) result.Add(0x00); return result.ToArray(); } private bool[] DecodeBits(byte[] value, int index, int length) { var result = new List(); var array = new BitArray(value); for (var i = index; i < index + length && i < array.Count; i++) result.Add(array[i]); return result.ToArray(); } private byte[] EncodeBits(byte[] source, int index, bool[] bits) { var array = new BitArray(source); for (var i = 0; i < bits.Length; i++) array.Set(index + i, bits[i]); var result = new byte[source.Length]; array.CopyTo(result, 0); return result; } #endregion #region Bit Manipulation public bool[] GetBits(byte[] value, int index, int length) { return DecodeBits(value, index, length); } public byte[] SetBits(byte[] value, int index, bool[] bits) { return EncodeBits(value, index, bits); } public bool[] DecodeByte(byte value, int index, int length) { return DecodeBits(new[] { value }, index, length); } public bool[] DecodeBytes(byte[] value, int index, int length) { return DecodeBits(value, index, length); } public bool[] DecodeInt8(sbyte value, int index, int length) { return DecodeBits(new[] { Convert.ToByte(value) }, index, length); } public bool[] DecodeInt16(short value, int index, int length) { return DecodeBits(BitConverter.GetBytes(value), index, length); } public bool[] DecodeUInt16(ushort value, int index, int length) { return DecodeBits(BitConverter.GetBytes(value), index, length); } public bool[] DecodeInt32(int value, int index, int length) { return DecodeBits(BitConverter.GetBytes(value), index, length); } public bool[] DecodeUInt32(uint value, int index, int length) { return DecodeBits(BitConverter.GetBytes(value), index, length); } public byte EncodeByte(bool[] bits) { return EncodeBits(new byte[] { default }, 0, bits).First(); } public byte[] EncodeBytes(bool[] bits, int size) { return EncodeBits(Array.CreateInstance(typeof(byte), size).OfType().ToArray(), 0, bits); } public sbyte EncodeInt8(bool[] bits) { return Convert.ToSByte(EncodeBits(new[] { Convert.ToByte(default(sbyte)) }, 0, bits).First()); } public short EncodeInt16(bool[] bits) { return BitConverter.ToInt16(EncodeBits(BitConverter.GetBytes(default(short)), 0, bits), 0); } public ushort EncodeUInt16(bool[] bits) { return BitConverter.ToUInt16(EncodeBits(BitConverter.GetBytes(default(ushort)), 0, bits), 0); } public int EncodeInt32(bool[] bits) { return BitConverter.ToInt32(EncodeBits(BitConverter.GetBytes(default(int)), 0, bits), 0); } public uint EncodeUInt32(bool[] bits) { return BitConverter.ToUInt32(EncodeBits(BitConverter.GetBytes(default(uint)), 0, bits), 0); } public byte UpdateByte(byte value, int index, bool[] bits) { return EncodeBits(new[] { value }, index, bits).First(); } public byte[] UpdateBytes(byte[] value, int index, bool[] bits, int size) { return EncodeBits(value, 0, bits); } public sbyte UpdateInt8(sbyte value, int index, bool[] bits) { return Convert.ToSByte(EncodeBits(new[] { Convert.ToByte(value) }, 0, bits).First()); } public short UpdateInt16(short value, int index, bool[] bits) { return BitConverter.ToInt16(EncodeBits(BitConverter.GetBytes(value), 0, bits), 0); } public ushort UpdateUInt16(ushort value, int index, bool[] bits) { return BitConverter.ToUInt16(EncodeBits(BitConverter.GetBytes(value), 0, bits), 0); } public int UpdateInt32(int value, int index, bool[] bits) { return BitConverter.ToInt32(EncodeBits(BitConverter.GetBytes(value), 0, bits), 0); } public uint UpdateUInt32(uint value, int index, bool[] bits) { return BitConverter.ToUInt32(EncodeBits(BitConverter.GetBytes(value), 0, bits), 0); } #endregion } }