diff --git a/Esiur/Data/Codec.cs b/Esiur/Data/Codec.cs
index a8123b9..213d5e6 100644
--- a/Esiur/Data/Codec.cs
+++ b/Esiur/Data/Codec.cs
@@ -39,41 +39,42 @@ namespace Esiur.Data;
public static class Codec
{
- delegate AsyncReply Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence);
+ delegate AsyncReply AsyncParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence);
+ delegate object SyncParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence);
- static Parser[][] FixedParsers = new Parser[][]
+ static AsyncParser[][] FixedParsers = new AsyncParser[][]
{
- new Parser[]{
+ new AsyncParser[]{
DataDeserializer.NullParser,
DataDeserializer.BooleanFalseParser,
DataDeserializer.BooleanTrueParser,
DataDeserializer.NotModifiedParser,
},
- new Parser[]{
+ new AsyncParser[]{
DataDeserializer.ByteParser,
DataDeserializer.SByteParser,
DataDeserializer.Char8Parser,
},
- new Parser[]{
+ new AsyncParser[]{
DataDeserializer.Int16Parser,
DataDeserializer.UInt16Parser,
DataDeserializer.Char16Parser,
},
- new Parser[]{
+ new AsyncParser[]{
DataDeserializer.Int32Parser,
DataDeserializer.UInt32Parser,
DataDeserializer.Float32Parser,
DataDeserializer.ResourceParser,
DataDeserializer.LocalResourceParser,
},
- new Parser[]{
+ new AsyncParser[]{
DataDeserializer.Int64Parser,
DataDeserializer.UInt64Parser,
DataDeserializer.Float64Parser,
DataDeserializer.DateTimeParser,
},
- new Parser[]
+ new AsyncParser[]
{
DataDeserializer.Int128Parser, // int 128
DataDeserializer.UInt128Parser, // uint 128
@@ -81,7 +82,7 @@ public static class Codec
}
};
- static Parser[] DynamicParsers = new Parser[]
+ static AsyncParser[] DynamicParsers = new AsyncParser[]
{
DataDeserializer.RawDataParser,
DataDeserializer.StringParser,
@@ -90,7 +91,7 @@ public static class Codec
DataDeserializer.RecordListParser,
};
- static Parser[] TypedParsers = new Parser[]
+ static AsyncParser[] TypedParsers = new AsyncParser[]
{
DataDeserializer.RecordParser,
DataDeserializer.TypedListParser,
@@ -110,7 +111,7 @@ public static class Codec
/// DistributedConnection is required in case a structure in the array holds items at the other end.
/// DataType, in case the data is not prepended with DataType
/// Value
- public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType? dataType = null)
+ public static (uint, AsyncReply) ParseAsync(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType? dataType = null)
{
uint len = 0;
@@ -143,6 +144,10 @@ public static class Codec
}
}
+ public static uint ParseSync(byte[] data, uint offset, TransmissionType? dataType = null)
+ {
+
+ }
///
/// Check if a resource is local to a given connection.
diff --git a/Esiur/Data/DataDeserializer - Copy.cs b/Esiur/Data/DataDeserializer - Copy.cs
new file mode 100644
index 0000000..b702a5c
--- /dev/null
+++ b/Esiur/Data/DataDeserializer - Copy.cs
@@ -0,0 +1,562 @@
+using Esiur.Core;
+using Esiur.Net.IIP;
+using Esiur.Resource;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Esiur.Data;
+using Esiur.Resource.Template;
+using System.Linq;
+using Esiur.Misc;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace Esiur.Data;
+
+public static class DataDeserializer
+{
+ public static AsyncReply NullParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(null);
+ }
+
+ public static AsyncReply BooleanTrueParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(true);
+ }
+
+ public static AsyncReply BooleanFalseParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(false);
+ }
+
+ public static AsyncReply NotModifiedParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(new NotModified());
+ }
+
+ public static AsyncReply ByteParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(data[offset]);
+ }
+ public static AsyncReply SByteParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply((sbyte)data[offset]);
+ }
+ public static unsafe AsyncReply Char16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(char*)ptr);
+ }
+
+ public static AsyncReply Char8Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply((char)data[offset]);
+ }
+
+
+ public static unsafe AsyncReply Int16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(short*)ptr);
+ }
+
+ public static unsafe AsyncReply UInt16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(ushort*)ptr);
+ }
+
+ public static unsafe AsyncReply Int32Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(int*)ptr);
+ }
+
+ public static unsafe AsyncReply UInt32Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(uint*)ptr);
+ }
+
+ public static unsafe AsyncReply Float32Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(float*)ptr);
+ }
+
+ public static unsafe AsyncReply Float64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(double*)ptr);
+ }
+
+ public static unsafe AsyncReply Float128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(decimal*)ptr);
+ }
+
+ public static unsafe AsyncReply Int128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(decimal*)ptr);
+ }
+
+
+ public static unsafe AsyncReply UInt128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(decimal*)ptr);
+ }
+
+
+ public static unsafe AsyncReply Int64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(long*)ptr);
+ }
+
+ public static unsafe AsyncReply UInt64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(*(ulong*)ptr);
+ }
+
+ public static unsafe AsyncReply DateTimeParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return new AsyncReply(new DateTime(*(long*)ptr, DateTimeKind.Utc));
+
+ }
+
+
+ public static unsafe AsyncReply ResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return connection.Fetch(*(uint*)ptr, requestSequence);
+ }
+
+ public static unsafe AsyncReply LocalResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ fixed (byte* ptr = &data[offset])
+ return Warehouse.GetById(*(uint*)ptr);
+ }
+
+
+ public static unsafe AsyncReply RawDataParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(data.Clip(offset, length));
+ }
+
+ public static unsafe AsyncReply StringParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ return new AsyncReply(data.GetString(offset, length));
+ }
+
+ public static unsafe AsyncReply RecordParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+
+ var reply = new AsyncReply();
+
+ var classId = data.GetUUID(offset);
+ offset += 16;
+ length -= 16;
+
+
+ var template = Warehouse.GetTemplateByClassId(classId, TemplateType.Record);
+
+ var initRecord = (TypeTemplate template) =>
+ {
+ ListParser(data, offset, length, connection, requestSequence).Then(r =>
+ {
+ var ar = (object[])r;
+
+ if (template == null)
+ {
+ // @TODO: add parse if no template settings
+ reply.TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.TemplateNotFound,
+ "Template not found for record."));
+ }
+ else if (template.DefinedType != null)
+ {
+ var record = Activator.CreateInstance(template.DefinedType) as IRecord;
+ for (var i = 0; i < template.Properties.Length; i++)
+ {
+ try
+ {
+ //var v = Convert.ChangeType(ar[i], template.Properties[i].PropertyInfo.PropertyType);
+ var v = DC.CastConvert(ar[i], template.Properties[i].PropertyInfo.PropertyType);
+ template.Properties[i].PropertyInfo.SetValue(record, v);
+ }
+ catch (Exception ex)
+ {
+ Global.Log(ex);
+ }
+ }
+
+ reply.Trigger(record);
+ }
+ else
+ {
+ var record = new Record();
+
+ for (var i = 0; i < template.Properties.Length; i++)
+ record.Add(template.Properties[i].Name, ar[i]);
+
+ reply.Trigger(record);
+ }
+
+ });
+ };
+
+ if (template != null)
+ {
+ initRecord(template);
+ }
+ else if (connection != null)
+ {
+ // try to get the template from the other end
+ connection.GetTemplate(classId).Then(tmp =>
+ {
+ initRecord(tmp);
+ }).Error(x => reply.TriggerError(x));
+ }
+ else
+ {
+ initRecord(null);
+ }
+
+ return reply;
+ }
+
+ public static unsafe AsyncReply ConstantParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static unsafe AsyncReply EnumParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+
+ var classId = data.GetUUID(offset);
+ offset += 16;
+ var index = data[offset++];
+
+ var template = Warehouse.GetTemplateByClassId(classId, TemplateType.Enum);
+
+ if (template != null)
+ {
+ return new AsyncReply(template.Constants[index].Value);
+ }
+ else
+ {
+ var reply = new AsyncReply();
+
+ connection.GetTemplate(classId).Then(tmp =>
+ {
+ reply.Trigger(tmp.Constants[index].Value);
+ }).Error(x => reply.TriggerError(x));
+
+ return reply;
+ }
+ }
+
+
+
+ public static AsyncReply RecordListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ var rt = new AsyncBag();
+
+ while (length > 0)
+ {
+ var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
+
+ rt.Add(reply);
+
+ if (cs > 0)
+ {
+ offset += (uint)cs;
+ length -= (uint)cs;
+ }
+ else
+ throw new Exception("Error while parsing structured data");
+
+ }
+
+ rt.Seal();
+ return rt;
+ }
+
+ public static AsyncReply ResourceListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
+ {
+ var rt = new AsyncBag();
+
+ while (length > 0)
+ {
+ var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
+
+ rt.Add(reply);
+
+ if (cs > 0)
+ {
+ offset += (uint)cs;
+ length -= (uint)cs;
+ }
+ else
+ throw new Exception("Error while parsing structured data");
+
+ }
+
+ rt.Seal();
+ return rt;
+ }
+
+
+ public static AsyncBag