74 lines
2.6 KiB
C#
74 lines
2.6 KiB
C#
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<Instruction> instructions,
|
|
IEnumerable<Value> constants) : ISerialize<Segment>
|
|
{
|
|
public readonly FixedArray<Instruction> Instructions = new(instructions);
|
|
public readonly FixedArray<Value> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Although this always returns a long, the actually stored data in the instruction set has a dynamic width (anything between 1 and 8 bytes)
|
|
/// </summary>
|
|
/// <param name="offset"></param>
|
|
/// <returns></returns>
|
|
public long ReadDynamic(long offset, out byte length)
|
|
{
|
|
length = Read(offset, 1)[0];
|
|
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;
|
|
}
|
|
}
|