Esempio n. 1
0
            public MessagePackSerializer Create(SerializationContext context, Type targetType, CollectionTraits collectionTraits, PolymorphismSchema schema, SerializationTarget targetInfo)
            {
                var itemSchema = schema ?? PolymorphismSchema.Default;

                return(new ReflectionCollectionMessagePackSerializer <TCollection, TItem>(context, targetType, collectionTraits, itemSchema, targetInfo));
            }
Esempio n. 2
0
 public MessagePackSerializer Create(SerializationContext context, Type targetType, CollectionTraits collectionTraits, PolymorphismSchema schema, SerializationTarget targetInfo)
 {
     return(new ReflectionNonGenericDictionaryMessagePackSerializer <T>(context, targetType, collectionTraits, schema, targetInfo));
 }
Esempio n. 3
0
        public static void GetMetadata(
            Type targetType,
            IList <SerializingMember> members,
            SerializationContext context,
            out Func <object, object>[] getters,
            out Action <object, object>[] setters,
            out MemberInfo[] memberInfos,
            out DataMemberContract[] contracts,
            out MessagePackSerializer[] serializers
            )
        {
            SerializationTarget.VerifyCanSerializeTargetType(context, targetType);

            if (members.Count == 0)
            {
                if (!typeof(IPackable).IsAssignableFrom(targetType))
                {
                    throw new SerializationException(
                              String.Format(
                                  CultureInfo.CurrentCulture,
                                  "At least one serializable member is required because type '{0}' does not implement IPackable interface.",
                                  targetType
                                  )
                              );
                }

                if (!typeof(IUnpackable).IsAssignableFrom(targetType))
                {
                    throw new SerializationException(
                              String.Format(
                                  CultureInfo.CurrentCulture,
                                  "At least one serializable member is required because type '{0}' does not implement IUnpackable interface.",
                                  targetType
                                  )
                              );
                }

#if FEATURE_TAP
                if (context.SerializerOptions.WithAsync)
                {
                    if (!typeof(IAsyncPackable).IsAssignableFrom(targetType))
                    {
                        throw new SerializationException(
                                  String.Format(
                                      CultureInfo.CurrentCulture,
                                      "At least one serializable member is required because type '{0}' does not implement IAsyncPackable interface.",
                                      targetType
                                      )
                                  );
                    }

                    if (!typeof(IAsyncUnpackable).IsAssignableFrom(targetType))
                    {
                        throw new SerializationException(
                                  String.Format(
                                      CultureInfo.CurrentCulture,
                                      "At least one serializable member is required because type '{0}' does not implement IAsyncUnpackable interface.",
                                      targetType
                                      )
                                  );
                    }
                }
#endif // FEATURE_TAP
            }

            getters     = new Func <object, object> [members.Count];
            setters     = new Action <object, object> [members.Count];
            memberInfos = new MemberInfo[members.Count];
            contracts   = new DataMemberContract[members.Count];
            serializers = new MessagePackSerializer[members.Count];

            for (var i = 0; i < members.Count; i++)
            {
                var member = members[i];

                if (member.Member == null)
                {
                    // Missing member exist because of unconbinous Id of MessagePackMember or Order of DataMember.
#if UNITY
                    contracts[i] = DataMemberContract.Null;
#endif // UNITY
                    continue;
                }

                FieldInfo asField;
                if ((asField = member.Member as FieldInfo) != null)
                {
                    if (context.SerializerOptions.DisablePrivilegedAccess && !asField.GetIsPublic())
                    {
                        continue;
                    }

                    getters[i] = asField.GetValue;
                    if (!asField.IsInitOnly)
                    {
                        setters[i] = asField.SetValue;
                    }
                }
                else
                {
                    var property = member.Member as PropertyInfo;
#if DEBUG
                    Contract.Assert(property != null, "member.Member is PropertyInfo");
#endif // DEBUG
                    if (context.SerializerOptions.DisablePrivilegedAccess && !property.GetIsPublic())
                    {
                        continue;
                    }

                    var getter = property.GetGetMethod(true);
                    if (getter == null)
                    {
                        ThrowMissingGetterException(targetType, i, property);
                    }

                    getters[i] = target => getter.InvokePreservingExceptionType(target, null);
                    var setter = property.GetSetMethod(true);
                    if (setter != null && (!context.SerializerOptions.DisablePrivilegedAccess || setter.GetIsPublic()))
                    {
                        setters[i] = (target, value) => setter.InvokePreservingExceptionType(target, new[] { value });
                    }
                }

                memberInfos[i] = member.Member;
#if !UNITY
                contracts[i] = member.Contract;
#else
                contracts[i] = member.Contract ?? DataMemberContract.Null;
#endif // !UNITY
                var memberType = member.Member.GetMemberValueType();
                if (memberType.GetIsEnum())
                {
                    serializers[i] =
                        context.GetSerializer(
                            memberType,
                            EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethod(
                                context,
                                memberType,
                                member.GetEnumMemberSerializationMethod()
                                )
                            );
                }
                else if (DateTimeMessagePackSerializerHelpers.IsDateTime(memberType))
                {
                    serializers[i] =
                        context.GetSerializer(
                            memberType,
                            DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethod(
                                context,
                                member.GetDateTimeMemberConversionMethod()
                                )
                            );
                }
                else
                {
                    serializers[i] = context.GetSerializer(memberType, PolymorphismSchema.Create(memberType, member));
                }
            }
        }
        public Func <SerializationContext, PolymorphismSchema, MessagePackSerializer> CreateObjectConstructor(
            AssemblyBuilderEmittingContext context,
            AssemblyBuilderSerializerBuilder builder,
            SerializationTarget targetInfo,
            SerializerCapabilities?capabilities
            )
        {
            var hasPackActions        = targetInfo != null && !typeof(IPackable).IsAssignableFrom(builder.TargetType);
            var hasUnpackActions      = targetInfo != null && !typeof(IUnpackable).IsAssignableFrom(builder.TargetType);
            var hasUnpackActionTables = hasUnpackActions && targetInfo.Members.Any(m => m.Member != null);               // Except tuples

#if FEATURE_TAP
            var hasPackAsyncActions        = targetInfo != null && !typeof(IAsyncPackable).IsAssignableFrom(builder.TargetType);
            var hasUnpackAsyncActions      = targetInfo != null && !typeof(IAsyncUnpackable).IsAssignableFrom(builder.TargetType);
            var hasUnpackAsyncActionTables = hasUnpackAsyncActions && targetInfo.Members.Any(m => m.Member != null);               // Except tuples
#endif // FEATURE_TAP
            // ReSharper disable RedundantDelegateCreation
            Func <bool, Func <ILConstruct> > packActionsInitialization =
                isAsync =>
                new Func <ILConstruct>(() => builder.EmitPackOperationListInitialization(context, targetInfo, isAsync));
            Func <bool, Func <ILConstruct> > packActionTableInitialization =
                isAsync =>
                new Func <ILConstruct>(() => builder.EmitPackOperationTableInitialization(context, targetInfo, isAsync));
            Func <ILConstruct> nullCheckerTableInitializtion             = () => builder.EmitPackNullCheckerTableInitialization(context, targetInfo);
            Func <bool, Func <ILConstruct> > unpackActionsInitialization =
                isAsync => new Func <ILConstruct>(() => builder.EmitUnpackOperationListInitialization(context, targetInfo, isAsync));
            Func <bool, Func <ILConstruct> > unpackActionTableInitialization =
                isAsync => new Func <ILConstruct>(() => builder.EmitUnpackOperationTableInitialization(context, targetInfo, isAsync));
            // ReSharper restore RedundantDelegateCreation

            var contextfulConstructor =
                this.CreateConstructor(
                    MethodAttributes.Public,
                    ConstructorParameterTypesWithoutCapabilities,
                    (type, il) =>
                    this.CreateContextfulObjectConstructor(
                        context,
                        type,
                        capabilities,
                        il,
                        hasPackActions
                                                                ? packActionsInitialization(false)
                                                                : default(Func <ILConstruct>),
                        hasPackActions
                                                                ? packActionTableInitialization(false)
                                                                : default(Func <ILConstruct>),
#if DEBUG
                        !SerializerDebugging.UseLegacyNullMapEntryHandling &&
#endif // DEBUG
                        hasPackActions
#if FEATURE_TAP
                        || hasPackAsyncActions
#endif // FEATURE_TAP
                                                                ? nullCheckerTableInitializtion
                                                                : default(Func <ILConstruct>),
                        hasUnpackActions
                                                                ? unpackActionsInitialization(false)
                                                                : default(Func <ILConstruct>),
                        hasUnpackActionTables
                                                                ? unpackActionTableInitialization(false)
                                                                : default(Func <ILConstruct>),
#if FEATURE_TAP
                        hasPackAsyncActions&& context.SerializationContext.SerializerOptions.WithAsync
                                                                ? packActionsInitialization(true)
                                                                : default(Func <ILConstruct>),
                        hasPackAsyncActions && context.SerializationContext.SerializerOptions.WithAsync
                                                                ? packActionTableInitialization(true)
                                                                : default(Func <ILConstruct>),
                        hasUnpackAsyncActions && context.SerializationContext.SerializerOptions.WithAsync
                                                                ? unpackActionsInitialization(true)
                                                                : default(Func <ILConstruct>),
                        hasUnpackAsyncActionTables && context.SerializationContext.SerializerOptions.WithAsync
                                                                ? unpackActionTableInitialization(true)
                                                                : default(Func <ILConstruct>),
#endif // FEATURE_TAP
                        (
                            hasUnpackActions
#if FEATURE_TAP
                            || hasUnpackAsyncActions
#endif // FEATURE_TAP
                        ) ? () => builder.EmitMemberListInitialization(context, targetInfo)
                                                                : default(Func <ILConstruct>),
                        context.IsUnpackToUsed
                                                                ? () => builder.EmitUnpackToInitialization(context)
                                                                : default(Func <ILConstruct>)
                        )
                    );
            this.CreateConstructor(
                MethodAttributes.Public,
                ReflectionAbstractions.EmptyTypes,
                (_, il) => CreateDefaultObjectConstructor(contextfulConstructor, il)
                );

#if !NETSTANDARD1_1 && !NETSTANDARD1_3
            var ctor = this._typeBuilder.CreateType().GetConstructor(ConstructorParameterTypesWithoutCapabilities);
#else
            var ctor = this._typeBuilder.CreateTypeInfo().GetConstructor(ConstructorParameterTypesWithoutCapabilities);
#endif // !NETSTANDARD1_1 && !NETSTANDARD1_3

#if DEBUG
            Contract.Assert(ctor != null, "ctor != null");
#endif
            var actualFunc = ctor.CreateConstructorDelegate <Func <SerializationContext, MessagePackSerializer> >();
            return((c, _) => actualFunc(c));
        }
Esempio n. 5
0
        private void BuildCollectionSerializer(
            TContext context,
            Type concreteType,
            PolymorphismSchema schema,
            out SerializationTarget targetInfo
            )
        {
#if DEBUG
            Contract.Assert(this.CollectionTraits.DetailedCollectionType != CollectionDetailedKind.Array);
#endif // DEBUG
            bool isUnpackFromRequired;
            bool isAddItemRequired;
            this.DetermineSerializationStrategy(context, concreteType, out targetInfo, out isUnpackFromRequired, out isAddItemRequired);

            if (typeof(IPackable).IsAssignableFrom(this.TargetType))
            {
                this.BuildIPackablePackTo(context);
            }
#if FEATURE_TAP
            if (this.WithAsync(context))
            {
                if (typeof(IAsyncPackable).IsAssignableFrom(this.TargetType))
                {
                    this.BuildIAsyncPackablePackTo(context);
                }
            }
#endif // FEATURE_TAP

            this.BuildCollectionCreateInstance(context, targetInfo.DeserializationConstructor, targetInfo.CanDeserialize);

            var useUnpackable = false;

            if (typeof(IUnpackable).IsAssignableFrom(concreteType ?? this.TargetType))
            {
                this.BuildIUnpackableUnpackFrom(context, this.GetUnpackableCollectionInstantiation(context), targetInfo.CanDeserialize);
                useUnpackable = true;
            }

#if FEATURE_TAP
            if (this.WithAsync(context))
            {
                if (typeof(IAsyncUnpackable).IsAssignableFrom(concreteType ?? this.TargetType))
                {
                    this.BuildIAsyncUnpackableUnpackFrom(context, this.GetUnpackableCollectionInstantiation(context), targetInfo.CanDeserialize);
                    useUnpackable = true;
                }
            }
#endif // FEATURE_TAP

            if (isAddItemRequired)
            {
                if (useUnpackable || !targetInfo.CanDeserialize)
                {
                    // AddItem should never called because UnpackFromCore calls IUnpackable/IAsyncUnpackable
                    this.BuildCollectionAddItemNotImplemented(context);
                }
                else
                {
                    // For IEnumerable implements and IReadOnlyXXX implements
                    this.BuildCollectionAddItem(
                        context,
                        this.CollectionTraits.AddMethod != null
                                                ? this.CollectionTraits                                                                                                                                                   // For declared collection.
                                                : (concreteType ?? this.TargetType).GetCollectionTraits(CollectionTraitOptions.Full, context.SerializationContext.CompatibilityOptions.AllowNonCollectionEnumerableTypes) // For concrete collection.
                        );
                }
            }

            if (isUnpackFromRequired && !useUnpackable)
            {
                this.BuildCollectionUnpackFromCore(context, concreteType, schema, targetInfo.CanDeserialize, isAsync: false);
#if FEATURE_TAP
                if (this.WithAsync(context))
                {
                    this.BuildCollectionUnpackFromCore(context, concreteType, schema, targetInfo.CanDeserialize, isAsync: true);
                }
#endif // FEATURE_TAP
            }

            this.BuildRestoreSchema(context, schema);
        }
Esempio n. 6
0
        private void DetermineSerializationStrategy(
            TContext context,
            Type concreteType,
            out SerializationTarget targetInfo,
            out bool isUnpackFromRequired,
            out bool isAddItemRequired
            )
        {
            targetInfo =
                UnpackHelpers.DetermineCollectionSerializationStrategy(
                    concreteType ?? this.TargetType,
                    context.SerializationContext.CompatibilityOptions.AllowAsymmetricSerializer
                    );

            switch (this.CollectionTraits.DetailedCollectionType)
            {
            case CollectionDetailedKind.NonGenericEnumerable:
            case CollectionDetailedKind.NonGenericCollection:
            {
                isUnpackFromRequired = true;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.NonGenericList:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }

            case CollectionDetailedKind.NonGenericDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }

            case CollectionDetailedKind.GenericEnumerable:
            {
                isUnpackFromRequired = true;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.GenericDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }

#if !NET35 && !UNITY && !NET40 && !(SILVERLIGHT && !WINDOWS_PHONE)
            case CollectionDetailedKind.GenericReadOnlyDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.GenericReadOnlyList:
            case CollectionDetailedKind.GenericReadOnlyCollection:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = true;
                break;
            }
#endif // !NET35 && !UNITY && !NET40 && !( SILVERLIGHT && !WINDOWS_PHONE )
            default:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }
            }             // switch
        }