private static void InitNoConverterNode(Dictionary <Type, TTLVStructNode> allNodeDic, FieldInfo fieldInfo, TTLVAttribute ttlvAttribute, TTLVStructNode node) { switch (ttlvAttribute.PropertyType) { case TTLVPropertyType.Collection: Type eleType; TTLVType ttlvType; TTLVCommon.GetCollectionElementType(fieldInfo.FieldType, out eleType, out ttlvType); node.TTLVType = ttlvType; node.ElementType = eleType; CreateTypeStructTree(allNodeDic, node, eleType); break; case TTLVPropertyType.SingleObject: if (allNodeDic.ContainsKey(fieldInfo.FieldType)) { //解决递归类型,即类型同嵌套自身类型 node.RefNode = allNodeDic[fieldInfo.FieldType]; } else { allNodeDic.Add(fieldInfo.FieldType, node); node.ElementType = fieldInfo.FieldType; CreateTypeStructTree(allNodeDic, node, fieldInfo.FieldType); } node.TTLVType = TTLVType.Object; break; default: throw new NotImplementedException($"未实现的TTLVPropertyType[{ttlvAttribute.PropertyType.ToString()}]"); } }
/// <summary> /// 目标对象转换为bytes /// </summary> /// <param name="tag">标签</param> /// <param name="obj">转换对象</param> /// <param name="targetType">目标属性或字段类型</param> /// <param name="converterPara">转换器参数</param> /// <returns>转换结果</returns> public override byte[] ConvertToBytes(int tag, object obj, Type targetType, object converterPara) { Type eleType; TTLVType ttlvType; TTLVCommon.GetCollectionElementType(targetType, out eleType, out ttlvType); TypeCode typeCode = Type.GetTypeCode(eleType); if (this.IsByteArray(typeCode, targetType)) { return((byte[])obj); } else { var collection = (IEnumerable)obj; List <byte> buffer = new List <byte>(); switch (typeCode) { case TypeCode.String: this.PrimitiveStringCollectionConvertToBytes(buffer, collection, typeCode); break; default: this.PrimitiveConvertToBytes(buffer, collection, typeCode); break; } return(buffer.ToArray()); } }
private void PrimitiveReadStringCollectionValue(byte[] buffer, Type eleType, IList list, TypeCode typeCode) { int index = 0; int length; object item; while (index < buffer.Length) { length = BitConverter.ToInt32(buffer, index); index += 4; if (length == 0) { list.Add(string.Empty); } else if (length > 0) { item = TTLVCommon.ConvterBack(buffer, typeCode, index, length); index += length; list.Add(item); } else { list.Add(null); } } }
private static void DecodingBasicType(BinaryReader br, ref object obj, TTLVStructNode node, int valueLength, TypeCode valueBufferTypeCode) { byte[] valueBuffer = new byte[valueLength]; br.Read(valueBuffer, 0, valueBuffer.Length); object value = TTLVCommon.ConvterBack(valueBuffer, valueBufferTypeCode, 0, valueLength); SetTTLVNodeValue(obj, node, value); }
private void PrimitiveConvertToBytes(List <byte> buffer, IEnumerable collection, TypeCode typeCode) { foreach (var item in collection) { byte[] tmpBuffer = TTLVCommon.ConvertToBytes(typeCode, item); buffer.AddRange(tmpBuffer); } }
private void PrimitiveReadValue(byte[] buffer, int eleSize, IList list, TypeCode typeCode) { int index = 0; object item; while (index < buffer.Length) { item = TTLVCommon.ConvterBack(buffer, typeCode, index, eleSize); index += eleSize; list.Add(item); } }
private void ReadValue(byte[] buffer, Type eleType, IList list) { TypeCode typeCode = Type.GetTypeCode(eleType); switch (typeCode) { case TypeCode.String: this.PrimitiveReadStringCollectionValue(buffer, eleType, list, typeCode); break; default: this.PrimitiveReadValue(buffer, TTLVCommon.GetConvertTypeLength(typeCode), list, typeCode); break; } }
public object CreateMemberInstance() { Type type; if (this._memberType) { type = this._propertyInfo.PropertyType; } else { type = this._fieldInfo.FieldType; } TTLVCommon.CheckHasNoParaConstructor(type); return(Activator.CreateInstance(type)); }
/// <summary> /// 转换bytes到目标对象 /// </summary> /// <param name="tag">标签</param> /// <param name="buffer">byte[]</param> /// <param name="memberValue">目标属性或字段值</param> /// <param name="targetType">目标属性或字段类型</param> /// <param name="converterPara">转换器参数</param> /// <returns>解析结果对象</returns> public override object ConvertBackObject(int tag, byte[] buffer, object memberValue, Type targetType, object converterPara) { Type eleType; TTLVType ttlvType; TTLVCommon.GetCollectionElementType(targetType, out eleType, out ttlvType); TypeCode typeCode = Type.GetTypeCode(eleType); if (this.IsByteArray(typeCode, targetType)) { return(buffer); } object value; switch (ttlvType) { case TTLVType.IList: var list = (IList)memberValue; if (list == null) { list = (IList)Activator.CreateInstance(targetType); } this.ReadValue(buffer, eleType, list); value = list; break; case TTLVType.Array: IList arraList = new List <object>(); this.ReadValue(buffer, eleType, arraList); Array array = Array.CreateInstance(eleType, arraList.Count); for (int i = 0; i < arraList.Count; i++) { array.SetValue(arraList[i], i); } value = array; break; default: throw new NotImplementedException($"未实现类型[{ttlvType.ToString()}]"); } return(value); }
private void PrimitiveStringCollectionConvertToBytes(List <byte> buffer, IEnumerable collection, TypeCode typeCode) { foreach (var item in collection) { if (item == null) { buffer.AddRange(this._stringNullLengthBuffer); } else { byte[] tmpBuffer = TTLVCommon.ConvertToBytes(typeCode, item); buffer.AddRange(BitConverter.GetBytes(tmpBuffer.Length)); if (tmpBuffer.Length > 0) { buffer.AddRange(tmpBuffer); } } } }
private static void DecodingCollection(IList list, BinaryReader br, TTLVStructNode node, int valueLength) { TTLVCommon.CheckHasNoParaConstructor(node.ElementType); var endPosition = br.BaseStream.Position + valueLength; var nodeInfo = new TTLVNodeInfo(); while (br.BaseStream.Position < endPosition) { //int tag = br.ReadInt32(); //TypeCode valueBufferTypeCode = (TypeCode)br.ReadByte(); //int length = br.ReadInt32(); _codec.ReadNodeInfo(br, nodeInfo); object instance = Activator.CreateInstance(node.ElementType); PrimitiveDecoding(br, br.BaseStream.Position + nodeInfo.Length, ref instance, node.Childs); list.Add(instance); } br.BaseStream.Position = endPosition; }
private static void EncodingBasicType(List <byte> buffer, TTLVStructNode node, object objValue) { byte[] valueBuffer = TTLVCommon.ConvertToBytes(node.TypeCode, objValue); AddTTLVNodeValue(buffer, node, valueBuffer); }