2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-09-13 12:43:17 +00:00

AsyncReply

This commit is contained in:
2025-08-19 15:24:05 +03:00
parent 39da379569
commit 46b7744852
15 changed files with 1473 additions and 1721 deletions

View File

@@ -47,47 +47,110 @@ public static class Codec
static AsyncParser[][] FixedAsyncParsers = new AsyncParser[][]
{
new AsyncParser[]{
DataDeserializer.NullParserAsync,
DataDeserializer.BooleanFalseParserAsync,
DataDeserializer.BooleanTrueParserAsync,
DataDeserializer.NotModifiedParserAsync,
},
new AsyncParser[]{
DataDeserializer.UInt8ParserAsync,
DataDeserializer.Int8ParserAsync,
DataDeserializer.Char8ParserAsync,
DataDeserializer.LocalResourceParser8Async,
DataDeserializer.ResourceParser8Async,
},
new AsyncParser[]{
DataDeserializer.Int16ParserAsync,
DataDeserializer.UInt16ParserAsync,
DataDeserializer.Char16ParserAsync,
DataDeserializer.LocalResourceParser16Async,
DataDeserializer.ResourceParser16Async,
},
new AsyncParser[]{
DataDeserializer.Int32ParserAsync,
DataDeserializer.UInt32ParserAsync,
DataDeserializer.Float32ParserAsync,
DataDeserializer.LocalResourceParser32Async,
DataDeserializer.ResourceParser32Async,
},
new AsyncParser[]{
DataDeserializer.Int64ParserAsync,
DataDeserializer.UInt64ParserAsync,
DataDeserializer.Float64ParserAsync,
DataDeserializer.DateTimeParserAsync,
},
new AsyncParser[]
{
DataDeserializer.Int128ParserAsync, // int 128
DataDeserializer.UInt128ParserAsync, // uint 128
DataDeserializer.Float128ParserAsync,
}
};
static AsyncParser[] DynamicAsyncParsers = new AsyncParser[]
{
DataDeserializer.RawDataParserAsync,
DataDeserializer.StringParserAsync,
DataDeserializer.ListParserAsync,
DataDeserializer.ResourceListParserAsync,
DataDeserializer.RecordListParserAsync,
};
static AsyncParser[] TypedAsyncParsers = new AsyncParser[]
{
DataDeserializer.RecordParserAsync,
DataDeserializer.TypedListParserAsync,
DataDeserializer.TypedMapParserAsync,
DataDeserializer.TupleParserAsync,
DataDeserializer.EnumParserAsync,
DataDeserializer.ConstantParserAsync,
};
static SyncParser[][] FixedParsers = new SyncParser[][]
{
new SyncParser[]{
DataDeserializer.NullParser,
DataDeserializer.BooleanFalseParser,
DataDeserializer.BooleanTrueParser,
DataDeserializer.NotModifiedParser,
},
new AsyncParser[]{
DataDeserializer.ByteParser,
DataDeserializer.SByteParser,
new SyncParser[]{
DataDeserializer.UInt8Parser,
DataDeserializer.Int8Parser,
DataDeserializer.Char8Parser,
DataDeserializer.LocalResourceParser8,
DataDeserializer.ResourceParser8,
},
new AsyncParser[]{
new SyncParser[]{
DataDeserializer.Int16Parser,
DataDeserializer.UInt16Parser,
DataDeserializer.Char16Parser,
DataDeserializer.LocalResourceParser16,
DataDeserializer.ResourceParser16,
},
new AsyncParser[]{
new SyncParser[]{
DataDeserializer.Int32Parser,
DataDeserializer.UInt32Parser,
DataDeserializer.Float32Parser,
DataDeserializer.LocalResourceParser32,
DataDeserializer.ResourceParser32,
},
new AsyncParser[]{
new SyncParser[]{
DataDeserializer.Int64Parser,
DataDeserializer.UInt64Parser,
DataDeserializer.Float64Parser,
DataDeserializer.DateTimeParser,
},
new AsyncParser[]
new SyncParser[]
{
DataDeserializer.Int128Parser, // int 128
DataDeserializer.UInt128Parser, // uint 128
DataDeserializer.Float128Parser,
}
};
};
static AsyncParser[] DynamicAsyncParsers = new AsyncParser[]
static SyncParser[] DynamicParsers = new SyncParser[]
{
DataDeserializer.RawDataParser,
DataDeserializer.StringParser,
@@ -96,7 +159,7 @@ public static class Codec
DataDeserializer.RecordListParser,
};
static AsyncParser[] TypedAsyncParsers = new AsyncParser[]
static SyncParser[] TypedParsers = new SyncParser[]
{
DataDeserializer.RecordParser,
DataDeserializer.TypedListParser,
@@ -106,7 +169,6 @@ public static class Codec
DataDeserializer.ConstantParser,
};
/// <summary>
/// Parse a value
/// </summary>
@@ -246,15 +308,15 @@ public static class Codec
[typeof(IResource[])] = DataSerializer.ResourceListComposer,
[typeof(IResource?[])] = DataSerializer.ResourceListComposer,
[typeof(List<IResource>)] = DataSerializer.ResourceListComposer,
[typeof(List<IResource?>)] = DataSerializer.ResourceListComposer,
[typeof(VarList<IResource>)] = DataSerializer.ResourceListComposer,
[typeof(VarList<IResource?>)] = DataSerializer.ResourceListComposer,
[typeof(List<IResource?>)] = DataSerializer.ResourceListComposer,
[typeof(VarList<IResource>)] = DataSerializer.ResourceListComposer,
[typeof(VarList<IResource?>)] = DataSerializer.ResourceListComposer,
[typeof(IRecord[])] = DataSerializer.RecordListComposer,
[typeof(IRecord?[])] = DataSerializer.RecordListComposer,
[typeof(List<IRecord>)] = DataSerializer.RecordListComposer,
[typeof(List<IRecord?>)] = DataSerializer.RecordListComposer,
[typeof(VarList<IRecord>)] = DataSerializer.RecordListComposer,
[typeof(VarList<IRecord?>)] = DataSerializer.RecordListComposer,
[typeof(VarList<IRecord?>)] = DataSerializer.RecordListComposer,
[typeof(Map<object, object>)] = DataSerializer.MapComposer,
[typeof(Map<object?, object>)] = DataSerializer.MapComposer,
[typeof(Map<object, object?>)] = DataSerializer.MapComposer,

View File

@@ -373,7 +373,7 @@ public static class DataDeserializer
var initRecord = (TypeTemplate template) =>
{
ListParser(data, offset, length, connection, requestSequence).Then(r =>
ListParserAsync(data, offset, length, connection, requestSequence).Then(r =>
{
var ar = (object[])r;
@@ -684,6 +684,31 @@ public static class DataDeserializer
return rt.ToArray();
}
public static (uint, ulong, object[]) LimitedCountListParser(byte[] data, uint offset, ulong length, uint countLimit = uint.MaxValue)
{
var rt = new List<object>();
while (length > 0 && rt.Count < countLimit)
{
var (cs, reply) = Codec.ParseSync(data, offset);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
return (offset, length, rt.ToArray());
}
public static AsyncReply TypedMapParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
{
// get key type
@@ -826,6 +851,21 @@ public static class DataDeserializer
var type = typeof(ValueTuple<,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
}
else if (ar.Length == 5)
{
var type = typeof(ValueTuple<,,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4]));
}
else if (ar.Length == 6)
{
var type = typeof(ValueTuple<,,,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4], ar[5]));
}
else if (ar.Length == 7)
{
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3], ar[4], ar[5], ar[6]));
}
});
return rt;
@@ -896,9 +936,12 @@ public static class DataDeserializer
var type = typeof(ValueTuple<,,,,,,>).MakeGenericType(types.ToArray());
return Activator.CreateInstance(type, results[0], results[1], results[2], results[3], results[4], results[5], results[6]);
}
throw new Exception("Unknown tuple length.");
}
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
public static AsyncReply TypedListParserAsync(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<object>();
@@ -932,13 +975,47 @@ public static class DataDeserializer
return rt;
}
public static object TypedListParser(byte[] data, uint offset, uint length)
{
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
// get the type
var (hdrCs, rep) = RepresentationType.Parse(data, offset);
offset += hdrCs;
length -= hdrCs;
var runtimeType = rep.GetRuntimeType();
var list = new List<object>();
while (length > 0)
{
var (cs, reply) = Codec.ParseSync(data, offset);
list.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
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)
{
var rt = new AsyncBag<PropertyValue>();
ListParser(data, offset, length, connection, requestSequence).Then(x =>
ListParserAsync(data, offset, length, connection, requestSequence).Then(x =>
{
var ar = (object[])x;
var pvs = new List<PropertyValue>();
@@ -954,7 +1031,8 @@ public static class DataDeserializer
}
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
public static (uint, AsyncReply<PropertyValue>) PropertyValueParserAsync(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
{
var reply = new AsyncReply<PropertyValue>();
@@ -967,15 +1045,22 @@ public static class DataDeserializer
var (valueSize, results) = Codec.ParseAsync(data, offset, connection, requestSequence);
results.Then(value =>
if (results is AsyncReply)
{
reply.Trigger(new PropertyValue(value, age, date));
});
(results as AsyncReply).Then(value =>
{
reply.Trigger(new PropertyValue(value, age, date));
});
}
else
{
reply.Trigger(new PropertyValue(results, age, date));
}
return (16 + valueSize, reply);
}
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParserAsync(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
{
//var count = (int)toAge - (int)fromAge;
@@ -994,7 +1079,7 @@ public static class DataDeserializer
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
var (len, pv) = PropertyValueParser(data, offset, connection, requestSequence);
var (len, pv) = PropertyValueParserAsync(data, offset, connection, requestSequence);
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
offset += len;

View File

@@ -102,7 +102,7 @@ public static class DataSerializer
var rt = new byte[16];
fixed (byte* ptr = rt)
*((decimal*)ptr) = v;
return (TransmissionTypeIdentifier.Float128, rt);
return (TransmissionTypeIdentifier.Decimal128, rt);
}
@@ -122,7 +122,7 @@ public static class DataSerializer
var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode());
var ct = template.Constants.FirstOrDefault(x => x.Value.Equals(intVal));
if (ct == null)
return (TransmissionTypeIdentifier.Null, new byte[0]);
@@ -131,7 +131,7 @@ public static class DataSerializer
rt.AddRange(template.ClassId.Data);
rt.Add(ct.Index);
return (TransmissionTypeIdentifier.Enum, rt.ToArray());
return (TransmissionTypeIdentifier.TypedEnum, rt.ToArray());
}
public static (TransmissionTypeIdentifier, byte[]) UInt8Composer(object value, DistributedConnection connection)
@@ -146,7 +146,7 @@ public static class DataSerializer
public static unsafe (TransmissionTypeIdentifier, byte[]) Char8Composer(object value, DistributedConnection connection)
{
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
}
public static unsafe (TransmissionTypeIdentifier, byte[]) Char16Composer(object value, DistributedConnection connection)
@@ -241,7 +241,7 @@ public static class DataSerializer
// .ToArray();
//}
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
{
if (value == null)
return (TransmissionTypeIdentifier.Null, new byte[0]);
@@ -274,9 +274,9 @@ public static class DataSerializer
var map = (IMap)value;
foreach(var el in map.Serialize())
foreach (var el in map.Serialize())
rt.AddRange(Codec.Compose(el, connection));
return (TransmissionTypeIdentifier.TypedMap, rt.ToArray());
}
@@ -315,32 +315,59 @@ public static class DataSerializer
public static unsafe (TransmissionTypeIdentifier, byte[]) ResourceComposer(object value, DistributedConnection connection)
{
var resource = (IResource)value;
var rt = new byte[4];
if (resource.Instance == null || resource.Instance.IsDestroyed)
if (resource.Instance == null || resource.Instance.IsDestroyed)
{
return (TransmissionTypeIdentifier.Null, new byte[0]);
}
if (Codec.IsLocalResource(resource, connection))
{
var rid = (resource as DistributedResource).DistributedResourceInstanceId;
fixed (byte* ptr = rt)
*((uint*)ptr) = (resource as DistributedResource).DistributedResourceInstanceId;
if (rid <= 0xFF)
return (TransmissionTypeIdentifier.LocalResource8, new byte[] { (byte)rid });
else if (rid <= 0xFFFF)
{
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = (ushort)rid;
return (TransmissionTypeIdentifier.ResourceLocal, rt);
return (TransmissionTypeIdentifier.LocalResource16, rt);
}
else
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = rid;
return (TransmissionTypeIdentifier.LocalResource32, rt);
}
}
else
{
//rt.Append((value as IResource).Instance.Template.ClassId, (value as IResource).Instance.Id);
connection.cache.Add(value as IResource, DateTime.UtcNow);
fixed (byte* ptr = rt)
*((uint*)ptr) = resource.Instance.Id;
var rid = resource.Instance.Id;
return (TransmissionTypeIdentifier.Resource, rt);
if (rid <= 0xFF)
return (TransmissionTypeIdentifier.RemoteResource8, new byte[] { (byte)rid });
else if (rid <= 0xFFFF)
{
var rt = new byte[2];
fixed (byte* ptr = rt)
*((ushort*)ptr) = (ushort)rid;
return (TransmissionTypeIdentifier.RemoteResource16, rt);
}
else
{
var rt = new byte[4];
fixed (byte* ptr = rt)
*((uint*)ptr) = rid;
return (TransmissionTypeIdentifier.RemoteResource32, rt);
}
}
}
@@ -400,7 +427,7 @@ public static class DataSerializer
var rt = new List<byte>();
var fields = value.GetType().GetFields();
var list = fields.Select(x => x.GetValue(value)).ToArray();
var list = fields.Select(x => x.GetValue(value)).ToArray();
var types = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();
rt.Add((byte)list.Length);
@@ -415,7 +442,7 @@ public static class DataSerializer
else
{
rt.AddRange(composed);
return (TransmissionTypeIdentifier.Tuple, rt.ToArray());
return (TransmissionTypeIdentifier.TypedTuple, rt.ToArray());
}
}
}