diff --git a/Esiur/Data/DataDeserializer.cs b/Esiur/Data/DataDeserializer.cs index 51d6b95..990c7c1 100644 --- a/Esiur/Data/DataDeserializer.cs +++ b/Esiur/Data/DataDeserializer.cs @@ -449,15 +449,15 @@ public static class DataDeserializer public static unsafe object RecordParser(ParsedTDU tdu, Warehouse warehouse) { - var classId = tdu.Metadata.GetUUID(0); - - var template = warehouse.GetTemplateByClassId(classId, TemplateType.Record); - var r = ListParser(tdu, warehouse); - var ar = (object[])r; + + + //var r = ListParser(tdu, warehouse); + + //var ar = (object[])r; if (template == null) { @@ -465,15 +465,68 @@ public static class DataDeserializer throw new AsyncException(ErrorType.Management, (ushort)ExceptionCode.TemplateNotFound, "Template not found for record."); } - else if (template.DefinedType != null) + + var list = new List(); + + ParsedTDU current; + ParsedTDU? previous = null; + + var offset = tdu.Offset; + var length = tdu.ContentLength; + var ends = offset + (uint)length; + + + for (var i = 0; i < template.Properties.Length; i++) { + 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; + } + else if (current.Identifier == TDUIdentifier.TypeOfTarget) + { + var (idf, mt) = template.Properties[i].ValueType.GetMetadata(); + current.Class = TDUClass.Typed; + current.Identifier = idf; + current.Metadata = mt; + current.Index = (int)idf & 0x7; + } + + 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"); + + } + + + + + 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); + var v = DC.CastConvert(list[i], template.Properties[i].PropertyInfo.PropertyType); template.Properties[i].PropertyInfo.SetValue(record, v); } catch (Exception ex) @@ -489,7 +542,7 @@ public static class DataDeserializer var record = new Record(); for (var i = 0; i < template.Properties.Length; i++) - record.Add(template.Properties[i].Name, ar[i]); + record.Add(template.Properties[i].Name, list[i]); return record; } @@ -690,28 +743,72 @@ public static class DataDeserializer public static object ListParser(ParsedTDU tdu, Warehouse warehouse) { - var rt = new List(); + var list = new List(); + + ParsedTDU current; + ParsedTDU? previous = null; var offset = tdu.Offset; var length = tdu.ContentLength; + var ends = offset + (uint)length; while (length > 0) { - var (cs, reply) = Codec.ParseSync(tdu.Data, offset, warehouse); + current = ParsedTDU.Parse(tdu.Data, offset, ends); - rt.Add(reply); + 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"); } - return rt.ToArray(); + return list.ToArray(); + + + + //var rt = new List(); + + //var offset = tdu.Offset; + //var length = tdu.ContentLength; + + //while (length > 0) + //{ + // var (cs, reply) = Codec.ParseSync(tdu.Data, offset, warehouse); + + // rt.Add(reply); + + // if (cs > 0) + // { + // offset += (uint)cs; + // length -= (uint)cs; + // } + // else + // throw new Exception("Error while parsing structured data"); + + //} + + //return rt.ToArray(); } @@ -1054,6 +1151,7 @@ public static class DataDeserializer // get the type var (hdrCs, rep) = TRU.Parse(tdu.Metadata, 0); + switch (rep.Identifier) { case TRUIdentifier.Int32: @@ -1100,6 +1198,14 @@ public static class DataDeserializer current.Identifier = previous.Value.Identifier; current.Metadata = previous.Value.Metadata; } + else if (current.Identifier == TDUIdentifier.TypeOfTarget) + { + var (idf, mt) = rep.GetMetadata(); + current.Class = TDUClass.Typed; + current.Identifier = idf; + current.Metadata = mt; + current.Index = (int)idf & 0x7; + } var (cs, reply) = Codec.ParseSync(current, warehouse); diff --git a/Esiur/Data/DataSerializer.cs b/Esiur/Data/DataSerializer.cs index b558622..a58d096 100644 --- a/Esiur/Data/DataSerializer.cs +++ b/Esiur/Data/DataSerializer.cs @@ -3,6 +3,7 @@ using Esiur.Data.GVWIE; using Esiur.Net.IIP; using Esiur.Resource; using Esiur.Resource.Template; +using Microsoft.CodeAnalysis; using System; using System.Buffers.Binary; using System.Collections; @@ -483,35 +484,45 @@ public static class DataSerializer public static TDU ListComposer(object value, Warehouse warehouse, DistributedConnection connection) { - if (value == null) + + var composed = DynamicArrayComposer((IEnumerable)value, warehouse, connection); + + if (composed == null) return new TDU(TDUIdentifier.Null, new byte[0], 0); - - var list = (IEnumerable)value; - - var rt = new List(); - - TDU? previous = null; - - foreach (var i in list) + else { - var tdu = Codec.ComposeInternal(i, warehouse, connection); - 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; + return new TDU(TDUIdentifier.List, composed, (uint)composed.Length); } - return new TDU(TDUIdentifier.List, rt.ToArray(), (uint)rt.Count); + //if (value == null) + // return new TDU(TDUIdentifier.Null, new byte[0], 0); + + //var list = value; + + //var rt = new List(); + + //TDU? previous = null; + + //foreach (var i in list) + //{ + // var tdu = Codec.ComposeInternal(i, warehouse, connection); + // 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; + //} + + //return new TDU(TDUIdentifier.List, rt.ToArray(), (uint)rt.Count); } diff --git a/Esiur/Data/TRU.cs b/Esiur/Data/TRU.cs index ce6af23..d5f32f1 100644 --- a/Esiur/Data/TRU.cs +++ b/Esiur/Data/TRU.cs @@ -2,6 +2,7 @@ using Esiur.Net.IIP; using Esiur.Resource; using Esiur.Resource.Template; +using Microsoft.CodeAnalysis; using System; using System.Collections; using System.Collections.Generic; @@ -208,6 +209,47 @@ namespace Esiur.Data return true; } + + public (TDUIdentifier, byte[]) GetMetadata() + { + switch (Identifier) + { + case TRUIdentifier.TypedList: + return (TDUIdentifier.TypedList, SubTypes[0].Compose()); + case TRUIdentifier.TypedRecord: + return (TDUIdentifier.Record, UUID?.Data); + case TRUIdentifier.TypedMap: + return (TDUIdentifier.TypedMap, + SubTypes[0].Compose().Concat(SubTypes[1].Compose()).ToArray()); + default: + + throw new NotImplementedException(); + } + } + + //public TDUIdentifier GetTDUIdentifer() + //{ + // switch (Identifier) + // { + + // case TRUIdentifier.TypedList: return TDUIdentifier.TypedList + + // case TRUIdentifier.Int8: return TDUIdentifier.Int8; + // case TRUIdentifier.Int16: return TDUIdentifier.Int16; + // case TRUIdentifier.Int32: return TDUIdentifier.Int32; + // case TRUIdentifier.Int64: return TDUIdentifier.Int64; + + // case TRUIdentifier.UInt8: return TDUIdentifier.UInt8; + // case TRUIdentifier.UInt16: return TDUIdentifier.UInt16; + // case TRUIdentifier.UInt32: return TDUIdentifier.UInt32; + // case TRUIdentifier.UInt64: return TDUIdentifier.UInt64; + + // case TRUIdentifier.String: return TDUIdentifier.String; + // case TRUIdentifier.Float32: return TDUIdentifier.Float32; + // case TRUIdentifier.Float64: return TDUIdentifier.Float64; + // case TRUIdentifier. } + //} + public static TRU? FromType(Type type) { if (type == null)