mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-09-13 12:43:17 +00:00
AsyncReply
This commit is contained in:
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user