private T DeserializeInternal <T>(byte[] bytes) where T : class, new() { _byteLevels.Add(bytes); T byteClass = new T(); var classtype = (BinaryType)typeof(T).GetTypeInfo().GetCustomAttribute(typeof(BinaryType)); if (classtype != null) { if (classtype.IsEncrypted) { if (_session.EncryptKey == null || _session.EncryptIV == null) { throw new Exception("Missing encryptKey/IV in serializationsettings."); } bytes = bytes.Decrypt(_session.EncryptKey, _session.EncryptIV); } var bytelist = new List <byte>(bytes); SerializeInfo <T> serInfo = new SerializeInfo <T>(bytes); for (int i = 0; i < serInfo.InfoElementOrderedList.Count; i++) { var current = serInfo.InfoElementOrderedList[i]; int start = current.Element.FieldOffset; if (start < bytes.Length) { var property = current.Info; int length = 0; if (current.Element.Length != -1) { length = current.Element.Length; } else { if (i + 1 != serInfo.InfoElementOrderedList.Count) { length = serInfo.InfoElementOrderedList[i + 1].Element.FieldOffset - start; } else { length = bytes.Length - start; } //todo: last one if (bytes.Length < (start + length)) { length = bytes.Length - start; } } var value = bytelist.GetRange(start, length); object setvalue = null; bool IsLittleEndian = BitConverter.IsLittleEndian; IsLittleEndian = classtype.IsLittleEndian; List <byte> EndianValue = new List <byte>(); if (IsLittleEndian) { EndianValue = value; } else { EndianValue = value.ToArray().Reverse().ToList(); } if (value != null) { if (property.PropertyType == typeof(byte)) { setvalue = EndianValue[0]; } if (property.PropertyType == typeof(byte[])) { //do nothing setvalue = EndianValue.ToArray(); } if (property.PropertyType == typeof(string)) { setvalue = Encoding.ASCII.GetString(EndianValue.ToArray()); } if (property.PropertyType == typeof(Int16)) { setvalue = EndianValue.ToArray().GetInt16(0); } if (property.PropertyType == typeof(UInt16)) { setvalue = EndianValue.ToArray().GetUInt16(0); } if (property.PropertyType == typeof(Int32)) { setvalue = EndianValue.ToArray().GetInt32(0); } if (property.PropertyType == typeof(UInt32)) { setvalue = EndianValue.ToArray().GetUInt32(0); } if (property.PropertyType == typeof(Int64)) { setvalue = EndianValue.ToArray().GetInt64(0); } if (property.PropertyType == typeof(DateTime)) { if (IsLittleEndian) { var startIndex = 0; var rtc = bytes.GetInt32(startIndex); var offset = bytes.GetInt32(startIndex + 4); setvalue = DateTimeExtension.GetDateTime(rtc, offset); } else { var startIndex = 0; var rtc = bytes.GetInt32BigE(startIndex); var offset = bytes.GetInt32BigE(startIndex + 4); setvalue = DateTimeExtension.GetDateTime(rtc, offset); } } if (property.PropertyType.GetTypeInfo().IsGenericType&& property.PropertyType.GetGenericTypeDefinition() == typeof(List <>)) { var binaryElementLists = (IEnumerable <BinaryElementList>)property.GetCustomAttributes(typeof(BinaryElementList)); if (binaryElementLists.Count() > 0) { BinaryElementList list = binaryElementLists.First(); //var listElement=Activator.CreateInstance(list.Type); var listvalue = (IList)property.GetValue(byteClass); byte listCount = (byte)serInfo.InfoElements[list.CountProperty].Info.GetValue(byteClass); int listlength = listCount * list.ByteSize; //var listbytes = value.ToList().GetRange(current.Element.FieldOffset, listlength).ToList(); var listbytes = value; List <Byte[]> splitBytes = new List <byte[]>(); for (int j = 0; j < listCount; j++) { int startindex = j * list.ByteSize; var serByte = value.ToList().GetRange(startindex, list.ByteSize); var serializerMethodes = typeof(CGM.Communication.Common.Serialize.Serializer).GetRuntimeMethods(); var generic0 = serializerMethodes.FirstOrDefault(e => e.Name == "DeserializeInternal"); var generic = generic0.MakeGenericMethod(list.Type); var elementValue = generic.Invoke(this, new object[] { serByte.ToArray() }); listvalue.Add(elementValue); } setvalue = listvalue; } } var attributes = (IEnumerable <MessageType>)property.GetCustomAttributes(typeof(MessageType)); bool containssubtype = property.PropertyType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBinaryType)); if (containssubtype || attributes.Count() > 0) { Type SeriType = null; int lengthEquals = 0; if (containssubtype) { SeriType = property.PropertyType; } if (attributes != null && attributes.Count() > 0) { foreach (var item in attributes) { lengthEquals = item.LengthEquals; if (!string.IsNullOrEmpty(item.Path)) { var prop = serInfo.InfoElements.FirstOrDefault(e => e.Value.Info.Name == item.Path); if (item.Value is IEnumerable <byte> ) { var newValue = (IEnumerable <byte>)item.Value; var validationValue = bytes.ToList().GetRange(prop.Value.Element.FieldOffset, newValue.Count()); if (validationValue.SequenceEqual(newValue)) { SeriType = item.Type; break; } } else { var propinfo = serInfo.PropertyInfos.FirstOrDefault(e => e.Name == item.Path); var validationValue = propinfo.GetValue(byteClass); if (validationValue.Equals(item.Value)) { SeriType = item.Type; break; } } } else { if (item.ReportPattern != null) { if (item.ReportPattern.Evaluate(_byteLevels[0])) { SeriType = item.Type; break; } } else { SeriType = item.Type; break; } } } } if (SeriType != null) { //if (lengthEquals != 0 && lengthEquals != value.Count) //{ // throw new Exception($"Expected length {lengthEquals}. Is {value.Count}"); //} var serializerMethodes = typeof(CGM.Communication.Common.Serialize.Serializer).GetRuntimeMethods(); var generic0 = serializerMethodes.FirstOrDefault(e => e.Name == "DeserializeInternal"); var generic = generic0.MakeGenericMethod(SeriType); setvalue = generic.Invoke(this, new object[] { value.ToArray() }); var ctors = (IEnumerable <BinaryPropertyValueTransfer>)property.GetCustomAttributes(typeof(BinaryPropertyValueTransfer)); if (ctors.Count() > 0) { foreach (var item in ctors) { var propinfo = serInfo.PropertyInfos.FirstOrDefault(e => e.Name == item.ParentPropertyName); var parentvalue = propinfo.GetValue(byteClass); setvalue.GetType().GetProperty(item.ChildPropertyName).SetValue(setvalue, parentvalue); } } } } // bool containssubtype = property.PropertyType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBinaryType)); property.SetValue(byteClass, setvalue); } } } if (typeof(T).GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBinaryDeserializationSetting))) { ((IBinaryDeserializationSetting)byteClass).OnDeserialization(bytes, _session); } return(byteClass); } return(null); }
private byte[] SerializeInternal <T>(T s) where T : class { var classtype = (BinaryType)typeof(T).GetTypeInfo().GetCustomAttribute(typeof(BinaryType)); if (classtype != null) { //var dic = GetDic(s); //var query = dic.Keys.OrderBy(e => e.FieldOffset); List <byte> temp = new List <byte>(); SerializeInfo <T> serInfo = new SerializeInfo <T>(s); bool IsLittleEndian = BitConverter.IsLittleEndian; IsLittleEndian = classtype.IsLittleEndian; foreach (var item in serInfo.InfoElementOrderedList) { var property = item.Info;// dic[item]; byte[] value = null; var getvalue = property.GetValue(s); if (getvalue != null) { var checktype = getvalue.GetType(); if (checktype == typeof(byte)) { value = new byte[] { (byte)property.GetValue(s) }; } if (checktype == typeof(UInt16)) { value = BitConverter.GetBytes((UInt16)property.GetValue(s)); } if (checktype == typeof(byte[])) { value = (byte[])property.GetValue(s); } if (checktype == typeof(string)) { value = Encoding.ASCII.GetBytes((string)property.GetValue(s)); } if (property.PropertyType.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBinaryType))) { var serializerMethodes = typeof(CGM.Communication.Common.Serialize.Serializer).GetRuntimeMethods(); var generic0 = serializerMethodes.FirstOrDefault(e => e.Name == "SerializeInternal"); var generic = generic0.MakeGenericMethod(property.PropertyType); value = (byte[])generic.Invoke(this, new object[] { getvalue }); } if (value == null && getvalue != null) { if (getvalue.GetType().GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBinaryType))) { var serializerMethodes = typeof(CGM.Communication.Common.Serialize.Serializer).GetRuntimeMethods(); var generic0 = serializerMethodes.FirstOrDefault(e => e.Name == "SerializeInternal"); var generic = generic0.MakeGenericMethod(checktype); var tempValue = (byte[])generic.Invoke(this, new object[] { getvalue }); if (IsLittleEndian == false) { value = tempValue.Reverse().ToArray(); } else { value = tempValue; } } } if (value != null) { if (IsLittleEndian == false) { value = value.Reverse().ToArray(); } if (item.Element.FieldOffset == 1000) { temp.AddRange(value); } else { temp.InsertRange(item.Element.FieldOffset, value); } } } } var logicAttributes = GetLogics <T>(s); if (logicAttributes.Count > 0) { var logicOrdered = logicAttributes.OrderBy(e => e.Logic.Order); foreach (var item in logicOrdered) { var element = serInfo.InfoElements.FirstOrDefault(e => e.Key == item.PropInfo.Name).Value; if (element != null) { item.Logic.SetValue(temp, element.Element.FieldOffset, item.PropInfo, s, _session); } // var element = (BinaryElement)item.PropInfo.GetCustomAttribute(typeof(BinaryElement)); } } if (typeof(T).GetTypeInfo().ImplementedInterfaces.Contains(typeof(IBinarySerializationSetting))) { ((IBinarySerializationSetting)s).OnSerialization(temp, _session); } if (classtype.IsEncrypted) { if (_session.EncryptKey == null || _session.EncryptIV == null) { throw new Exception("Missing encryptKey/IV in serializationsettings."); } temp = temp.ToArray().Encrypt(_session.EncryptKey, _session.EncryptIV).ToList(); } return(temp.ToArray()); } return(null); }