using Qrakhen.Qamp.Core.Collections; using Qrakhen.Qamp.Core.Values; namespace Qrakhen.Qamp.Core.Execution; using Unsigned = ulong; using Signed = long; using Char = char; using Byte = byte; using Bool = bool; using Decimal = double; public class Segment( IEnumerable instructions, IEnumerable constants) : ISerialize { public readonly FixedArray Instructions = new(instructions); public readonly FixedArray Constants = new(constants); public byte Read(long offset) => Instructions[offset]; public byte[] Read(long offset, int length) { ArgumentOutOfRangeException.ThrowIfGreaterThan(offset + length, Instructions.Length); byte[] bytes = new byte[length]; for (int i = 0; i < length; i++) bytes[i] = Instructions[offset + i]; return bytes; } /// /// Although this always returns a long, the actually stored data in the instruction set has a dynamic width (anything between 1 and 8 bytes) /// /// /// public long ReadDynamic(long offset, out byte length) { length = (byte)(Read(offset) ^ 0x80); byte[] bytes = new byte[8]; for (int i = 0; i < length; i++) { bytes[i] = Instructions[offset + 1 + i]; } return bytes.ToInt64(); } public short ReadShort(long offset) => BitConverter.ToInt16(Read(offset, 2)); public int ReadInt(long offset) => BitConverter.ToInt32(Read(offset, 4)); public long ReadLong(long offset) => BitConverter.ToInt64(Read(offset, 8)); public byte[] Serialize() { var opCodes = Instructions.Select(i => (byte)i).ToArray(); var constants = Constants.Select(c => c.Unsigned.GetBytes()).ToArray(); byte[] bytes = new byte[sizeof(long) * 2 + opCodes.Length + constants.Length * 8]; Array.Copy(opCodes.LongLength.GetBytes(), 0, bytes, 0, sizeof(long)); Array.Copy((constants.LongLength * sizeof(long)).GetBytes(), 0, bytes, sizeof(long), sizeof(long)); int offset = sizeof(long) * 2; for (long i = 0; i < opCodes.LongLength; i++) { bytes[offset++] = opCodes[i]; } for (long i = 0; i < constants.LongLength; i++) { for (int j = 0; j < sizeof(long); j++) { bytes[offset++] = constants[i][j]; } } return bytes; } public static Segment Deserialize(byte[] data) { return null; } }