diff --git a/Esiur/Data/Codec.cs b/Esiur/Data/Codec.cs index 672d2be..ededea1 100644 --- a/Esiur/Data/Codec.cs +++ b/Esiur/Data/Codec.cs @@ -338,20 +338,11 @@ public static class Codec }; - - /// - /// Compose a variable - /// - /// Value to compose. - /// DistributedConnection is required to check locality. - /// If True, prepend the DataType at the beginning of the output. - /// Array of bytes in the network byte order. - public static byte[] Compose(object valueOrSource, Warehouse warehouse, DistributedConnection connection)//, bool prependType = true) + internal static (TransmissionTypeIdentifier identifier, byte[]) + ComposeInternal(object valueOrSource, Warehouse warehouse, DistributedConnection connection) { - - if (valueOrSource == null) - return TransmissionType.Compose(TransmissionTypeIdentifier.Null, null); + return (TransmissionTypeIdentifier.Null, null); var type = valueOrSource.GetType(); @@ -377,11 +368,8 @@ public static class Codec if (valueOrSource is IUserType) valueOrSource = ((IUserType)valueOrSource).Get(); - //if (valueOrSource is Func) - // valueOrSource = (valueOrSource as Func)(connection); - if (valueOrSource == null) - return TransmissionType.Compose(TransmissionTypeIdentifier.Null, null); + return (TransmissionTypeIdentifier.Null, null); type = valueOrSource.GetType(); @@ -390,32 +378,32 @@ public static class Codec if (Composers.ContainsKey(type)) { var (hdr, data) = Composers[type](valueOrSource, warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } else { if (Codec.ImplementsInterface(type, typeof(IResource))) { var (hdr, data) = DataSerializer.ResourceComposer(valueOrSource, warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } else if (Codec.ImplementsInterface(type, typeof(IRecord))) { var (hdr, data) = DataSerializer.RecordComposer(valueOrSource, warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } else if (type.IsGenericType) { var genericType = type.GetGenericTypeDefinition(); - if (genericType == typeof(List<>) - || genericType == typeof(VarList<>) + if (genericType == typeof(List<>) + || genericType == typeof(VarList<>) || genericType == typeof(IList<>)) { var args = type.GetGenericArguments(); //if (Composers.ContainsKey(args[0])) //{ var (hdr, data) = DataSerializer.TypedListComposer((IEnumerable)valueOrSource, args[0], warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); //} } else if (genericType == typeof(Map<,>)) @@ -423,15 +411,15 @@ public static class Codec var args = type.GetGenericArguments(); var (hdr, data) = DataSerializer.TypedMapComposer(valueOrSource, args[0], args[1], warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } else if (genericType == typeof(Dictionary<,>)) { var args = type.GetGenericArguments(); - + var (hdr, data) = DataSerializer.TypedDictionaryComposer(valueOrSource, args[0], args[1], warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } @@ -444,7 +432,7 @@ public static class Codec ) { var (hdr, data) = DataSerializer.TupleComposer(valueOrSource, warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } } else if (type.IsArray) @@ -454,23 +442,35 @@ public static class Codec //if (Composers.ContainsKey(elementType)) //{ var (hdr, data) = DataSerializer.TypedListComposer((IEnumerable)valueOrSource, elementType, warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); //} } else if (type.IsEnum) { var (hdr, data) = DataSerializer.EnumComposer(valueOrSource, warehouse, connection); - return TransmissionType.Compose(hdr, data); + return (hdr, data); } } - return TransmissionType.Compose(TransmissionTypeIdentifier.Null, null); + return (TransmissionTypeIdentifier.Null, null); } + /// + /// Compose a variable + /// + /// Value to compose. + /// DistributedConnection is required to check locality. + /// If True, prepend the DataType at the beginning of the output. + /// Array of bytes in the network byte order. + public static byte[] Compose(object valueOrSource, Warehouse warehouse, DistributedConnection connection)//, bool prependType = true) + { + var (hdr, data) = ComposeInternal(valueOrSource, warehouse, connection); + return TransmissionType.Compose(hdr, data); + } public static bool IsAnonymous(Type type) { diff --git a/Esiur/Data/DataConverter.cs b/Esiur/Data/DataConverter.cs index 9f7e884..92cec05 100644 --- a/Esiur/Data/DataConverter.cs +++ b/Esiur/Data/DataConverter.cs @@ -105,9 +105,12 @@ public static class DC // Data Converter { return Convert.ChangeType(value, destinationType); } + } - catch + catch (Exception ex) { + + throw ex; return null; } } @@ -317,7 +320,7 @@ public static class DC // Data Converter - + public static byte[] ToBytes(this string value) { return Encoding.UTF8.GetBytes(value); diff --git a/Esiur/Data/DataDeserializer.cs b/Esiur/Data/DataDeserializer.cs index 71dfa4d..51961ef 100644 --- a/Esiur/Data/DataDeserializer.cs +++ b/Esiur/Data/DataDeserializer.cs @@ -1,14 +1,15 @@ using Esiur.Core; +using Esiur.Data; +using Esiur.Misc; using Esiur.Net.IIP; using Esiur.Resource; +using Esiur.Resource.Template; +using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.Collections.Generic; -using System.Text; -using Esiur.Data; -using Esiur.Resource.Template; +using System.ComponentModel.DataAnnotations; using System.Linq; -using Esiur.Misc; -using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Text; namespace Esiur.Data; @@ -676,8 +677,20 @@ public static class DataDeserializer { var rt = new List(); + //TransmissionTypeIdentifier? previous = null; + //byte[]? previousUUID = null; + + TransmissionType? previous = null; + while (length > 0) { + var (longLen, dataType) = TransmissionType.Parse(data, offset, (uint)data.Length); + + if (dataType.Value.Identifier == TransmissionTypeIdentifier.Same) + { + // Add UUID + } + var (cs, reply) = Codec.ParseSync(data, offset, warehouse); rt.Add(reply); diff --git a/Esiur/Data/DataSerializer.cs b/Esiur/Data/DataSerializer.cs index 51eeae9..d3f03b1 100644 --- a/Esiur/Data/DataSerializer.cs +++ b/Esiur/Data/DataSerializer.cs @@ -225,7 +225,7 @@ public static class DataSerializer return (TransmissionTypeIdentifier.Null, new byte[0]); var header = RepresentationType.FromType(type).Compose(); - + var rt = new List(); rt.AddRange(header); @@ -320,8 +320,33 @@ public static class DataSerializer var rt = new List(); + TransmissionTypeIdentifier? previous = null; + byte[]? previousUUID = null; + foreach (var i in value) + { + var (hdr, data) = Codec.ComposeInternal(i, warehouse, connection); + if (previous == null) + previous = hdr; + else if (hdr == previous) + { + if (hdr == TransmissionTypeIdentifier.Record) + { + var newUUID = data.Take(16).ToArray(); + // check same uuid + if (newUUID.SequenceEqual(previousUUID)) + rt.AddRange(TransmissionType.Compose(TransmissionTypeIdentifier.Same, + data.Skip(16).ToArray())); + else + rt.AddRange(TransmissionType.Compose(hdr, data)); + + previous = hdr; + previousUUID = newUUID; + } + } + rt.AddRange(Codec.Compose(i, warehouse, connection)); + } return rt.ToArray(); } diff --git a/Esiur/Data/Map.cs b/Esiur/Data/Map.cs index 2865ad2..473173f 100644 --- a/Esiur/Data/Map.cs +++ b/Esiur/Data/Map.cs @@ -22,17 +22,18 @@ SOFTWARE. */ +using Esiur.Core; +using Esiur.Data; +using Esiur.Misc; +using Esiur.Net.IIP; using System; using System.Collections; using System.Collections.Generic; +using System.Dynamic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; -using Esiur.Data; -using Esiur.Misc; -using Esiur.Core; -using System.Reflection; -using System.Dynamic; namespace Esiur.Data; @@ -54,69 +55,70 @@ namespace Esiur.Data; public interface IMap { public void Add(object key, object value); - public void Remove(object key); - public void Clear(); - public bool ContainsKey(object key); + //public void Remove(object key); + //public void Clear(); + //public bool ContainsKey(object key); public object[] Serialize(); } -public class Map : IEnumerable>, IMap +public class Map : Dictionary, IMap // IEnumerable> { - private Dictionary dic = new Dictionary(); + //private Dictionary dic = new Dictionary(); private object syncRoot = new object(); - // Change map types + //public static implicit operator Map(Dictionary dictionary) + // => new Map() { dic = dictionary }; + + //public static implicit operator Dictionary(Map map) + // => map.ToDictionary(); + + //Change map types public Map Select (Func, KeyValuePair> selector) { var rt = new Map(); - foreach(var kv in dic) + foreach (var kv in this) { var nt = selector(kv); - rt.dic.Add(nt.Key, nt.Value); + rt.Add(nt.Key, nt.Value); } return rt; } - public bool ContainsKey(KT key) - { - return dic.ContainsKey(key); - } + //public bool ContainsKey(KT key) + //{ + // return dic.ContainsKey(key); + //} public override string ToString() { var rt = ""; - foreach (var kv in dic) + foreach (var kv in this) rt += kv.Key + ": " + kv.Value.ToString() + " \r\n"; return rt.TrimEnd('\r', '\n'); } - public Map(Map source) - { - dic = source.dic; - } + //public Map(Map source) + //{ + // dic = source.dic; + //} public Map() { } - public static Map FromMap(Map source, Type destinationType) - { - var rt = Activator.CreateInstance(destinationType) as Map; - rt.dic = source.dic; - return rt; - } - - //public static T FromStructure(Map source) where T : Map + //public static Map FromMap(Map source, Type destinationType) //{ - // var rt = Activator.CreateInstance(); + // var rt = Activator.CreateInstance(destinationType) as Map; // rt.dic = source.dic; // return rt; //} + + // public static explicit operator Map(ExpandoObject obj) => FromDynamic(obj); public static Map FromDynamic(ExpandoObject obj) @@ -127,10 +129,10 @@ public class Map : IEnumerable>, IMap return rt; } - public static Map FromDictionary(Dictionary dictionary) - => new Map() { dic = dictionary }; + //public static Map FromDictionary(Dictionary dictionary) + // => new Map() { dic = dictionary }; - public Dictionary ToDictionary() => dic; + //public Dictionary ToDictionary() => dic; public static Map FromObject(object obj) { @@ -169,68 +171,65 @@ public class Map : IEnumerable>, IMap // // return null; } - public IEnumerator> GetEnumerator() - { - return dic.GetEnumerator(); - } + //public IEnumerator> GetEnumerator() + //{ + // return dic.GetEnumerator(); + //} - IEnumerator IEnumerable.GetEnumerator() - { - return dic.GetEnumerator(); - } + //IEnumerator IEnumerable.GetEnumerator() + //{ + // return dic.GetEnumerator(); + //} - public int Length - { - get { return dic.Count; } - } + //public int Length + //{ + // get { return dic.Count; } + //} - public KeyValuePair At(int index) - { - return dic.ElementAt(index); - } + //public KeyValuePair At(int index) + //{ + // return dic.ElementAt(index); + //} public object SyncRoot { get { return syncRoot; } } - public KT[] GetKeys() => dic.Keys.ToArray();//GetKeys() - //{ - // return dic.Keys.ToArray(); - //} + //public KT[] GetKeys() => dic.Keys.ToArray(); - public void Add(KT key, VT value) - { - if (dic.ContainsKey(key)) - dic[key] = value; - else - dic.Add(key, value); - } + //public void Add(KT key, VT value) + //{ + // if (dic.ContainsKey(key)) + // dic[key] = value; + // else + // dic.Add(key, value); + // } public void Add(object key, object value) { - Add((KT)key, (VT)value); + base.Add((KT)key, (VT)value); } - public void Remove(object key) - { - Remove((KT)key); - } + //public void Remove(object key) + //{ + // Remove((KT)key); + //} - public void Clear() - { - dic.Clear(); - } + //public void Clear() + //{ + // dic.Clear(); + //} - public bool ContainsKey(object key) - { - return ContainsKey((KT)key); - } + //public bool ContainsKey(object key) + //{ + // return ContainsKey((KT)key); + //} public object[] Serialize() { var rt = new List(); - foreach(var kv in dic) + foreach(var kv in this) { rt.Add(kv.Key); rt.Add(kv.Value); @@ -239,22 +238,22 @@ public class Map : IEnumerable>, IMap return rt.ToArray(); } - public VT this[KT index] - { - get - { - if (dic.ContainsKey(index)) - return dic[index]; - else - return default; - } - set - { - if (dic.ContainsKey(index)) - dic[index] = value; - else - dic.Add(index, value); - } - } + //public VT this[KT index] + //{ + // get + // { + // if (dic.ContainsKey(index)) + // return dic[index]; + // else + // return default; + // } + // set + // { + // if (dic.ContainsKey(index)) + // dic[index] = value; + // else + // dic.Add(index, value); + // } + //} } diff --git a/Esiur/Data/RepresentationType.cs b/Esiur/Data/RepresentationType.cs index 716db8c..fc40733 100644 --- a/Esiur/Data/RepresentationType.cs +++ b/Esiur/Data/RepresentationType.cs @@ -76,6 +76,46 @@ namespace Esiur.Data RepresentationTypeIdentifier.TypedResource }; + static Map typesMap = new Map() + { + [TransmissionTypeIdentifier.UInt8] = RepresentationTypeIdentifier.UInt8, + [TransmissionTypeIdentifier.Int8] = RepresentationTypeIdentifier.Int8, + [TransmissionTypeIdentifier.UInt16] = RepresentationTypeIdentifier.UInt16, + [TransmissionTypeIdentifier.Int16] = RepresentationTypeIdentifier.Int16, + [TransmissionTypeIdentifier.UInt32] = RepresentationTypeIdentifier.UInt32, + [TransmissionTypeIdentifier.Int32] = RepresentationTypeIdentifier.Int32, + [TransmissionTypeIdentifier.UInt64] = RepresentationTypeIdentifier.UInt64, + [TransmissionTypeIdentifier.Int64] = RepresentationTypeIdentifier.Int64, + [TransmissionTypeIdentifier.UInt128] = RepresentationTypeIdentifier.UInt128, + [TransmissionTypeIdentifier.Int128] = RepresentationTypeIdentifier.Int128, + [TransmissionTypeIdentifier.Char8] = RepresentationTypeIdentifier.Char, + [TransmissionTypeIdentifier.DateTime] = RepresentationTypeIdentifier.DateTime, + [TransmissionTypeIdentifier.Float32] = RepresentationTypeIdentifier.Float32, + [TransmissionTypeIdentifier.Float64] = RepresentationTypeIdentifier.Float64, + [TransmissionTypeIdentifier.Decimal128] = RepresentationTypeIdentifier.Decimal, + [TransmissionTypeIdentifier.False] = RepresentationTypeIdentifier.Bool, + [TransmissionTypeIdentifier.True] = RepresentationTypeIdentifier.Bool, + [TransmissionTypeIdentifier.Map] = RepresentationTypeIdentifier.Map, + [TransmissionTypeIdentifier.List] = RepresentationTypeIdentifier.List, + [TransmissionTypeIdentifier.RawData] = RepresentationTypeIdentifier.RawData, + [TransmissionTypeIdentifier.Record] = RepresentationTypeIdentifier.Record, + [TransmissionTypeIdentifier.String] = RepresentationTypeIdentifier.String, + }; + + public bool IsCompatible(TransmissionType tdu) + { + var tru = typesMap[tdu.Identifier]; + + if (tru != Identifier) + return false; + + if (tdu.Class == TransmissionTypeClass.Typed) + { + if (tdu.Identifier == TransmissionTypeIdentifier.) + } + return true; + } + public void SetNull(List flags) { if (refTypes.Contains(Identifier)) diff --git a/Esiur/Data/TransmissionType.cs b/Esiur/Data/TransmissionType.cs index fa2068d..a1d5437 100644 --- a/Esiur/Data/TransmissionType.cs +++ b/Esiur/Data/TransmissionType.cs @@ -56,7 +56,9 @@ public enum TransmissionTypeIdentifier : byte TypedEnum = 0x84, TypedConstant = 0x85, - ResourceLink = 0xC0 + ResourceLink = 0xC0, + + Same = 0xFF } public enum TransmissionTypeClass