SerializableType GetOrCompileType(Type type, bool describedOnly) { SerializableType serialiableType = null; if (!this.TryGetSerializableType(type, out serialiableType)) { serialiableType = this.CompileType(type, describedOnly); if (serialiableType != null) { this.customTypeCache.TryAdd(type, serialiableType); } } if (serialiableType == null) { throw new NotSupportedException(type.FullName); } return(serialiableType); }
public override int WriteMembers(ByteBuffer buffer, object container) { int count = 0; foreach (SerialiableMember member in this.Members) { AmqpCodec.EncodeSymbol(member.Name, buffer); object memberValue = member.Accessor.Get(container); SerializableType effectiveType = member.Type; if (!effectiveType.Final && memberValue.GetType() != effectiveType.type) { effectiveType = this.serializer.GetType(memberValue.GetType()); } effectiveType.WriteObject(buffer, memberValue); count += 2; } return(count); }
public override int WriteMembers(ByteBuffer buffer, object container) { foreach (SerialiableMember member in this.Members) { object memberValue = member.Accessor.Get(container); if (memberValue == null) { AmqpEncoding.EncodeNull(buffer); } else { SerializableType effectiveType = member.Type; if (!effectiveType.Final && memberValue.GetType() != effectiveType.type) { effectiveType = this.serializer.GetType(memberValue.GetType()); } effectiveType.WriteObject(buffer, memberValue); } } return(this.Members.Length); }
public override int WriteMembers(ByteBuffer buffer, object container) { int count = 0; foreach (object item in (IEnumerable)container) { if (item == null) { AmqpEncoding.EncodeNull(buffer); } else { SerializableType effectiveType = this.itemType; if (item.GetType() != effectiveType.type) { effectiveType = this.serializer.GetType(item.GetType()); } effectiveType.WriteObject(buffer, item); } ++count; } return(count); }
public override int WriteMembers(ByteBuffer buffer, object container) { int count = 0; foreach (object item in (IEnumerable)container) { object key = this.keyAccessor.Get(item); object value = this.valueAccessor.Get(item); if (value != null) { this.keyType.WriteObject(buffer, key); SerializableType effectiveType = this.valueType; if (value.GetType() != effectiveType.type) { effectiveType = this.serializer.GetType(value.GetType()); } effectiveType.WriteObject(buffer, value); count += 2; } } return(count); }
SerializableType CompileType(Type type, bool describedOnly) { var typeAttributes = type.GetTypeInfo().GetCustomAttributes(typeof(AmqpContractAttribute), false); if (!typeAttributes.Any()) { if (describedOnly) { return(null); } else { return(CompileNonContractTypes(type)); } } AmqpContractAttribute contractAttribute = (AmqpContractAttribute)typeAttributes.First(); SerializableType baseType = null; if (type.GetTypeInfo().BaseType != typeof(object)) { baseType = this.CompileType(type.GetTypeInfo().BaseType, true); if (baseType != null) { if (baseType.Encoding != contractAttribute.Encoding) { throw new SerializationException(AmqpResources.GetString(AmqpResources.AmqpEncodingTypeMismatch, type.Name, contractAttribute.Encoding, type.GetTypeInfo().BaseType.Name, baseType.Encoding)); } this.customTypeCache.TryAdd(type.GetTypeInfo().BaseType, baseType); } } string descriptorName = contractAttribute.Name; ulong? descriptorCode = contractAttribute.InternalCode; if (descriptorName == null && descriptorCode == null) { descriptorName = type.FullName; } List <SerialiableMember> memberList = new List <SerialiableMember>(); if (contractAttribute.Encoding == EncodingType.List && baseType != null) { memberList.AddRange(baseType.Members); } int lastOrder = memberList.Count + 1; MemberInfo[] memberInfos = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); MethodAccessor onDeserialized = null; foreach (MemberInfo memberInfo in memberInfos) { if (memberInfo.DeclaringType != type) { continue; } if (memberInfo is FieldInfo || memberInfo is PropertyInfo) { var memberAttributes = memberInfo.GetCustomAttributes(typeof(AmqpMemberAttribute), true); if (memberAttributes.Count() != 1) { continue; } AmqpMemberAttribute attribute = (AmqpMemberAttribute)memberAttributes.First(); SerialiableMember member = new SerialiableMember(); member.Name = attribute.Name ?? memberInfo.Name; member.Order = attribute.InternalOrder ?? lastOrder++; member.Mandatory = attribute.Mandatory; member.Accessor = MemberAccessor.Create(memberInfo, true); // This will recursively resolve member types Type memberType = memberInfo is FieldInfo ? ((FieldInfo)memberInfo).FieldType : ((PropertyInfo)memberInfo).PropertyType; member.Type = GetType(memberType); memberList.Add(member); } else if (memberInfo is MethodInfo) { var memberAttributes = memberInfo.GetCustomAttributes(typeof(OnDeserializedAttribute), false); if (memberAttributes.Count() == 1) { onDeserialized = MethodAccessor.Create((MethodInfo)memberInfo); } } } if (contractAttribute.Encoding == EncodingType.List) { memberList.Sort(MemberOrderComparer.Instance); int order = -1; foreach (SerialiableMember member in memberList) { if (order > 0 && member.Order == order) { throw new SerializationException(AmqpResources.GetString(AmqpResources.AmqpDuplicateMemberOrder, order, type.Name)); } order = member.Order; } } SerialiableMember[] members = memberList.ToArray(); Dictionary <Type, SerializableType> knownTypes = null; foreach (object o in type.GetTypeInfo().GetCustomAttributes(typeof(KnownTypeAttribute), false)) { KnownTypeAttribute knownAttribute = (KnownTypeAttribute)o; if (knownAttribute.Type.GetTypeInfo().GetCustomAttributes(typeof(AmqpContractAttribute), false).Any()) { if (knownTypes == null) { knownTypes = new Dictionary <Type, SerializableType>(); } // KnownType compilation is delayed and non-recursive to avoid circular references knownTypes.Add(knownAttribute.Type, null); } } if (contractAttribute.Encoding == EncodingType.List) { return(SerializableType.CreateDescribedListType(this, type, baseType, descriptorName, descriptorCode, members, knownTypes, onDeserialized)); } else if (contractAttribute.Encoding == EncodingType.Map) { return(SerializableType.CreateDescribedMapType(this, type, baseType, descriptorName, descriptorCode, members, knownTypes, onDeserialized)); } else { throw new NotSupportedException(contractAttribute.Encoding.ToString()); } }
internal TAs ReadObjectInternal <T, TAs>(ByteBuffer buffer) { SerializableType type = this.GetType(typeof(T)); return((TAs)type.ReadObject(buffer)); }
public CompositeMap( AmqpContractSerializer serializer, Type type, SerializableType baseType, string descriptorName, ulong? descriptorCode, SerialiableMember[] members, Dictionary<Type, SerializableType> knownTypes, MethodAccessor onDesrialized) : base(serializer, type, baseType, descriptorName, descriptorCode, members, knownTypes, onDesrialized) { this.EncodingType = EncodingType.Map; }
protected Composite( AmqpContractSerializer serializer, Type type, SerializableType baseType, string descriptorName, ulong? descriptorCode, SerialiableMember[] members, Dictionary<Type, SerializableType> knownTypes, MethodAccessor onDesrialized) : base(serializer, type) { this.AmqpType = AmqpType.Composite; this.baseType = (Composite)baseType; this.descriptorName = descriptorName; this.descriptorCode = descriptorCode; this.members = members; this.onDeserialized = onDesrialized; this.knownTypes = GetKnownTypes(knownTypes); }
public Map(AmqpContractSerializer serializer, Type type, MemberAccessor keyAccessor, MemberAccessor valueAccessor, MethodAccessor addAccessor) : base(serializer, type) { this.AmqpType = AmqpType.Primitive; this.keyType = this.serializer.GetType(keyAccessor.Type); this.valueType = this.serializer.GetType(valueAccessor.Type); this.keyAccessor = keyAccessor; this.valueAccessor = valueAccessor; this.addMethodAccessor = addAccessor; }
public List(AmqpContractSerializer serializer, Type type, Type itemType, MethodAccessor addAccessor) : base(serializer, type) { this.AmqpType = AmqpType.Primitive; this.itemType = serializer.GetType(itemType); this.addMethodAccessor = addAccessor; }
SerializableType CompileNonContractTypes(Type type) { if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(Nullable <>)) { Type[] argTypes = type.GetGenericArguments(); Fx.Assert(argTypes.Length == 1, "Nullable type must have one argument"); return(this.GetType(argTypes[0])); } if (type.GetTypeInfo().IsInterface) { if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) { // if a member is defined as enumerable interface, we have to change it // to list, otherwise the decoder cannot initialize an object of an interface Type itemType = typeof(object); Type listType = typeof(List <object>); if (type.GetTypeInfo().IsGenericType) { Type[] argTypes = type.GetGenericArguments(); Fx.Assert(argTypes.Length == 1, "IEnumerable type must have one argument"); itemType = argTypes[0]; listType = typeof(List <>).MakeGenericType(argTypes); } MethodAccessor addAccess = MethodAccessor.Create(listType.GetMethod("Add", new Type[] { itemType })); return(new SerializableType.List(this, listType, itemType, addAccess) { Final = true }); } return(null); } if (type.GetTypeInfo().IsEnum) { Type underlyingType = Enum.GetUnderlyingType(type); return(new SerializableType.Converted( AmqpType.Converted, type, underlyingType, (o, t) => Convert.ChangeType(o, t), (o, t) => Enum.ToObject(t, o))); } if (type.GetInterfaces().Any(it => it == typeof(IAmqpSerializable))) { return(new SerializableType.Serializable(this, type)); } if (type.IsArray) { // validate item type to be AMQP types only AmqpEncoding.GetEncoding(type.GetElementType()); return(SerializableType.CreatePrimitiveType(type)); } foreach (Type it in type.GetInterfaces()) { if (it.GetTypeInfo().IsGenericType) { Type genericTypeDef = it.GetGenericTypeDefinition(); if (genericTypeDef == typeof(IDictionary <,>)) { Type[] argTypes = it.GetGenericArguments(); Type itemType = typeof(KeyValuePair <,>).MakeGenericType(argTypes); MemberAccessor keyAccessor = MemberAccessor.Create(itemType.GetProperty("Key"), false); MemberAccessor valueAccessor = MemberAccessor.Create(itemType.GetProperty("Value"), false); MethodAccessor addAccess = MethodAccessor.Create(type.GetMethod("Add", argTypes)); return(new SerializableType.Map(this, type, keyAccessor, valueAccessor, addAccess)); } if (genericTypeDef == typeof(ICollection <>)) { Type[] argTypes = it.GetGenericArguments(); Type itemType = argTypes[0]; MethodAccessor addAccess = MethodAccessor.Create(type.GetMethod("Add", argTypes)); return(new SerializableType.List(this, type, itemType, addAccess)); } } } return(null); }
public T ReadObjectInternal <T>(ByteBuffer buffer) { SerializableType type = this.GetType(typeof(T)); return((T)type.ReadObject(buffer)); }
protected override void Initialize(ByteBuffer buffer, FormatCode formatCode, out int size, out int count, out int encodeWidth, out CollectionType effectiveType) { if (formatCode != FormatCode.Described) { throw new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpInvalidFormatCode, formatCode, buffer.Offset)); } effectiveType = null; formatCode = AmqpEncoding.ReadFormatCode(buffer); ulong? code = null; AmqpSymbol symbol = default(AmqpSymbol); if (formatCode == FormatCode.ULong0) { code = 0; } else if (formatCode == FormatCode.ULong || formatCode == FormatCode.SmallULong) { code = ULongEncoding.Decode(buffer, formatCode); } else if (formatCode == FormatCode.Symbol8 || formatCode == FormatCode.Symbol32) { symbol = SymbolEncoding.Decode(buffer, formatCode); } if (this.AreEqual(this.descriptorCode, this.descriptorName, code, symbol)) { effectiveType = this; } else if (this.knownTypes != null) { for (int i = 0; i < this.knownTypes.Length; ++i) { var kvp = this.knownTypes[i]; if (kvp.Value == null) { SerializableType knownType = this.serializer.GetType(kvp.Key); this.knownTypes[i] = kvp = new KeyValuePair <Type, SerializableType>(kvp.Key, knownType); } DescribedType describedKnownType = (DescribedType)kvp.Value; if (this.AreEqual(describedKnownType.descriptorCode, describedKnownType.descriptorName, code, symbol)) { effectiveType = describedKnownType; break; } } } if (effectiveType == null) { throw new SerializationException(AmqpResources.GetString(AmqpResources.AmqpUnknownDescriptor, code ?? (object)symbol.Value, this.type.Name)); } formatCode = AmqpEncoding.ReadFormatCode(buffer); if (this.Code == FormatCode.List32) { if (formatCode == FormatCode.List0) { size = count = encodeWidth = 0; } else { encodeWidth = formatCode == FormatCode.List8 ? FixedWidth.UByte : FixedWidth.UInt; AmqpEncoding.ReadSizeAndCount(buffer, formatCode, FormatCode.List8, FormatCode.List32, out size, out count); } } else { encodeWidth = formatCode == FormatCode.Map8 ? FixedWidth.UByte : FixedWidth.UInt; AmqpEncoding.ReadSizeAndCount(buffer, formatCode, FormatCode.Map8, FormatCode.Map32, out size, out count); } }
public ListType(AmqpContractSerializer serializer, Type type, Type itemType, MethodAccessor addAccessor) : base(serializer, type) { this.itemType = serializer.GetType(itemType); this.addMethodAccessor = addAccessor; }
/// <summary> /// Reads an object from a buffer. /// </summary> /// <typeparam name="T">The expected type.</typeparam> /// <typeparam name="TAs">The returned type.</typeparam> /// <param name="buffer">The source buffer.</param> /// <returns>An object of TAs.</returns> /// <remarks>The serializer uses T to resolve decoding /// types and returns the decoded object as TAs.</remarks> public TAs ReadObjectFromBuffer <T, TAs>(ByteBuffer buffer) { SerializableType type = this.GetType(typeof(T)); return((TAs)type.ReadObject(buffer)); }