Пример #1
0
        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);
        }
Пример #2
0
            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);
            }
Пример #3
0
            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);
            }
Пример #4
0
            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);
            }
Пример #5
0
            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);
            }
Пример #6
0
        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());
            }
        }
Пример #7
0
        internal TAs ReadObjectInternal <T, TAs>(ByteBuffer buffer)
        {
            SerializableType type = this.GetType(typeof(T));

            return((TAs)type.ReadObject(buffer));
        }
Пример #8
0
 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;
 }
Пример #9
0
 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);
 }
Пример #10
0
 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;
 }
Пример #11
0
 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;
 }
Пример #12
0
        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);
        }
Пример #13
0
        public T ReadObjectInternal <T>(ByteBuffer buffer)
        {
            SerializableType type = this.GetType(typeof(T));

            return((T)type.ReadObject(buffer));
        }
Пример #14
0
            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);
                }
            }
Пример #15
0
 public ListType(AmqpContractSerializer serializer, Type type, Type itemType, MethodAccessor addAccessor)
     : base(serializer, type)
 {
     this.itemType          = serializer.GetType(itemType);
     this.addMethodAccessor = addAccessor;
 }
Пример #16
0
        /// <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));
        }