2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-10-30 15:41:35 +00:00

Pull Stream

This commit is contained in:
2025-10-30 12:45:29 +03:00
parent a63a9b5511
commit 746f12320e
25 changed files with 1637 additions and 704 deletions

View File

@@ -381,7 +381,7 @@ public static class Codec
ComposeInternal(object valueOrSource, Warehouse warehouse, DistributedConnection connection)
{
if (valueOrSource == null)
return new TDU(TDUIdentifier.Null);
return new TDU(TDUIdentifier.Null, null, 0);
var type = valueOrSource.GetType();
@@ -408,7 +408,7 @@ public static class Codec
valueOrSource = ((IUserType)valueOrSource).Get();
if (valueOrSource == null)
return new TDU(TDUIdentifier.Null);
return new TDU(TDUIdentifier.Null, null, 0);
type = valueOrSource.GetType();
@@ -484,7 +484,7 @@ public static class Codec
}
return new TDU(TDUIdentifier.Null);
return new TDU(TDUIdentifier.Null, null, 0);
}

View File

@@ -36,11 +36,15 @@ using System.Reflection;
using Esiur.Data;
using Esiur.Core;
using Esiur.Resource;
using System.Collections;
using Esiur.Data.GVWIE;
namespace Esiur.Data;
public static class DC // Data Converter
{
public static object CastConvert(object value, Type destinationType)
{
if (value == null)

View File

@@ -1,5 +1,6 @@
using Esiur.Core;
using Esiur.Data;
using Esiur.Data.GVWIE;
using Esiur.Misc;
using Esiur.Net.IIP;
using Esiur.Resource;
@@ -742,8 +743,8 @@ public static class DataDeserializer
{
// get key type
var (keyCs, keyRepType) = RepresentationType.Parse(tdu.Metadata, 0);
var (valueCs, valueRepType) = RepresentationType.Parse(tdu.Metadata, keyCs);
var (keyCs, keyRepType) = TRU.Parse(tdu.Metadata, 0);
var (valueCs, valueRepType) = TRU.Parse(tdu.Metadata, keyCs);
var wh = connection.Instance.Warehouse;
@@ -792,8 +793,8 @@ public static class DataDeserializer
{
// get key type
var (keyCs, keyRepType) = RepresentationType.Parse(tdu.Metadata, 0);
var (valueCs, valueRepType) = RepresentationType.Parse(tdu.Metadata, keyCs);
var (keyCs, keyRepType) = TRU.Parse(tdu.Metadata, 0);
var (valueCs, valueRepType) = TRU.Parse(tdu.Metadata, keyCs);
var map = (IMap)Activator.CreateInstance(typeof(Map<,>).MakeGenericType(keyRepType.GetRuntimeType(warehouse), valueRepType.GetRuntimeType(warehouse)));
@@ -838,7 +839,7 @@ public static class DataDeserializer
uint mtOffset = 1;
for (var i = 0; i < tupleSize; i++)
{
var (cs, rep) = RepresentationType.Parse(tdu.Metadata, mtOffset);
var (cs, rep) = TRU.Parse(tdu.Metadata, mtOffset);
types.Add(rep.GetRuntimeType(connection.Instance.Warehouse));
mtOffset += cs;
}
@@ -913,7 +914,7 @@ public static class DataDeserializer
uint mtOffset = 1;
for (var i = 0; i < tupleSize; i++)
{
var (cs, rep) = RepresentationType.Parse(tdu.Metadata, mtOffset);
var (cs, rep) = TRU.Parse(tdu.Metadata, mtOffset);
types.Add(rep.GetRuntimeType(warehouse));
mtOffset += cs;
}
@@ -975,111 +976,152 @@ public static class DataDeserializer
public static AsyncReply TypedListParserAsync(ParsedTDU tdu, DistributedConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<object>();
// get the type
var (hdrCs, rep) = RepresentationType.Parse(tdu.Metadata, 0);
var (hdrCs, rep) = TRU.Parse(tdu.Metadata, 0);
var runtimeType = rep.GetRuntimeType(connection.Instance.Warehouse);
rt.ArrayType = runtimeType;
ParsedTDU current;
ParsedTDU? previous = null;
var offset = tdu.Offset;
var length = tdu.ContentLength;
var ends = offset + (uint)length;
while (length > 0)
switch (rep.Identifier)
{
case TRUIdentifier.Int32:
return new AsyncReply(GroupInt32Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength)));
case TRUIdentifier.Int64:
return new AsyncReply(GroupInt64Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength)));
case TRUIdentifier.Int16:
return new AsyncReply(GroupInt16Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength)));
case TRUIdentifier.UInt32:
return new AsyncReply(GroupUInt32Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength)));
case TRUIdentifier.UInt64:
return new AsyncReply(GroupUInt64Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength)));
case TRUIdentifier.UInt16:
return new AsyncReply(GroupUInt16Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength)));
default:
current = ParsedTDU.Parse(tdu.Data, offset, ends);
var rt = new AsyncBag<object>();
if (current.Class == TDUClass.Invalid)
throw new Exception("Unknown type.");
var runtimeType = rep.GetRuntimeType(connection.Instance.Warehouse);
rt.ArrayType = runtimeType;
ParsedTDU current;
ParsedTDU? previous = null;
var offset = tdu.Offset;
var length = tdu.ContentLength;
var ends = offset + (uint)length;
while (length > 0)
{
current = ParsedTDU.Parse(tdu.Data, offset, ends);
if (current.Class == TDUClass.Invalid)
throw new Exception("Unknown type.");
if (current.Identifier == TDUIdentifier.TypeContinuation)
{
current.Class = previous.Value.Class;
current.Identifier = previous.Value.Identifier;
current.Metadata = previous.Value.Metadata;
}
if (current.Identifier == TDUIdentifier.TypeContinuation)
{
current.Class = previous.Value.Class;
current.Identifier = previous.Value.Identifier;
current.Metadata = previous.Value.Metadata;
}
var (cs, reply) = Codec.ParseAsync(tdu.Data, offset, connection, requestSequence);
var (cs, reply) = Codec.ParseAsync(tdu.Data, offset, connection, requestSequence);
rt.Add(reply);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
rt.Seal();
return rt;
}
rt.Seal();
return rt;
}
public static object TypedListParser(ParsedTDU tdu, Warehouse warehouse)
{
// get the type
var (hdrCs, rep) = RepresentationType.Parse(tdu.Metadata, 0);
var (hdrCs, rep) = TRU.Parse(tdu.Metadata, 0);
//offset += hdrCs;
//length -= hdrCs;
var runtimeType = rep.GetRuntimeType(warehouse);
var list = new List<object>();
ParsedTDU current;
ParsedTDU? previous = null;
var offset = tdu.Offset;
var length = tdu.ContentLength;
var ends = offset + (uint)length;
while (length > 0)
switch (rep.Identifier)
{
current = ParsedTDU.Parse(tdu.Data, offset, ends);
if (current.Class == TDUClass.Invalid)
throw new Exception("Unknown type.");
case TRUIdentifier.Int32:
return GroupInt32Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength));
case TRUIdentifier.Int64:
return GroupInt64Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength));
case TRUIdentifier.Int16:
return GroupInt16Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength));
case TRUIdentifier.UInt32:
return GroupUInt32Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength));
case TRUIdentifier.UInt64:
return GroupUInt64Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength));
case TRUIdentifier.UInt16:
return GroupUInt16Codec.Decode(tdu.Data.AsSpan(
(int)tdu.Offset, (int)tdu.ContentLength));
default:
if (current.Identifier == TDUIdentifier.TypeContinuation)
{
current.Class = previous.Value.Class;
current.Identifier = previous.Value.Identifier;
current.Metadata = previous.Value.Metadata;
}
var list = new List<object>();
var (cs, reply) = Codec.ParseSync(current, warehouse);
ParsedTDU current;
ParsedTDU? previous = null;
list.Add(reply);
var offset = tdu.Offset;
var length = tdu.ContentLength;
var ends = offset + (uint)length;
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
previous = current;
}
else
throw new Exception("Error while parsing structured data");
while (length > 0)
{
current = ParsedTDU.Parse(tdu.Data, offset, ends);
if (current.Class == TDUClass.Invalid)
throw new Exception("Unknown type.");
if (current.Identifier == TDUIdentifier.TypeContinuation)
{
current.Class = previous.Value.Class;
current.Identifier = previous.Value.Identifier;
current.Metadata = previous.Value.Metadata;
}
var (cs, reply) = Codec.ParseSync(current, warehouse);
list.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
previous = current;
}
else
throw new Exception("Error while parsing structured data");
}
var runtimeType = rep.GetRuntimeType(warehouse);
var rt = Array.CreateInstance(runtimeType, list.Count);
Array.Copy(list.ToArray(), rt, rt.Length);
return rt;
}
var rt = Array.CreateInstance(runtimeType, list.Count);
Array.Copy(list.ToArray(), rt, rt.Length);
return rt;
}
public static AsyncBag<PropertyValue> PropertyValueArrayParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)

View File

@@ -1,4 +1,5 @@
using Esiur.Core;
using Esiur.Data.GVWIE;
using Esiur.Net.IIP;
using Esiur.Resource;
using Esiur.Resource.Template;
@@ -112,7 +113,7 @@ public static class DataSerializer
}
public static unsafe TDU Float32Composer(object value, Warehouse warehouse, DistributedConnection connection)
public static unsafe TDU Float32Composer(object value, Warehouse warehouse, DistributedConnection connection)
{
float v = (float)value;
@@ -404,6 +405,7 @@ public static class DataSerializer
if (ct == null)
return new TDU(TDUIdentifier.Null, null, 0);
return Codec.ComposeInternal(intVal, warehouse, connection);
return new TDU(TDUIdentifier.TypedEnum,
new byte[] { ct.Index }, 1, template.ClassId.Data);
@@ -442,18 +444,18 @@ public static class DataSerializer
{
if ((bool)value)
{
return new TDU(TDUIdentifier.True);
return new TDU(TDUIdentifier.True, null, 0);
}
else
{
return new TDU(TDUIdentifier.True);
return new TDU(TDUIdentifier.True, null, 0);
}
}
public static TDU NotModifiedComposer(object value, Warehouse warehouse, DistributedConnection connection)
{
return new TDU(TDUIdentifier.NotModified);
return new TDU(TDUIdentifier.NotModified, null, 0);
}
public static TDU RawDataComposerFromArray(object value, Warehouse warehouse, DistributedConnection connection)
@@ -492,16 +494,85 @@ public static class DataSerializer
public static TDU TypedListComposer(IEnumerable value, Type type, Warehouse warehouse, DistributedConnection connection)
{
var composed = ArrayComposer((IEnumerable)value, warehouse, connection);
byte[] composed;
if (value == null)
return new TDU(TDUIdentifier.Null, new byte[0], 0);
var tru = TRU.FromType(type);
if (type == typeof(int))
{
composed = GroupInt32Codec.Encode((IList<int>)value);
}
else if (type == typeof(long))
{
composed = GroupInt64Codec.Encode((IList<long>)value);
}
else if (type == typeof(short))
{
composed = GroupInt16Codec.Encode((IList<short>)value);
}
else if (type == typeof(uint))
{
composed = GroupUInt32Codec.Encode((IList<uint>)value);
}
else if (type == typeof(ulong))
{
composed = GroupUInt64Codec.Encode((IList<ulong>)value);
}
else if (type == typeof(ushort))
{
composed = GroupUInt16Codec.Encode((IList<ushort>)value);
}
else
{
var rt = new List<byte>();
TDU? previous = null;
foreach (var i in value)
{
var tdu = Codec.ComposeInternal(i, warehouse, connection);
var currentTru = TRU.FromType(i.GetType());
if (tru.Match(currentTru))
{
var d = tdu.Composed.Clip(tdu.ContentOffset,
(uint)tdu.Composed.Length - tdu.ContentOffset);
var ntd = new TDU(TDUIdentifier.TypeOfTarget, d, (ulong)d.Length);
rt.AddRange(ntd.Composed);
}
else
if (previous != null && tdu.MatchType(previous.Value))
{
var d = tdu.Composed.Clip(tdu.ContentOffset,
(uint)tdu.Composed.Length - tdu.ContentOffset);
var ntd = new TDU(TDUIdentifier.TypeContinuation, d, (ulong)d.Length);
rt.AddRange(ntd.Composed);
}
else
{
rt.AddRange(tdu.Composed);
}
previous = tdu;
}
composed = rt.ToArray();
}
if (composed == null)
return new TDU(TDUIdentifier.Null, new byte[0], 0);
var metadata = RepresentationType.FromType(type).Compose();
var metadata = tru.Compose();
return new TDU(TDUIdentifier.TypedList, composed,
(uint)composed.Length, metadata);
return new TDU(TDUIdentifier.TypedList, composed, (uint)composed.Length, metadata);
}
//public static byte[] PropertyValueComposer(PropertyValue propertyValue, DistributedConnection connection)//, bool includeAge = true)
@@ -539,8 +610,8 @@ public static class DataSerializer
if (value == null)
return new TDU(TDUIdentifier.Null, new byte[0], 0);
var kt = RepresentationType.FromType(keyType).Compose();
var vt = RepresentationType.FromType(valueType).Compose();
var kt = TRU.FromType(keyType).Compose();
var vt = TRU.FromType(valueType).Compose();
var rt = new List<byte>();
@@ -558,8 +629,8 @@ public static class DataSerializer
if (value == null)
return new TDU(TDUIdentifier.Null, null, 0);
var kt = RepresentationType.FromType(keyType).Compose();
var vt = RepresentationType.FromType(valueType).Compose();
var kt = TRU.FromType(keyType).Compose();
var vt = TRU.FromType(valueType).Compose();
var rt = new List<byte>();
@@ -583,7 +654,7 @@ public static class DataSerializer
DC.Combine(kt, 0, (uint)kt.Length, vt, 0, (uint)vt.Length));
}
public static byte[] ArrayComposer(IEnumerable value, Warehouse warehouse, DistributedConnection connection)
public static byte[] DynamicArrayComposer(IEnumerable value, Warehouse warehouse, DistributedConnection connection)
{
if (value == null)
return null;
@@ -727,14 +798,29 @@ public static class DataSerializer
foreach (var pt in template.Properties)
{
var propValue = pt.PropertyInfo.GetValue(record, null);
var rr = Codec.Compose(propValue, warehouse, connection);
rt.AddRange(rr);
if (propValue == null)
return new TDU(TDUIdentifier.Null, null, 0);
var tru = TRU.FromType(propValue.GetType());
var tdu = Codec.ComposeInternal(propValue, warehouse, connection);
if (pt.ValueType.Identifier == TRUIdentifier.TypedRecord && pt.ValueType.Match(tru))
{
// strip metadata
var len = (uint)tdu.Composed.Length - tdu.ContentOffset;
tdu = new TDU(TDUIdentifier.TypeOfTarget,
tdu.Composed.Clip(tdu.ContentOffset, len), len);
}
rt.AddRange(tdu.Composed);
}
return new TDU(TDUIdentifier.Record, rt.ToArray(),
(uint)rt.Count,
template.ClassId.Data);
}
public static byte[] HistoryComposer(KeyList<PropertyTemplate, PropertyValue[]> history, Warehouse warehouse,
DistributedConnection connection, bool prependLength = false)
{
@@ -758,7 +844,7 @@ public static class DataSerializer
var fields = value.GetType().GetFields();
var list = fields.Select(x => x.GetValue(value)).ToArray();
var types = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();
var types = fields.Select(x => TRU.FromType(x.FieldType).Compose()).ToArray();
var metadata = new List<byte>();

View File

@@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Esiur.Data.GVWIE;
public static class GroupInt16Codec
{
// ----------------- Encoder -----------------
public static byte[] Encode(IList<short> values)
{
var dst = new List<byte>(values.Count); // close lower bound
int i = 0;
while (i < values.Count)
{
ushort zz = ZigZag16(values[i]);
// Fast path: single byte with 7-bit ZigZag
if (zz <= 0x7Fu)
{
dst.Add((byte)zz); // MSB=0 implicitly
i++;
continue;
}
// Group path: up to 64 items sharing width (1 or 2 bytes)
int start = i;
int count = 1;
int width = (zz <= 0xFFu) ? 1 : 2;
while (count < 64 && (i + count) < values.Count)
{
ushort z2 = ZigZag16(values[i + count]);
int w2 = (z2 <= 0xFFu) ? 1 : 2;
if (w2 > width) width = w2; // widen as needed
count++;
}
// Header: 1 | (count-1)[6 bits] | (width-1)[1 bit]
byte header = 0x80;
header |= (byte)(((count - 1) & 0x3F) << 1);
header |= (byte)((width - 1) & 0x01);
dst.Add(header);
// Payload: count ZigZag magnitudes, LE, 'width' bytes each
for (int k = 0; k < count; k++)
{
ushort z = ZigZag16(values[start + k]);
WriteLE(dst, z, width);
}
i += count;
}
return dst.ToArray();
}
// ----------------- Decoder -----------------
public static short[] Decode(ReadOnlySpan<byte> src)
{
var result = new List<short>();
int pos = 0;
while (pos < src.Length)
{
byte h = src[pos++];
if ((h & 0x80) == 0)
{
// Fast path: 7-bit ZigZag
ushort zz7 = (ushort)(h & 0x7F);
result.Add(UnZigZag16(zz7));
continue;
}
int count = ((h >> 1) & 0x3F) + 1; // 1..64
int width = (h & 0x01) + 1; // 1..2
for (int j = 0; j < count; j++)
{
uint raw = ReadLE(src, ref pos, width);
if (width > 2 && (raw >> 16) != 0)
throw new OverflowException("Decoded ZigZag value exceeds 16-bit range.");
ushort u = (ushort)raw;
short val = UnZigZag16(u);
result.Add(val);
}
}
return result.ToArray();
}
// ----------------- Helpers -----------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort ZigZag16(short v)
{
// (v << 1) ^ (v >> 15), result as unsigned 16-bit
return (ushort)(((uint)(ushort)v << 1) ^ (uint)((int)v >> 15));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short UnZigZag16(ushort u)
{
// (u >> 1) ^ -(u & 1), narrowed to 16-bit signed
return (short)((u >> 1) ^ (ushort)-(short)(u & 1));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteLE(List<byte> dst, ushort value, int width)
{
// width is 1 or 2
dst.Add((byte)(value & 0xFF));
if (width == 2) dst.Add((byte)(value >> 8));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint ReadLE(ReadOnlySpan<byte> src, ref int pos, int width)
{
if ((uint)(pos + width) > (uint)src.Length)
throw new ArgumentException("Buffer underflow while reading group payload.");
uint v = src[pos++];
if (width == 2)
{
v |= (uint)src[pos++] << 8;
}
return v;
}
}

View File

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using System.Collections;
namespace Esiur.Data.GVWIE;
public static class GroupInt32Codec
{
// ----------------- Encoder -----------------
public static byte[] Encode(IList<int> values)
{
//var values = value as int[];
var dst = new List<byte>(values.Count * 2);
int i = 0;
while (i < values.Count)
{
uint zz = ZigZag32(values[i]);
// Fast path: single byte (MSB=0) when zigzag fits in 7 bits
if (zz <= 0x7Fu)
{
dst.Add((byte)zz);
i++;
continue;
}
// Group: up to 32 items sharing a common width (1..4 bytes)
int start = i;
int count = 1;
int width = WidthFromZigZag(zz);
while (count < 32 && (i + count) < values.Count)
{
uint z2 = ZigZag32(values[i + count]);
int w2 = WidthFromZigZag(z2);
width = Math.Max(width, w2); // widen as needed
count++;
}
// Header: 1 | (count-1)[5 bits] | (width-1)[2 bits]
byte header = 0x80;
header |= (byte)(((count - 1) & 0x1F) << 2);
header |= (byte)((width - 1) & 0x03);
dst.Add(header);
// Payload: 'count' zigzag values, LE, 'width' bytes each
for (int k = 0; k < count; k++)
WriteLE(dst, ZigZag32(values[start + k]), width);
i += count;
}
return dst.ToArray();
}
// ----------------- Decoder -----------------
public static int[] Decode(ReadOnlySpan<byte> src)
{
var result = new List<int>();
int pos = 0;
while (pos < src.Length)
{
byte h = src[pos++];
if ((h & 0x80) == 0)
{
// Fast path: 7-bit ZigZag in low bits
uint zz7 = (uint)(h & 0x7F);
result.Add(UnZigZag32(zz7));
continue;
}
int count = ((h >> 2) & 0x1F) + 1; // 1..32
int width = (h & 0x03) + 1; // 1..4
for (int j = 0; j < count; j++)
{
uint raw = (uint)ReadLE(src, ref pos, width);
int val = UnZigZag32(raw);
result.Add(val);
}
}
return result.ToArray();
}
// ----------------- Helpers -----------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint ZigZag32(int v) => (uint)((v << 1) ^ (v >> 31));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int UnZigZag32(uint u) => (int)((u >> 1) ^ (uint)-(int)(u & 1));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int WidthFromZigZag(uint z)
{
if (z <= 0xFFu) return 1;
if (z <= 0xFFFFu) return 2;
if (z <= 0xFFFFFFu) return 3;
return 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteLE(List<byte> dst, uint value, int width)
{
for (int i = 0; i < width; i++)
dst.Add((byte)((value >> (8 * i)) & 0xFF));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong ReadLE(ReadOnlySpan<byte> src, ref int pos, int width)
{
if ((uint)(pos + width) > (uint)src.Length)
throw new ArgumentException("Buffer underflow while reading group payload.");
ulong v = 0;
for (int i = 0; i < width; i++)
v |= (ulong)src[pos++] << (8 * i);
return v;
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Esiur.Data.GVWIE;
public static class GroupInt64Codec
{
// ----------------- Encoder -----------------
public static byte[] Encode(IList<long> values)
{
var dst = new List<byte>(values.Count * 2);
int i = 0;
while (i < values.Count)
{
ulong zz = ZigZag64(values[i]);
// Fast path: 1 byte when ZigZag fits in 7 bits
if (zz <= 0x7Ful)
{
dst.Add((byte)zz); // MSB = 0 implicitly
i++;
continue;
}
// Group path: up to 16 items sharing a common width (1..8 bytes)
int start = i;
int count = 1;
int width = WidthFromZigZag(zz);
while (count < 16 && (i + count) < values.Count)
{
ulong z2 = ZigZag64(values[i + count]);
int w2 = WidthFromZigZag(z2);
width = Math.Max(width, w2); // widen as needed
count++;
}
// Header: 1 | (count-1)[4 bits] | (width-1)[3 bits]
byte header = 0x80;
header |= (byte)(((count - 1) & 0x0F) << 3);
header |= (byte)((width - 1) & 0x07);
dst.Add(header);
// Payload: 'count' ZigZag values, LE, 'width' bytes each
for (int k = 0; k < count; k++)
{
ulong z = ZigZag64(values[start + k]);
WriteLE(dst, z, width);
}
i += count;
}
return dst.ToArray();
}
// ----------------- Decoder -----------------
public static long[] Decode(ReadOnlySpan<byte> src)
{
var result = new List<long>();
int pos = 0;
while (pos < src.Length)
{
byte h = src[pos++];
if ((h & 0x80) == 0)
{
// Fast path: 7-bit ZigZag
ulong zz7 = (ulong)(h & 0x7F);
result.Add(UnZigZag64(zz7));
continue;
}
int count = ((h >> 3) & 0x0F) + 1; // 1..16
int width = (h & 0x07) + 1; // 1..8
for (int j = 0; j < count; j++)
{
ulong raw = ReadLE(src, ref pos, width);
long val = UnZigZag64(raw);
result.Add(val);
}
}
return result.ToArray();
}
// ----------------- Helpers -----------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong ZigZag64(long v) => (ulong)((v << 1) ^ (v >> 63));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static long UnZigZag64(ulong u) => (long)((u >> 1) ^ (ulong)-(long)(u & 1));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int WidthFromZigZag(ulong z)
{
if (z <= 0xFFUL) return 1;
if (z <= 0xFFFFUL) return 2;
if (z <= 0xFFFFFFUL) return 3;
if (z <= 0xFFFFFFFFUL) return 4;
if (z <= 0xFFFFFFFFFFUL) return 5;
if (z <= 0xFFFFFFFFFFFFUL) return 6;
if (z <= 0xFFFFFFFFFFFFFFUL) return 7;
return 8;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteLE(List<byte> dst, ulong value, int width)
{
for (int i = 0; i < width; i++)
dst.Add((byte)((value >> (8 * i)) & 0xFF));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong ReadLE(ReadOnlySpan<byte> src, ref int pos, int width)
{
if ((uint)(pos + width) > (uint)src.Length)
throw new ArgumentException("Buffer underflow while reading group payload.");
ulong v = 0;
for (int i = 0; i < width; i++)
v |= (ulong)src[pos++] << (8 * i);
return v;
}
}

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace Esiur.Data.GVWIE;
public static class GroupUInt16Codec
{
// ----------------- Encoder -----------------
public static byte[] Encode(IList<ushort> values)
{
if (values is null) throw new ArgumentNullException(nameof(values));
var dst = new List<byte>(values.Count * 2);
int i = 0;
while (i < values.Count)
{
ushort v = values[i];
// Fast path: single byte for 0..127
if (v <= 0x7F)
{
dst.Add((byte)v); // MSB=0 implicitly
i++;
continue;
}
// Group path: up to 16 items sharing a common width (1..2 bytes for uint16)
int start = i;
int count = 1;
int width = WidthFromUnsigned(v);
while (count < 16 && (i + count) < values.Count)
{
ushort v2 = values[i + count];
int w2 = WidthFromUnsigned(v2);
if (w2 > width) width = w2; // widen group if needed
count++;
}
// Header: 1 | (count-1)[4b] | (width-1)[3b]
byte header = 0x80;
header |= (byte)(((count - 1) & 0xF) << 3);
header |= (byte)((width - 1) & 0x7);
dst.Add(header);
// Payload
for (int k = 0; k < count; k++)
{
WriteLE(dst, values[start + k], width);
}
i += count;
}
return dst.ToArray();
}
// ----------------- Decoder -----------------
public static ushort[] Decode(ReadOnlySpan<byte> src)
{
var result = new List<ushort>();
int pos = 0;
while (pos < src.Length)
{
byte h = src[pos++];
if ((h & 0x80) == 0)
{
// Fast path byte (0..127)
result.Add(h);
continue;
}
int count = ((h >> 3) & 0xF) + 1; // 1..16
int width = (h & 0x7) + 1; // 1..8 (expect 1..2)
if (width > 2)
throw new NotSupportedException($"Width {width} bytes exceeds uint16 capacity.");
for (int j = 0; j < count; j++)
{
uint val = (uint)ReadLE(src, ref pos, width);
if (val > 0xFFFFu)
throw new OverflowException("Decoded value exceeds UInt16 range.");
result.Add((ushort)val);
}
}
return result.ToArray();
}
// ----------------- Helpers -----------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int WidthFromUnsigned(ushort v) => (v <= 0xFF) ? 1 : 2;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteLE(List<byte> dst, ushort value, int width)
{
// width is 1 or 2
dst.Add((byte)(value & 0xFF));
if (width == 2) dst.Add((byte)(value >> 8));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong ReadLE(ReadOnlySpan<byte> src, ref int pos, int width)
{
if (pos + width > src.Length)
throw new ArgumentException("Buffer underflow while reading payload.");
ulong v = src[pos++]; // first byte (LSB)
if (width == 2) v |= (ulong)src[pos++] << 8;
return v;
}
}

View File

@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace Esiur.Data.GVWIE;
public static class GroupUInt32Codec
{
// ----------------- Encoder -----------------
public static byte[] Encode(IList<uint> values)
{
if (values is null) throw new ArgumentNullException(nameof(values));
var dst = new List<byte>(values.Count * 2);
int i = 0;
while (i < values.Count)
{
uint v = values[i];
// Fast path: single byte for 0..127
if (v <= 0x7Fu)
{
dst.Add((byte)v); // MSB=0 implicitly
i++;
continue;
}
// Group path: up to 16 items sharing a common width (1..4 bytes for uint32)
int start = i;
int count = 1;
int width = WidthFromUnsigned(v);
while (count < 16 && (i + count) < values.Count)
{
uint v2 = values[i + count];
int w2 = WidthFromUnsigned(v2);
if (w2 > width) width = w2;
count++;
}
// Header: 1 | (count-1)[4b] | (width-1)[3b]
byte header = 0x80;
header |= (byte)(((count - 1) & 0xF) << 3);
header |= (byte)((width - 1) & 0x7);
dst.Add(header);
// Payload
for (int k = 0; k < count; k++)
{
WriteLE(dst, values[start + k], width);
}
i += count;
}
return dst.ToArray();
}
// ----------------- Decoder -----------------
public static uint[] Decode(ReadOnlySpan<byte> src)
{
var result = new List<uint>();
int pos = 0;
while (pos < src.Length)
{
byte h = src[pos++];
if ((h & 0x80) == 0)
{
// Fast path byte (0..127)
result.Add(h);
continue;
}
int count = ((h >> 3) & 0xF) + 1; // 1..16
int width = (h & 0x7) + 1; // 1..8 (we expect 1..4)
if (width > 4)
throw new NotSupportedException($"Width {width} bytes exceeds uint32 capacity.");
for (int j = 0; j < count; j++)
{
uint val = (uint)ReadLE(src, ref pos, width);
result.Add(val);
}
}
return result.ToArray();
}
// ----------------- Helpers -----------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int WidthFromUnsigned(uint v)
{
if (v <= 0xFFu) return 1;
if (v <= 0xFFFFu) return 2;
if (v <= 0xFFFFFFu) return 3;
return 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteLE(List<byte> dst, uint value, int width)
{
for (int i = 0; i < width; i++)
dst.Add((byte)((value >> (8 * i)) & 0xFF));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong ReadLE(ReadOnlySpan<byte> src, ref int pos, int width)
{
if (pos + width > src.Length)
throw new ArgumentException("Buffer underflow while reading payload.");
ulong v = 0;
for (int i = 0; i < width; i++)
v |= (ulong)src[pos++] << (8 * i);
return v;
}
}

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Esiur.Data.GVWIE;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public static class GroupUInt64Codec
{
// ----------------- Encoder -----------------
public static byte[] Encode(IList<ulong> values)
{
if (values is null) throw new ArgumentNullException(nameof(values));
var dst = new List<byte>(values.Count * 2);
int i = 0;
while (i < values.Count)
{
ulong v = values[i];
// Fast path: single byte for 0..127
if (v <= 0x7FUL)
{
dst.Add((byte)v); // MSB = 0 implicitly
i++;
continue;
}
// Group path: up to 16 items sharing max width (1..8 bytes)
int start = i;
int count = 1;
int width = WidthFromUnsigned(v);
while (count < 16 && (i + count) < values.Count)
{
ulong v2 = values[i + count];
int w2 = WidthFromUnsigned(v2);
if (w2 > width) width = w2;
count++;
}
// Header: 1 | (count-1)[4b] | (width-1)[3b]
byte header = 0x80;
header |= (byte)(((count - 1) & 0xF) << 3);
header |= (byte)((width - 1) & 0x7);
dst.Add(header);
// Payload
for (int k = 0; k < count; k++)
WriteLE(dst, values[start + k], width);
i += count;
}
return dst.ToArray();
}
// ----------------- Decoder -----------------
public static ulong[] Decode(ReadOnlySpan<byte> src)
{
var result = new List<ulong>();
int pos = 0;
while (pos < src.Length)
{
byte h = src[pos++];
if ((h & 0x80) == 0)
{
// Fast path byte (0..127)
result.Add(h);
continue;
}
int count = ((h >> 3) & 0xF) + 1; // 1..16
int width = (h & 0x7) + 1; // 1..8
if (width < 1 || width > 8)
throw new NotSupportedException($"Invalid width {width} in header.");
for (int j = 0; j < count; j++)
{
ulong val = ReadLE(src, ref pos, width);
result.Add(val);
}
}
return result.ToArray();
}
// ----------------- Helpers -----------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int WidthFromUnsigned(ulong v)
{
if (v <= 0xFFUL) return 1;
if (v <= 0xFFFFUL) return 2;
if (v <= 0xFFFFFFUL) return 3;
if (v <= 0xFFFFFFFFUL) return 4;
if (v <= 0xFFFFFFFFFFUL) return 5;
if (v <= 0xFFFFFFFFFFFFUL) return 6;
if (v <= 0xFFFFFFFFFFFFFFUL) return 7;
return 8;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void WriteLE(List<byte> dst, ulong value, int width)
{
for (int i = 0; i < width; i++)
dst.Add((byte)((value >> (8 * i)) & 0xFF));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong ReadLE(ReadOnlySpan<byte> src, ref int pos, int width)
{
if (pos + width > src.Length)
throw new ArgumentException("Buffer underflow while reading payload.");
ulong v = 0;
for (int i = 0; i < width; i++)
v |= (ulong)src[pos++] << (8 * i);
return v;
}
}

View File

@@ -1,536 +0,0 @@
using Esiur.Core;
using Esiur.Net.IIP;
using Esiur.Resource;
using Esiur.Resource.Template;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
#nullable enable
namespace Esiur.Data
{
public enum RepresentationTypeIdentifier
{
Void = 0x0,
Dynamic = 0x1,
Bool = 0x2,
UInt8,
Int8,
Char,
UInt16,
Int16,
UInt32,
Int32,
Float32,
UInt64,
Int64,
Float64,
DateTime,
UInt128,
Int128,
Decimal,
String,
RawData,
Resource,
Record,
List,
Map,
Enum = 0x44,
TypedResource = 0x45, // Followed by UUID
TypedRecord = 0x46, // Followed by UUID
TypedList = 0x48, // Followed by element type
Tuple2 = 0x50, // Followed by element type
TypedMap = 0x51, // Followed by key type and value type
Tuple3 = 0x58,
Tuple4 = 0x60,
Tuple5 = 0x68,
Tuple6 = 0x70,
Tuple7 = 0x78
}
public class RepresentationType
{
static RepresentationTypeIdentifier[] refTypes = new RepresentationTypeIdentifier[]
{
RepresentationTypeIdentifier.Dynamic,
RepresentationTypeIdentifier.RawData,
RepresentationTypeIdentifier.String,
RepresentationTypeIdentifier.Resource,
RepresentationTypeIdentifier.Record,
RepresentationTypeIdentifier.Map,
RepresentationTypeIdentifier.List,
RepresentationTypeIdentifier.TypedList,
RepresentationTypeIdentifier.TypedMap,
RepresentationTypeIdentifier.Tuple2,
RepresentationTypeIdentifier.Tuple3,
RepresentationTypeIdentifier.Tuple4,
RepresentationTypeIdentifier.Tuple5,
RepresentationTypeIdentifier.Tuple6,
RepresentationTypeIdentifier.Tuple7,
RepresentationTypeIdentifier.TypedRecord,
RepresentationTypeIdentifier.TypedResource
};
static Map<TDUIdentifier, RepresentationTypeIdentifier> typesMap = new Map<TDUIdentifier, RepresentationTypeIdentifier>()
{
[TDUIdentifier.UInt8] = RepresentationTypeIdentifier.UInt8,
[TDUIdentifier.Int8] = RepresentationTypeIdentifier.Int8,
[TDUIdentifier.UInt16] = RepresentationTypeIdentifier.UInt16,
[TDUIdentifier.Int16] = RepresentationTypeIdentifier.Int16,
[TDUIdentifier.UInt32] = RepresentationTypeIdentifier.UInt32,
[TDUIdentifier.Int32] = RepresentationTypeIdentifier.Int32,
[TDUIdentifier.UInt64] = RepresentationTypeIdentifier.UInt64,
[TDUIdentifier.Int64] = RepresentationTypeIdentifier.Int64,
[TDUIdentifier.UInt128] = RepresentationTypeIdentifier.UInt128,
[TDUIdentifier.Int128] = RepresentationTypeIdentifier.Int128,
[TDUIdentifier.Char8] = RepresentationTypeIdentifier.Char,
[TDUIdentifier.DateTime] = RepresentationTypeIdentifier.DateTime,
[TDUIdentifier.Float32] = RepresentationTypeIdentifier.Float32,
[TDUIdentifier.Float64] = RepresentationTypeIdentifier.Float64,
[TDUIdentifier.Decimal128] = RepresentationTypeIdentifier.Decimal,
[TDUIdentifier.False] = RepresentationTypeIdentifier.Bool,
[TDUIdentifier.True] = RepresentationTypeIdentifier.Bool,
[TDUIdentifier.Map] = RepresentationTypeIdentifier.Map,
[TDUIdentifier.List] = RepresentationTypeIdentifier.List,
[TDUIdentifier.RawData] = RepresentationTypeIdentifier.RawData,
[TDUIdentifier.Record] = RepresentationTypeIdentifier.Record,
[TDUIdentifier.String] = RepresentationTypeIdentifier.String,
};
public void SetNull(List<byte> flags)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flags.FirstOrDefault() == 2);
if (flags.Count > 0)
flags.RemoveAt(0);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNull(flags);
}
public void SetNull(byte flag)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flag == 2);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNull(flag);
}
public void SetNotNull(List<byte> flags)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flags.FirstOrDefault() != 1);
if (flags.Count > 0)
flags.RemoveAt(0);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNotNull(flags);
}
public override string ToString()
{
if (SubTypes != null && SubTypes.Length > 0)
return Identifier.ToString() + "<" + String.Join(",", SubTypes.Select(x => x.ToString())) + ">" + (Nullable ? "?" : "");
return Identifier.ToString() + (Nullable ? "?" : "");
}
public void SetNotNull(byte flag)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flag != 1);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNotNull(flag);
}
public Type? GetRuntimeType(Warehouse warehouse)
{
if (Identifier == RepresentationTypeIdentifier.TypedList)
{
var sub = SubTypes?[0].GetRuntimeType(warehouse);
if (sub == null)
return null;
var rt = sub.MakeArrayType();
return rt;
}
else if (Identifier == RepresentationTypeIdentifier.TypedMap)
{
var subs = SubTypes.Select(x => x.GetRuntimeType(warehouse)).ToArray();
var rt = typeof(Map<,>).MakeGenericType(subs);
return rt;
}
return Identifier switch
{
(RepresentationTypeIdentifier.Void) => typeof(void),
(RepresentationTypeIdentifier.Dynamic) => typeof(object),
(RepresentationTypeIdentifier.Bool) => Nullable ? typeof(bool?) : typeof(bool),
(RepresentationTypeIdentifier.Char) => Nullable ? typeof(char?) : typeof(char),
(RepresentationTypeIdentifier.UInt8) => Nullable ? typeof(byte?) : typeof(byte),
(RepresentationTypeIdentifier.Int8) => Nullable ? typeof(sbyte?) : typeof(sbyte),
(RepresentationTypeIdentifier.Int16) => Nullable ? typeof(short?) : typeof(short),
(RepresentationTypeIdentifier.UInt16) => Nullable ? typeof(ushort?) : typeof(ushort),
(RepresentationTypeIdentifier.Int32) => Nullable ? typeof(int?) : typeof(int),
(RepresentationTypeIdentifier.UInt32) => Nullable ? typeof(uint?) : typeof(uint),
(RepresentationTypeIdentifier.Int64) => Nullable ? typeof(ulong?) : typeof(long),
(RepresentationTypeIdentifier.UInt64) => Nullable ? typeof(ulong?) : typeof(ulong),
(RepresentationTypeIdentifier.Float32) => Nullable ? typeof(float?) : typeof(float),
(RepresentationTypeIdentifier.Float64) => Nullable ? typeof(double?) : typeof(double),
(RepresentationTypeIdentifier.Decimal) => Nullable ? typeof(decimal?) : typeof(decimal),
(RepresentationTypeIdentifier.String) => typeof(string),
(RepresentationTypeIdentifier.DateTime) => Nullable ? typeof(DateTime?) : typeof(DateTime),
(RepresentationTypeIdentifier.Resource) => typeof(IResource),
(RepresentationTypeIdentifier.Record) => typeof(IRecord),
(RepresentationTypeIdentifier.TypedRecord) => warehouse.GetTemplateByClassId((UUID)UUID!, TemplateType.Record)?.DefinedType,
(RepresentationTypeIdentifier.TypedResource) => warehouse.GetTemplateByClassId((UUID)UUID!, TemplateType.Resource)?.DefinedType,
(RepresentationTypeIdentifier.Enum) =>warehouse.GetTemplateByClassId((UUID)UUID!, TemplateType.Enum)?.DefinedType,
_ => null
};
}
public RepresentationTypeIdentifier Identifier;
public bool Nullable;
public UUID? UUID;
//public RepresentationType? SubType1; // List + Map
//public RepresentationType? SubType2; // Map
//public RepresentationType? SubType3; // No types yet
public RepresentationType[]? SubTypes = null;
public RepresentationType ToNullable()
{
return new RepresentationType(Identifier, true, UUID, SubTypes);
}
public static RepresentationType? FromType(Type type)
{
var nullable = false;
var nullType = System.Nullable.GetUnderlyingType(type);
if (nullType != null)
{
type = nullType;
nullable = true;
}
if (type == typeof(IResource))
return new RepresentationType(RepresentationTypeIdentifier.Resource, nullable);
else if (type == typeof(IRecord) || type == typeof(Record))
return new RepresentationType(RepresentationTypeIdentifier.Record, nullable);
else if (type == typeof(Map<object, object>)
|| type == typeof(Dictionary<object, object>))
return new RepresentationType(RepresentationTypeIdentifier.Map, nullable);
else if (Codec.ImplementsInterface(type, typeof(IResource)))
{
return new RepresentationType(
RepresentationTypeIdentifier.TypedResource,
nullable,
TypeTemplate.GetTypeUUID(type)
);
}
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
{
return new RepresentationType(
RepresentationTypeIdentifier.TypedRecord,
nullable,
TypeTemplate.GetTypeUUID(type)
);
}
else if (type.IsGenericType)
{
var genericType = type.GetGenericTypeDefinition();
if (genericType == typeof(List<>)
|| genericType == typeof(VarList<>)
|| genericType == typeof(IList<>))
{
var args = type.GetGenericArguments();
if (args[0] == typeof(object))
{
return new RepresentationType(RepresentationTypeIdentifier.List, nullable);
}
else
{
var subType = FromType(args[0]);
if (subType == null) // unrecongnized type
return null;
return new RepresentationType(RepresentationTypeIdentifier.TypedList, nullable, null,
new RepresentationType[] { subType });
}
}
else if (genericType == typeof(Map<,>)
|| genericType == typeof(Dictionary<,>))
{
var args = type.GetGenericArguments();
if (args[0] == typeof(object) && args[1] == typeof(object))
{
return new RepresentationType(RepresentationTypeIdentifier.Map, nullable);
}
else
{
var subType1 = FromType(args[0]);
if (subType1 == null)
return null;
var subType2 = FromType(args[1]);
if (subType2 == null)
return null;
return new RepresentationType(RepresentationTypeIdentifier.TypedMap, nullable, null,
new RepresentationType[] { subType1, subType2 });
}
}
//else if (genericType == typeof(AsyncReply<>))
//{
// var args = type.GetGenericArguments();
// return FromType(args[0]);
//}
//else if (genericType == typeof(DistributedPropertyContext<>))
//{
// var args = type.GetGenericArguments();
// return FromType(args[0]);
//}
else if (genericType == typeof(ValueTuple<,>))
{
var args = type.GetGenericArguments();
var subTypes = new RepresentationType[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new RepresentationType(RepresentationTypeIdentifier.Tuple2, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,>))
{
var args = type.GetGenericArguments();
var subTypes = new RepresentationType[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new RepresentationType(RepresentationTypeIdentifier.Tuple3, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new RepresentationType[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new RepresentationType(RepresentationTypeIdentifier.Tuple4, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new RepresentationType[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new RepresentationType(RepresentationTypeIdentifier.Tuple5, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new RepresentationType[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new RepresentationType(RepresentationTypeIdentifier.Tuple6, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new RepresentationType[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new RepresentationType(RepresentationTypeIdentifier.Tuple7, nullable, null, subTypes);
}
else
return null;
}
else if (type.IsArray)
{
var elementType = type.GetElementType();
if (elementType == typeof(object))
return new RepresentationType(RepresentationTypeIdentifier.List, nullable);
else
{
var subType = FromType(elementType);
if (subType == null)
return null;
return new RepresentationType(RepresentationTypeIdentifier.TypedList, nullable, null,
new RepresentationType[] { subType });
}
}
else if (type.IsEnum)
{
return new RepresentationType(RepresentationTypeIdentifier.Enum, nullable, TypeTemplate.GetTypeUUID(type));
}
else if (type.IsInterface)
{
return null; // other interfaces are not supported
}
//else if (typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => RepresentationTypeIdentifier.Structure)
//{
//}
return type switch
{
_ when type == typeof(void) => new RepresentationType(RepresentationTypeIdentifier.Void, nullable),
_ when type == typeof(object) => new RepresentationType(RepresentationTypeIdentifier.Dynamic, nullable),
_ when type == typeof(bool) => new RepresentationType(RepresentationTypeIdentifier.Bool, nullable),
_ when type == typeof(char) => new RepresentationType(RepresentationTypeIdentifier.Char, nullable),
_ when type == typeof(byte) => new RepresentationType(RepresentationTypeIdentifier.UInt8, nullable),
_ when type == typeof(sbyte) => new RepresentationType(RepresentationTypeIdentifier.Int8, nullable),
_ when type == typeof(short) => new RepresentationType(RepresentationTypeIdentifier.Int16, nullable),
_ when type == typeof(ushort) => new RepresentationType(RepresentationTypeIdentifier.UInt16, nullable),
_ when type == typeof(int) => new RepresentationType(RepresentationTypeIdentifier.Int32, nullable),
_ when type == typeof(uint) => new RepresentationType(RepresentationTypeIdentifier.UInt32, nullable),
_ when type == typeof(long) => new RepresentationType(RepresentationTypeIdentifier.Int64, nullable),
_ when type == typeof(ulong) => new RepresentationType(RepresentationTypeIdentifier.UInt64, nullable),
_ when type == typeof(float) => new RepresentationType(RepresentationTypeIdentifier.Float32, nullable),
_ when type == typeof(double) => new RepresentationType(RepresentationTypeIdentifier.Float64, nullable),
_ when type == typeof(decimal) => new RepresentationType(RepresentationTypeIdentifier.Decimal, nullable),
_ when type == typeof(string) => new RepresentationType(RepresentationTypeIdentifier.String, nullable),
_ when type == typeof(DateTime) => new RepresentationType(RepresentationTypeIdentifier.DateTime, nullable),
_ => null
};
}
public RepresentationType(RepresentationTypeIdentifier identifier, bool nullable, UUID? uuid = null, RepresentationType[]? subTypes = null)
{
Nullable = nullable;
Identifier = identifier;
UUID = uuid;
SubTypes = subTypes;
}
public byte[] Compose()
{
var rt = new BinaryList();
if (Nullable)
rt.AddUInt8((byte)(0x80 | (byte)Identifier));
else
rt.AddUInt8((byte)Identifier);
if (UUID != null)
rt.AddUInt8Array(UUID.Value.Data);
if (SubTypes != null)
for (var i = 0; i < SubTypes.Length; i++)
rt.AddUInt8Array(SubTypes[i].Compose());
return rt.ToArray();
}
//public override string ToString() => Identifier.ToString() + (Nullable ? "?" : "")
// + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
public static (uint, RepresentationType) Parse(byte[] data, uint offset)
{
var oOffset = offset;
var header = data[offset++];
bool nullable = (header & 0x80) > 0;
var identifier = (RepresentationTypeIdentifier)(header & 0x7F);
if ((header & 0x40) > 0)
{
var hasUUID = (header & 0x4) > 0;
var subsCount = (header >> 3) & 0x7;
UUID? uuid = null;
if (hasUUID)
{
uuid = data.GetUUID(offset);
offset += 16;
}
var subs = new RepresentationType[subsCount];
for (var i = 0; i < subsCount; i++)
{
(var len, subs[i]) = RepresentationType.Parse(data, offset);
offset += len;
}
return (offset - oOffset, new RepresentationType(identifier, nullable, uuid, subs));
}
else
{
return (1, new RepresentationType(identifier, nullable));
}
}
}
}

View File

@@ -61,6 +61,7 @@ public struct TDU
public TDU(TDUIdentifier identifier)
{
Identifier = identifier;
Composed = new byte[0];
}
public TDU(TDUIdentifier identifier,
@@ -74,7 +75,10 @@ public struct TDU
if (Class == TDUClass.Fixed)
{
Composed = DC.Combine(new byte[] { (byte)Identifier }, 0, 1, data, 0, (uint)length);
if (length == 0)
Composed = new byte[1] { (byte)identifier };
else
Composed = DC.Combine(new byte[] { (byte)Identifier }, 0, 1, data, 0, (uint)length);
}
else if (Class == TDUClass.Dynamic
|| Class == TDUClass.Extension)

View File

@@ -58,7 +58,7 @@ namespace Esiur.Data
TypedConstant = 0x85,
TypeContinuation = 0xC0,
TypeOfTarget = 0xC1,
}
}

502
Esiur/Data/TRU.cs Normal file
View File

@@ -0,0 +1,502 @@
using Esiur.Core;
using Esiur.Net.IIP;
using Esiur.Resource;
using Esiur.Resource.Template;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
#nullable enable
namespace Esiur.Data
{
public class TRU
{
static TRUIdentifier[] refTypes = new TRUIdentifier[]
{
TRUIdentifier.Dynamic,
TRUIdentifier.RawData,
TRUIdentifier.String,
TRUIdentifier.Resource,
TRUIdentifier.Record,
TRUIdentifier.Map,
TRUIdentifier.List,
TRUIdentifier.TypedList,
TRUIdentifier.TypedMap,
TRUIdentifier.Tuple2,
TRUIdentifier.Tuple3,
TRUIdentifier.Tuple4,
TRUIdentifier.Tuple5,
TRUIdentifier.Tuple6,
TRUIdentifier.Tuple7,
TRUIdentifier.TypedRecord,
TRUIdentifier.TypedResource
};
static Map<TDUIdentifier, TRUIdentifier> typesMap = new Map<TDUIdentifier, TRUIdentifier>()
{
[TDUIdentifier.UInt8] = TRUIdentifier.UInt8,
[TDUIdentifier.Int8] = TRUIdentifier.Int8,
[TDUIdentifier.UInt16] = TRUIdentifier.UInt16,
[TDUIdentifier.Int16] = TRUIdentifier.Int16,
[TDUIdentifier.UInt32] = TRUIdentifier.UInt32,
[TDUIdentifier.Int32] = TRUIdentifier.Int32,
[TDUIdentifier.UInt64] = TRUIdentifier.UInt64,
[TDUIdentifier.Int64] = TRUIdentifier.Int64,
[TDUIdentifier.UInt128] = TRUIdentifier.UInt128,
[TDUIdentifier.Int128] = TRUIdentifier.Int128,
[TDUIdentifier.Char8] = TRUIdentifier.Char,
[TDUIdentifier.DateTime] = TRUIdentifier.DateTime,
[TDUIdentifier.Float32] = TRUIdentifier.Float32,
[TDUIdentifier.Float64] = TRUIdentifier.Float64,
[TDUIdentifier.Decimal128] = TRUIdentifier.Decimal,
[TDUIdentifier.False] = TRUIdentifier.Bool,
[TDUIdentifier.True] = TRUIdentifier.Bool,
[TDUIdentifier.Map] = TRUIdentifier.Map,
[TDUIdentifier.List] = TRUIdentifier.List,
[TDUIdentifier.RawData] = TRUIdentifier.RawData,
[TDUIdentifier.Record] = TRUIdentifier.Record,
[TDUIdentifier.String] = TRUIdentifier.String,
};
public void SetNull(List<byte> flags)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flags.FirstOrDefault() == 2);
if (flags.Count > 0)
flags.RemoveAt(0);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNull(flags);
}
public void SetNull(byte flag)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flag == 2);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNull(flag);
}
public void SetNotNull(List<byte> flags)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flags.FirstOrDefault() != 1);
if (flags.Count > 0)
flags.RemoveAt(0);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNotNull(flags);
}
public override string ToString()
{
if (SubTypes != null && SubTypes.Length > 0)
return Identifier.ToString() + "<" + String.Join(",", SubTypes.Select(x => x.ToString())) + ">" + (Nullable ? "?" : "");
return Identifier.ToString() + (Nullable ? "?" : "");
}
public void SetNotNull(byte flag)
{
if (refTypes.Contains(Identifier))
{
Nullable = (flag != 1);
}
if (SubTypes != null)
foreach (var st in SubTypes)
st.SetNotNull(flag);
}
public Type? GetRuntimeType(Warehouse warehouse)
{
if (Identifier == TRUIdentifier.TypedList)
{
var sub = SubTypes?[0].GetRuntimeType(warehouse);
if (sub == null)
return null;
var rt = sub.MakeArrayType();
return rt;
}
else if (Identifier == TRUIdentifier.TypedMap)
{
var subs = SubTypes.Select(x => x.GetRuntimeType(warehouse)).ToArray();
var rt = typeof(Map<,>).MakeGenericType(subs);
return rt;
}
return Identifier switch
{
(TRUIdentifier.Void) => typeof(void),
(TRUIdentifier.Dynamic) => typeof(object),
(TRUIdentifier.Bool) => Nullable ? typeof(bool?) : typeof(bool),
(TRUIdentifier.Char) => Nullable ? typeof(char?) : typeof(char),
(TRUIdentifier.UInt8) => Nullable ? typeof(byte?) : typeof(byte),
(TRUIdentifier.Int8) => Nullable ? typeof(sbyte?) : typeof(sbyte),
(TRUIdentifier.Int16) => Nullable ? typeof(short?) : typeof(short),
(TRUIdentifier.UInt16) => Nullable ? typeof(ushort?) : typeof(ushort),
(TRUIdentifier.Int32) => Nullable ? typeof(int?) : typeof(int),
(TRUIdentifier.UInt32) => Nullable ? typeof(uint?) : typeof(uint),
(TRUIdentifier.Int64) => Nullable ? typeof(ulong?) : typeof(long),
(TRUIdentifier.UInt64) => Nullable ? typeof(ulong?) : typeof(ulong),
(TRUIdentifier.Float32) => Nullable ? typeof(float?) : typeof(float),
(TRUIdentifier.Float64) => Nullable ? typeof(double?) : typeof(double),
(TRUIdentifier.Decimal) => Nullable ? typeof(decimal?) : typeof(decimal),
(TRUIdentifier.String) => typeof(string),
(TRUIdentifier.DateTime) => Nullable ? typeof(DateTime?) : typeof(DateTime),
(TRUIdentifier.Resource) => typeof(IResource),
(TRUIdentifier.Record) => typeof(IRecord),
(TRUIdentifier.TypedRecord) => warehouse.GetTemplateByClassId((UUID)UUID!, TemplateType.Record)?.DefinedType,
(TRUIdentifier.TypedResource) => warehouse.GetTemplateByClassId((UUID)UUID!, TemplateType.Resource)?.DefinedType,
(TRUIdentifier.Enum) =>warehouse.GetTemplateByClassId((UUID)UUID!, TemplateType.Enum)?.DefinedType,
_ => null
};
}
public TRUIdentifier Identifier;
public bool Nullable;
public UUID? UUID;
//public RepresentationType? SubType1; // List + Map
//public RepresentationType? SubType2; // Map
//public RepresentationType? SubType3; // No types yet
public TRU[]? SubTypes = null;
public TRU ToNullable()
{
return new TRU(Identifier, true, UUID, SubTypes);
}
public bool Match(TRU other)
{
if (other.Identifier != Identifier)
return false;
if (other.UUID != UUID)
return false;
if (other.SubTypes != null)
{
if (other.SubTypes.Length != (SubTypes?.Length ?? -1))
return false;
for (var i = 0; i < SubTypes?.Length; i++)
if (!SubTypes[i].Match(other.SubTypes[i]))
return false;
}
return true;
}
public static TRU? FromType(Type type)
{
var nullable = false;
var nullType = System.Nullable.GetUnderlyingType(type);
if (nullType != null)
{
type = nullType;
nullable = true;
}
if (type == typeof(IResource))
return new TRU(TRUIdentifier.Resource, nullable);
else if (type == typeof(IRecord) || type == typeof(Record))
return new TRU(TRUIdentifier.Record, nullable);
else if (type == typeof(Map<object, object>)
|| type == typeof(Dictionary<object, object>))
return new TRU(TRUIdentifier.Map, nullable);
else if (Codec.ImplementsInterface(type, typeof(IResource)))
{
return new TRU(
TRUIdentifier.TypedResource,
nullable,
TypeTemplate.GetTypeUUID(type)
);
}
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
{
return new TRU(
TRUIdentifier.TypedRecord,
nullable,
TypeTemplate.GetTypeUUID(type)
);
}
else if (type.IsGenericType)
{
var genericType = type.GetGenericTypeDefinition();
if (genericType == typeof(List<>)
|| genericType == typeof(VarList<>)
|| genericType == typeof(IList<>))
{
var args = type.GetGenericArguments();
if (args[0] == typeof(object))
{
return new TRU(TRUIdentifier.List, nullable);
}
else
{
var subType = FromType(args[0]);
if (subType == null) // unrecongnized type
return null;
return new TRU(TRUIdentifier.TypedList, nullable, null,
new TRU[] { subType });
}
}
else if (genericType == typeof(Map<,>)
|| genericType == typeof(Dictionary<,>))
{
var args = type.GetGenericArguments();
if (args[0] == typeof(object) && args[1] == typeof(object))
{
return new TRU(TRUIdentifier.Map, nullable);
}
else
{
var subType1 = FromType(args[0]);
if (subType1 == null)
return null;
var subType2 = FromType(args[1]);
if (subType2 == null)
return null;
return new TRU(TRUIdentifier.TypedMap, nullable, null,
new TRU[] { subType1, subType2 });
}
}
else if (genericType == typeof(ValueTuple<,>))
{
var args = type.GetGenericArguments();
var subTypes = new TRU[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new TRU(TRUIdentifier.Tuple2, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,>))
{
var args = type.GetGenericArguments();
var subTypes = new TRU[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new TRU(TRUIdentifier.Tuple3, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new TRU[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new TRU(TRUIdentifier.Tuple4, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new TRU[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new TRU(TRUIdentifier.Tuple5, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new TRU[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new TRU(TRUIdentifier.Tuple6, nullable, null, subTypes);
}
else if (genericType == typeof(ValueTuple<,,,,,,>))
{
var args = type.GetGenericArguments();
var subTypes = new TRU[args.Length];
for (var i = 0; i < args.Length; i++)
{
var t = FromType(args[i]);
if (t == null)
return null;
subTypes[i] = t;
}
return new TRU(TRUIdentifier.Tuple7, nullable, null, subTypes);
}
else
return null;
}
else if (type.IsArray)
{
var elementType = type.GetElementType();
if (elementType == typeof(object))
return new TRU(TRUIdentifier.List, nullable);
else
{
var subType = FromType(elementType);
if (subType == null)
return null;
return new TRU(TRUIdentifier.TypedList, nullable, null,
new TRU[] { subType });
}
}
else if (type.IsEnum)
{
return new TRU(TRUIdentifier.Enum, nullable, TypeTemplate.GetTypeUUID(type));
}
else if (type.IsInterface)
{
return null; // other interfaces are not supported
}
//else if (typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => TRUIdentifier.Structure)
//{
//}
return type switch
{
_ when type == typeof(void) => new TRU(TRUIdentifier.Void, nullable),
_ when type == typeof(object) => new TRU(TRUIdentifier.Dynamic, nullable),
_ when type == typeof(bool) => new TRU(TRUIdentifier.Bool, nullable),
_ when type == typeof(char) => new TRU(TRUIdentifier.Char, nullable),
_ when type == typeof(byte) => new TRU(TRUIdentifier.UInt8, nullable),
_ when type == typeof(sbyte) => new TRU(TRUIdentifier.Int8, nullable),
_ when type == typeof(short) => new TRU(TRUIdentifier.Int16, nullable),
_ when type == typeof(ushort) => new TRU(TRUIdentifier.UInt16, nullable),
_ when type == typeof(int) => new TRU(TRUIdentifier.Int32, nullable),
_ when type == typeof(uint) => new TRU(TRUIdentifier.UInt32, nullable),
_ when type == typeof(long) => new TRU(TRUIdentifier.Int64, nullable),
_ when type == typeof(ulong) => new TRU(TRUIdentifier.UInt64, nullable),
_ when type == typeof(float) => new TRU(TRUIdentifier.Float32, nullable),
_ when type == typeof(double) => new TRU(TRUIdentifier.Float64, nullable),
_ when type == typeof(decimal) => new TRU(TRUIdentifier.Decimal, nullable),
_ when type == typeof(string) => new TRU(TRUIdentifier.String, nullable),
_ when type == typeof(DateTime) => new TRU(TRUIdentifier.DateTime, nullable),
_ => null
};
}
public TRU(TRUIdentifier identifier, bool nullable, UUID? uuid = null, TRU[]? subTypes = null)
{
Nullable = nullable;
Identifier = identifier;
UUID = uuid;
SubTypes = subTypes;
}
public byte[] Compose()
{
var rt = new BinaryList();
if (Nullable)
rt.AddUInt8((byte)(0x80 | (byte)Identifier));
else
rt.AddUInt8((byte)Identifier);
if (UUID != null)
rt.AddUInt8Array(UUID.Value.Data);
if (SubTypes != null)
for (var i = 0; i < SubTypes.Length; i++)
rt.AddUInt8Array(SubTypes[i].Compose());
return rt.ToArray();
}
public static (uint, TRU) Parse(byte[] data, uint offset)
{
var oOffset = offset;
var header = data[offset++];
bool nullable = (header & 0x80) > 0;
var identifier = (TRUIdentifier)(header & 0x7F);
if ((header & 0x40) > 0)
{
var hasUUID = (header & 0x4) > 0;
var subsCount = (header >> 3) & 0x7;
UUID? uuid = null;
if (hasUUID)
{
uuid = data.GetUUID(offset);
offset += 16;
}
var subs = new TRU[subsCount];
for (var i = 0; i < subsCount; i++)
{
(var len, subs[i]) = TRU.Parse(data, offset);
offset += len;
}
return (offset - oOffset, new TRU(identifier, nullable, uuid, subs));
}
else
{
return (1, new TRU(identifier, nullable));
}
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Data
{
public enum TRUIdentifier
{
Void = 0x0,
Dynamic = 0x1,
Bool = 0x2,
UInt8,
Int8,
Char,
UInt16,
Int16,
UInt32,
Int32,
Float32,
UInt64,
Int64,
Float64,
DateTime,
UInt128,
Int128,
Decimal,
String,
RawData,
Resource,
Record,
List,
Map,
Enum = 0x44,
TypedResource = 0x45, // Followed by UUID
TypedRecord = 0x46, // Followed by UUID
TypedList = 0x48, // Followed by element type
Tuple2 = 0x50, // Followed by element type
TypedMap = 0x51, // Followed by key type and value type
Tuple3 = 0x58,
Tuple4 = 0x60,
Tuple5 = 0x68,
Tuple6 = 0x70,
Tuple7 = 0x78
}
}

View File

@@ -9,6 +9,7 @@ namespace Esiur.Net.Packets
// Success
Completed = 0x0,
Propagated = 0x1,
Stream = 0x2,
// Error
PermissionError = 0x81,

View File

@@ -32,6 +32,11 @@ namespace Esiur.Net.Packets
// Request Static
KeepAlive = 0x18,
ProcedureCall = 0x19,
StaticCall = 0x1A
StaticCall = 0x1A,
IndirectCall = 0x1B,
PullStream = 0x1C,
TerminateExecution = 0x1D,
HaltExecution = 0x1E,
}
}

View File

@@ -121,28 +121,28 @@ public static class TemplateGenerator
}
static string GetTypeName(RepresentationType representationType, TypeTemplate[] templates)
static string GetTypeName(TRU representationType, TypeTemplate[] templates)
{
string name;
if (representationType.Identifier == RepresentationTypeIdentifier.TypedResource)// == DataType.Resource)
if (representationType.Identifier == TRUIdentifier.TypedResource)// == DataType.Resource)
name = templates.First(x => x.ClassId == representationType.UUID && (x.Type == TemplateType.Resource)).ClassName;
else if (representationType.Identifier == RepresentationTypeIdentifier.TypedRecord)
else if (representationType.Identifier == TRUIdentifier.TypedRecord)
name = templates.First(x => x.ClassId == representationType.UUID && x.Type == TemplateType.Record).ClassName;
else if (representationType.Identifier == RepresentationTypeIdentifier.Enum)
else if (representationType.Identifier == TRUIdentifier.Enum)
name = templates.First(x => x.ClassId == representationType.UUID && x.Type == TemplateType.Enum).ClassName;
else if (representationType.Identifier == RepresentationTypeIdentifier.TypedList)
else if (representationType.Identifier == TRUIdentifier.TypedList)
name = GetTypeName(representationType.SubTypes[0], templates) + "[]";
else if (representationType.Identifier == RepresentationTypeIdentifier.TypedMap)
else if (representationType.Identifier == TRUIdentifier.TypedMap)
name = "Map<" + GetTypeName(representationType.SubTypes[0], templates)
+ "," + GetTypeName(representationType.SubTypes[1], templates)
+ ">";
else if (representationType.Identifier == RepresentationTypeIdentifier.Tuple2 ||
representationType.Identifier == RepresentationTypeIdentifier.Tuple3 ||
representationType.Identifier == RepresentationTypeIdentifier.Tuple4 ||
representationType.Identifier == RepresentationTypeIdentifier.Tuple5 ||
representationType.Identifier == RepresentationTypeIdentifier.Tuple6 ||
representationType.Identifier == RepresentationTypeIdentifier.Tuple7)
else if (representationType.Identifier == TRUIdentifier.Tuple2 ||
representationType.Identifier == TRUIdentifier.Tuple3 ||
representationType.Identifier == TRUIdentifier.Tuple4 ||
representationType.Identifier == TRUIdentifier.Tuple5 ||
representationType.Identifier == TRUIdentifier.Tuple6 ||
representationType.Identifier == TRUIdentifier.Tuple7)
name = "(" + String.Join(",", representationType.SubTypes.Select(x => GetTypeName(x, templates)))
+ ")";
else
@@ -150,26 +150,26 @@ public static class TemplateGenerator
name = representationType.Identifier switch
{
RepresentationTypeIdentifier.Dynamic => "object",
RepresentationTypeIdentifier.Bool => "bool",
RepresentationTypeIdentifier.Char => "char",
RepresentationTypeIdentifier.DateTime => "DateTime",
RepresentationTypeIdentifier.Decimal => "decimal",
RepresentationTypeIdentifier.Float32 => "float",
RepresentationTypeIdentifier.Float64 => "double",
RepresentationTypeIdentifier.Int16 => "short",
RepresentationTypeIdentifier.Int32 => "int",
RepresentationTypeIdentifier.Int64 => "long",
RepresentationTypeIdentifier.Int8 => "sbyte",
RepresentationTypeIdentifier.String => "string",
RepresentationTypeIdentifier.Map => "Map<object, object>",
RepresentationTypeIdentifier.UInt16 => "ushort",
RepresentationTypeIdentifier.UInt32 => "uint",
RepresentationTypeIdentifier.UInt64 => "ulong",
RepresentationTypeIdentifier.UInt8 => "byte",
RepresentationTypeIdentifier.List => "object[]",
RepresentationTypeIdentifier.Resource => "IResource",
RepresentationTypeIdentifier.Record => "IRecord",
TRUIdentifier.Dynamic => "object",
TRUIdentifier.Bool => "bool",
TRUIdentifier.Char => "char",
TRUIdentifier.DateTime => "DateTime",
TRUIdentifier.Decimal => "decimal",
TRUIdentifier.Float32 => "float",
TRUIdentifier.Float64 => "double",
TRUIdentifier.Int16 => "short",
TRUIdentifier.Int32 => "int",
TRUIdentifier.Int64 => "long",
TRUIdentifier.Int8 => "sbyte",
TRUIdentifier.String => "string",
TRUIdentifier.Map => "Map<object, object>",
TRUIdentifier.UInt16 => "ushort",
TRUIdentifier.UInt32 => "uint",
TRUIdentifier.UInt64 => "ulong",
TRUIdentifier.UInt8 => "byte",
TRUIdentifier.List => "object[]",
TRUIdentifier.Resource => "IResource",
TRUIdentifier.Record => "IRecord",
_ => "object"
};
}

View File

@@ -40,7 +40,7 @@ public class Storable : global::System.Attribute
SerializerFunction serializer;
DeserializerFunction deserializer;
RepresentationType dataType;
TRU dataType;
public Storable()
{
@@ -57,12 +57,12 @@ public class Storable : global::System.Attribute
get { return serializer; }
}
public Storable(RepresentationType type)
public Storable(TRU type)
{
this.dataType = type;
}
public Storable(RepresentationType type, SerializerFunction serializer, DeserializerFunction deserializer)
public Storable(TRU type, SerializerFunction serializer, DeserializerFunction deserializer)
{
this.dataType = type;
this.serializer = serializer;

View File

@@ -11,7 +11,7 @@ public class ArgumentTemplate
public bool Optional { get; set; }
public RepresentationType Type { get; set; }
public TRU Type { get; set; }
public ParameterInfo ParameterInfo { get; set; }
@@ -24,7 +24,7 @@ public class ArgumentTemplate
var cs = (uint)data[offset++];
var name = data.GetString(offset, cs);
offset += cs;
var (size, type) = RepresentationType.Parse(data, offset);
var (size, type) = TRU.Parse(data, offset);
return (cs + 2 + size, new ArgumentTemplate(name, index, type, optional));
}
@@ -34,7 +34,7 @@ public class ArgumentTemplate
}
public ArgumentTemplate(string name, int index, RepresentationType type, bool optional)
public ArgumentTemplate(string name, int index, TRU type, bool optional)
{
Name = name;
Index = index;

View File

@@ -12,11 +12,11 @@ public class ConstantTemplate : MemberTemplate
public readonly object Value;
//public readonly byte[] ValueData;
public readonly string Annotation;
public readonly RepresentationType ValueType;
public readonly TRU ValueType;
public FieldInfo FieldInfo { get; set; }
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string annotation)
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, TRU valueType, object value, string annotation)
: base(template, index, name, inherited)
{
Annotation = annotation;
@@ -73,7 +73,7 @@ public class ConstantTemplate : MemberTemplate
{
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
var valueType = RepresentationType.FromType(ci.FieldType);
var valueType = TRU.FromType(ci.FieldType);
if (valueType == null)
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");

View File

@@ -21,7 +21,7 @@ public class EventTemplate : MemberTemplate
public EventInfo EventInfo { get; set; }
public RepresentationType ArgumentType { get; set; }
public TRU ArgumentType { get; set; }
public override byte[] Compose()
{
@@ -55,7 +55,7 @@ public class EventTemplate : MemberTemplate
.ToArray();
}
public EventTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType argumentType, string annotation = null, bool subscribable = false)
public EventTemplate(TypeTemplate template, byte index, string name, bool inherited, TRU argumentType, string annotation = null, bool subscribable = false)
: base(template, index, name, inherited)
{
this.Annotation = annotation;
@@ -75,7 +75,7 @@ public class EventTemplate : MemberTemplate
var argType = ei.EventHandlerType.GenericTypeArguments[0];
var evtType = RepresentationType.FromType(argType);
var evtType = TRU.FromType(argType);
if (evtType == null)
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");

View File

@@ -25,7 +25,7 @@ public class FunctionTemplate : MemberTemplate
// set;
//}
public RepresentationType ReturnType { get; set; }
public TRU ReturnType { get; set; }
public bool IsStatic { get; set; }
@@ -66,7 +66,7 @@ public class FunctionTemplate : MemberTemplate
return bl.ToArray();
}
public FunctionTemplate(TypeTemplate template, byte index, string name, bool inherited, bool isStatic, ArgumentTemplate[] arguments, RepresentationType returnType, string annotation = null)
public FunctionTemplate(TypeTemplate template, byte index, string name, bool inherited, bool isStatic, ArgumentTemplate[] arguments, TRU returnType, string annotation = null)
: base(template, index, name, inherited)
{
this.Arguments = arguments;
@@ -82,20 +82,20 @@ public class FunctionTemplate : MemberTemplate
var genericRtType = mi.ReturnType.IsGenericType ? mi.ReturnType.GetGenericTypeDefinition() : null;
RepresentationType rtType;
TRU rtType;
if (genericRtType == typeof(AsyncReply<>))
{
rtType = RepresentationType.FromType(mi.ReturnType.GetGenericArguments()[0]);
rtType = TRU.FromType(mi.ReturnType.GetGenericArguments()[0]);
}
else if (genericRtType == typeof(IEnumerable<>))// || genericRtType == typeof(IAsyncEnumerable<>))
{
// get export
rtType = RepresentationType.FromType(mi.ReturnType.GetGenericArguments()[0]);
rtType = TRU.FromType(mi.ReturnType.GetGenericArguments()[0]);
}
else
{
rtType = RepresentationType.FromType(mi.ReturnType);
rtType = TRU.FromType(mi.ReturnType);
}
if (rtType == null)
@@ -165,7 +165,7 @@ public class FunctionTemplate : MemberTemplate
var arguments = args.Select(x =>
{
var argType = RepresentationType.FromType(x.ParameterType);
var argType = TRU.FromType(x.ParameterType);
if (argType == null)
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");

View File

@@ -25,7 +25,7 @@ public class PropertyTemplate : MemberTemplate
set;
}
public RepresentationType ValueType { get; set; }
public TRU ValueType { get; set; }
/*
@@ -136,7 +136,7 @@ public class PropertyTemplate : MemberTemplate
}
public PropertyTemplate(TypeTemplate template, byte index, string name, bool inherited,
RepresentationType valueType, string readAnnotation = null, string writeAnnotation = null, bool recordable = false)
TRU valueType, string readAnnotation = null, string writeAnnotation = null, bool recordable = false)
: base(template, index, name, inherited)
{
this.Recordable = recordable;
@@ -152,8 +152,8 @@ public class PropertyTemplate : MemberTemplate
var genericPropType = pi.PropertyType.IsGenericType ? pi.PropertyType.GetGenericTypeDefinition() : null;
var propType = genericPropType == typeof(PropertyContext<>) ?
RepresentationType.FromType(pi.PropertyType.GetGenericArguments()[0]) :
RepresentationType.FromType(pi.PropertyType);
TRU.FromType(pi.PropertyType.GetGenericArguments()[0]) :
TRU.FromType(pi.PropertyType);
if (propType == null)
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");

View File

@@ -380,7 +380,7 @@ public class TypeTemplate
{
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
var valueType = RepresentationType.FromType(ci.FieldType);
var valueType = TRU.FromType(ci.FieldType);
if (valueType == null)
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
@@ -783,7 +783,7 @@ public class TypeTemplate
offset += (uint)data[offset] + 1;
// return type
var (rts, returnType) = RepresentationType.Parse(data, offset);
var (rts, returnType) = TRU.Parse(data, offset);
offset += rts;
// arguments count
@@ -823,7 +823,7 @@ public class TypeTemplate
offset += (uint)data[offset] + 1;
var (dts, valueType) = RepresentationType.Parse(data, offset);
var (dts, valueType) = TRU.Parse(data, offset);
offset += dts;
@@ -857,7 +857,7 @@ public class TypeTemplate
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
offset += (uint)data[offset] + 1;
var (dts, argType) = RepresentationType.Parse(data, offset);
var (dts, argType) = TRU.Parse(data, offset);
offset += dts;
@@ -883,7 +883,7 @@ public class TypeTemplate
var name = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
var (dts, valueType) = RepresentationType.Parse(data, offset);
var (dts, valueType) = TRU.Parse(data, offset);
offset += dts;