using System; using System.IO; using System.Text; using System.Linq; using System.IO.Compression; using System.Collections.Generic; public class ByteLayer { private byte[] _byteBuffer; private int _position; public ByteLayer() { _byteBuffer = new byte[0]; _position = 0; } public int Length => _byteBuffer.Length; public int CurrentPosition => _position; public byte[] Bytes => _byteBuffer.Take(_position).ToArray(); private void EnsureCapacity(int additionalBytes) { int requiredCapacity = _position + additionalBytes; if (requiredCapacity > _byteBuffer.Length) { Array.Resize(ref _byteBuffer, requiredCapacity); } } public void WriteInt(int value) { EnsureCapacity(4); Array.Copy(BitConverter.GetBytes(value), 0, _byteBuffer, _position, 4); if (BitConverter.IsLittleEndian) Array.Reverse(_byteBuffer, _position, 4); _position += 4; } public int ReadInt() { if (_position + 4 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); var value = _byteBuffer.Skip(_position).Take(4).ToArray(); if (BitConverter.IsLittleEndian) Array.Reverse(value); _position += 4; return BitConverter.ToInt32(value, 0); } public void WriteDouble(double value) { EnsureCapacity(8); var bytes = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) Array.Reverse(bytes); Array.Copy(bytes, 0, _byteBuffer, _position, 8); _position += 8; } public double ReadDouble() { if (_position + 8 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); var value = _byteBuffer.Skip(_position).Take(8).ToArray(); if (BitConverter.IsLittleEndian) Array.Reverse(value); _position += 8; return BitConverter.ToDouble(value, 0); } public void WriteFloat(float value) { EnsureCapacity(4); var bytes = BitConverter.GetBytes(value); if(BitConverter.IsLittleEndian) Array.Reverse(bytes); Array.Copy(bytes, 0, _byteBuffer, _position, 4); _position += 4; } public float ReadFloat() { if (_position + 4 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); var value = _byteBuffer.Skip(_position).Take(4).ToArray(); if (BitConverter.IsLittleEndian) Array.Reverse(value); _position += 4; return BitConverter.ToSingle(value, 0); } public void WriteString(string value) { var encoded = Encoding.UTF8.GetBytes(value); WriteShort((short)encoded.Length); EnsureCapacity(encoded.Length); Array.Copy(encoded, 0, _byteBuffer, _position, encoded.Length); _position += encoded.Length; } public string ReadString() { int length = ReadShort(); if (_position + length > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); var value = Encoding.UTF8.GetString(_byteBuffer, _position, length); _position += length; return value; } public void WriteShort(short value) { EnsureCapacity(2); var bytes = BitConverter.GetBytes((short)value); if (BitConverter.IsLittleEndian) Array.Reverse(bytes); Array.Copy(bytes, 0, _byteBuffer, _position, 2); _position += 2; } public short ReadShort() { if (_position + 2 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); var value = _byteBuffer.Skip(_position).Take(2).ToArray(); if (BitConverter.IsLittleEndian) Array.Reverse(value); _position += 2; return BitConverter.ToInt16(value, 0); } public void WriteByte(byte value) { EnsureCapacity(1); _byteBuffer[_position] = value; _position++; } public void WriteBytes(List bytes) { EnsureCapacity(bytes.Count); Array.Copy(bytes.ToArray(), 0, _byteBuffer, _position, bytes.Count); _position += bytes.Count; } public byte ReadByte() { if (_position >= _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); return _byteBuffer[_position++]; } public void ResetPosition() => _position = 0; public void RestorePosition(int position) { if (position < 0 || position > _byteBuffer.Length) throw new ArgumentOutOfRangeException(nameof(position)); _position = position; } public void Clear() { _position = 0; _byteBuffer = new byte[0]; } public void WriteToFile(string filePath) { File.WriteAllBytes(filePath, Bytes); } public void ReadFromFile(string filePath) { if (!File.Exists(filePath)) throw new FileNotFoundException("File does not exist.", filePath); _byteBuffer = File.ReadAllBytes(filePath); ResetPosition(); } public void Compress() { using var memoryStream = new MemoryStream(); using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress)) { gzipStream.Write(_byteBuffer, 0, _byteBuffer.Length); } _byteBuffer = memoryStream.ToArray(); _position = _byteBuffer.Length; } public void Decompress() { using var memoryStream = new MemoryStream(_byteBuffer); using var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress); using var decompressedStream = new MemoryStream(); gzipStream.CopyTo(decompressedStream); _byteBuffer = decompressedStream.ToArray(); _position = _byteBuffer.Length; } public void WriteVarInt(int value) { while ((value & ~0x7F) != 0) { WriteByte((byte)((value & 0x7F) | 0x80)); value >>= 7; } WriteByte((byte)(value & 0x7F)); } public int ReadVarInt() { int result = 0; int shift = 0; int byteRead; do { byteRead = ReadByte(); result |= (byteRead & 0x7F) << shift; shift += 7; } while ((byteRead & 0x80) != 0); return result; } public void WriteVarIntNoZigZag(int value) { while ((value & ~0x7F) != 0) { WriteByte((byte)((value & 0x7F) | 0x80)); value >>= 7; } WriteByte((byte)(value & 0x7F)); } public int ReadVarIntNoZigZag() { int result = 0; int shift = 0; int byteRead; do { byteRead = ReadByte(); result |= (byteRead & 0x7F) << shift; shift += 7; } while ((byteRead & 0x80) != 0); return result; } public void WriteLong(long value) { EnsureCapacity(8); Array.Copy(BitConverter.GetBytes(value), 0, _byteBuffer, _position, 8); if (BitConverter.IsLittleEndian) Array.Reverse(_byteBuffer, _position, 8); _position += 8; } public long ReadLong() { if (_position + 8 > _byteBuffer.Length) throw new InvalidOperationException("Buffer overflow."); var value = _byteBuffer.Skip(_position).Take(8).ToArray(); if (BitConverter.IsLittleEndian) Array.Reverse(value); _position += 8; return BitConverter.ToInt64(value, 0); } public void WriteVarLongZigZag(long value) { value = (value << 1) ^ (value >> 63); WriteVarLongNoZigZag(value); } public void WriteVarLongNoZigZag(long value) { while ((value & ~0x7F) != 0) { WriteByte((byte)((value & 0x7F) | 0x80)); value >>= 7; } WriteByte((byte)(value & 0x7F)); } public long ReadVarLongZigZag() { long result = ReadVarLongNoZigZag(); return (result >> 1) ^ -(result & 1); } public long ReadVarLongNoZigZag() { long result = 0; int shift = 0; int byteRead; do { byteRead = ReadByte(); result |= (byteRead & 0x7F) << shift; shift += 7; } while ((byteRead & 0x80) != 0); return result; } public void SetBit(int position, byte maskToSet) { if (position < _byteBuffer.Length) { Seek(position); byte current = ReadByte(); Seek(position); current |= maskToSet; WriteByte(current); } } public void ClearBit(int position, byte maskToClear) { if (position < _byteBuffer.Length) { Seek(position); byte current = ReadByte(); current &= (byte)~maskToClear; Seek(position); WriteByte(current); } } public bool CheckBit(int position, byte mask) { if (position < _byteBuffer.Length) { Seek(position); byte current = ReadByte(); return (current & mask) == mask; } return false; } public byte GetBit(int position) { if (position < _byteBuffer.Length) { Seek(position); return ReadByte(); } return 0; } public void Seek(int position) { if (position < 0 || position > _byteBuffer.Length) throw new ArgumentOutOfRangeException(nameof(position)); _position = position; } public void InsertRandomBytes(int count) { Random rng = new Random(); for (int i = 0; i < count; i++) { WriteByte((byte)rng.Next(256)); } } }