protected override Action <object> OnThrowValueTypeCannotBeNull3OnUnpacked(ReflectionSerializerNilImplicationHandlerOnUnpackedParameter parameter)
 {
     return
         (_ =>
     {
         throw SerializationExceptions.NewValueTypeCannotBeNull(
             parameter.MemberName,
             parameter.ItemType,
             parameter.DeclaringType
             );
     });
 }
        protected ObjectReflectionMessagePackSerializer(Type type, SerializationContext context, SerializingMember[] members)
            : base(type, (context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions)
        {
            if (type.GetIsAbstract() || type.GetIsInterface())
            {
                throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(type);
            }

            this._createInstance = () => Activator.CreateInstance(type);

            //Expression.Lambda<Func<T>>(
            //    typeof(T).GetIsValueType()
            //        ? Expression.Default(typeof(T)) as Expression
            //        : Expression.New(typeof(T).GetConstructor(ReflectionAbstractions.EmptyTypes))
            //    ).Compile();
            var isPackable   = typeof(IPackable).IsAssignableFrom(type);
            var isUnpackable = typeof(IUnpackable).IsAssignableFrom(type);

            if (isPackable && isUnpackable)
            {
                this._memberSerializers = null;
                this._indexMap          = null;
                this._isCollection      = null;
                this._nilImplications   = null;
                this._memberNames       = null;
            }
            else
            {
                this._memberSerializers =
                    members.Select(
                        m => m.Member == null ? NullSerializer.Instance : context.GetSerializer(m.Member.GetMemberValueType())).ToArray
                    (

                    );
                this._indexMap =
                    members
                    .Select((m, i) => new KeyValuePair <SerializingMember, int>(m, i))
                    .Where(kv => kv.Key.Member != null)
                    .ToDictionary(kv => kv.Key.Contract.Name, kv => kv.Value);

                this._isCollection =
                    members.Select(
                        m => m.Member == null ? CollectionTraits.NotCollection : m.Member.GetMemberValueType().GetCollectionTraits()).
                    Select(t => t.CollectionType != CollectionKind.NotCollection).ToArray();

                // NilImplication validity check
                foreach (var member in members)
                {
                    switch (member.Contract.NilImplication)
                    {
                    case NilImplication.Null:
                    {
                        if (member.Member.GetMemberValueType().GetIsValueType() &&
                            Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)
                        {
                            throw SerializationExceptions.NewValueTypeCannotBeNull(
                                      member.Contract.Name, member.Member.GetMemberValueType(), member.Member.DeclaringType
                                      );
                        }

                        if (!member.Member.CanSetValue())
                        {
                            throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(member.Contract.Name);
                        }

                        break;
                    }
                    }
                }

                this._nilImplications = members.Select(m => m.Contract.NilImplication).ToArray();
                this._memberNames     = members.Select(m => m.Contract.Name).ToArray();
            }

            if (isPackable)
            {
                this._packToMessage = (target, packer, packingOptions) =>
                {
                    ((IPackable)target).PackToMessage(packer, packingOptions);
                    //typeof(T).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single().Invoke(target, new object[] { packer, packingOptions });
                };
                this._memberGetters = null;
            }
            else
            {
                this._packToMessage = null;
                this._memberGetters =
                    members.Select <SerializingMember, Func <object, object> >(
                        m => m.Member == null ? (target => null)
                        : CreateMemberGetter(m)).ToArray();
            }

            if (isUnpackable)
            {
                this._unpackFromMessage = delegate(ref object target, Unpacker value)
                {
                    ((IUnpackable)target).UnpackFromMessage(value);
                };

                this._memberSetters = null;
            }
            else
            {
                this._unpackFromMessage = null;

                this._memberSetters =
                    members.Select(
                        m =>
                        m.Member == null
                        ? delegate(ref object target, object memberValue) { }
                :
                        m.Member.CanSetValue()
                        ? CreateMemberSetter(m)
                        : UnpackHelpers.IsReadOnlyAppendableCollectionMember(m.Member)
                        ? default(MemberSetter)
                        : ThrowGetOnlyMemberIsInvalid(m.Member)
                        ).ToArray();
            }
        }
Esempio n. 3
0
        private static void EmitNilImplicationForPrimitive(TracingILGenerator il, SerializingMember member, LocalBuilder value, Label endOfDeserialization)
        {
            var endIf = il.DefineLabel("END_IF_NULL");

            EmitCompareNull(il, value, endIf);

            switch (member.Contract.NilImplication)
            {
            case NilImplication.MemberDefault:
            {
                /*
                 * if( value == null )
                 * {
                 *		// Skip current.
                 *		goto END_OF_DESERIALIZATION;
                 * }
                 */
                il.EmitBr(endOfDeserialization);
                break;
            }

            case NilImplication.Null:
            {
                if (member.Member.GetMemberValueType().GetIsValueType() && Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)
                {
                    throw SerializationExceptions.NewValueTypeCannotBeNull(
                              member.Contract.Name, member.Member.GetMemberValueType(), member.Member.DeclaringType
                              );
                }

                // TODO: Refactoring
                // Throw exception for non-nullable value type.
                // Nop for nullables.
                if (member.Member.GetMemberValueType().GetIsValueType() &&
                    Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)
                {
                    /*
                     * if( value == null )
                     * {
                     *		throw SerializationEceptions.NewValueTypeCannotBeNull( "...", typeof( MEMBER ), typeof( TYPE ) );
                     * }
                     */
                    il.EmitLdstr(member.Contract.Name);
                    il.EmitLdtoken(member.Member.GetMemberValueType());
                    il.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                    il.EmitLdtoken(member.Member.DeclaringType);
                    il.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                    il.EmitAnyCall(SerializationExceptions.NewValueTypeCannotBeNull3Method);
                    il.EmitThrow();
                }

                break;
            }

            case NilImplication.Prohibit:
            {
                /*
                 * if( value == null )
                 * {
                 *		throw SerializationEceptions.NewProhibitNullException( "..." );
                 * }
                 */
                il.EmitLdstr(member.Contract.Name);
                il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                il.EmitThrow();
                break;
            }
            }

            il.MarkLabel(endIf);
        }
Esempio n. 4
0
        /// <summary>
        ///		Emits the nil implication.
        /// </summary>
        /// <param name="il">The il generator.</param>
        /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
        /// <param name="member">Metadata of the serializing member.</param>
        /// <param name="endOfDeserialization">The label to the end of deserialization.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        public static void EmitNilImplication(
            TracingILGenerator il,
            int unpackerArgumentIndex,
            SerializingMember member,
            Label endOfDeserialization,
            LocalVariableHolder localHolder
            )
        {
            switch (member.Contract.NilImplication)
            {
            case NilImplication.MemberDefault:
            {
                // TODO: This should be empty for extra items.

                /*
                 * if( unpacker.Data.Value.IsNil )
                 * {
                 *		// Skip current.
                 *		goto END_OF_DESERIALIZATION;
                 * }
                 */
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.LastReadData);
                var data = localHolder.UnpackedData;
                il.EmitAnyStloc(data);
                il.EmitAnyLdloca(data);
                il.EmitGetProperty(Metadata._MessagePackObject.IsNil);
                il.EmitBrtrue(endOfDeserialization);

                break;
            }

            case NilImplication.Null:
            {
                if (member.Member.GetMemberValueType().GetIsValueType() && Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)
                {
                    throw SerializationExceptions.NewValueTypeCannotBeNull(
                              member.Contract.Name, member.Member.GetMemberValueType(), member.Member.DeclaringType
                              );
                }

                if (!member.Member.CanSetValue())
                {
                    throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(
                              member.Contract.Name
                              );
                }

                break;
            }

            case NilImplication.Prohibit:
            {
                if (!member.Member.CanSetValue())
                {
                    throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(
                              member.Contract.Name
                              );
                }

                /*
                 * if( unpacker.Data.Value.IsNil )
                 * {
                 *		throw SerializationEceptions.NewProhibitNullException( "..." );
                 * }
                 */
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.LastReadData);
                var data = localHolder.UnpackedData;
                il.EmitAnyStloc(data);
                il.EmitAnyLdloca(data);
                il.EmitGetProperty(Metadata._MessagePackObject.IsNil);
                var endIf0 = il.DefineLabel("END_IF0");
                il.EmitBrfalse_S(endIf0);
                il.EmitLdstr(member.Contract.Name);
                il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                il.EmitThrow();
                il.MarkLabel(endIf0);

                break;
            }
            }
        }
        protected ObjectExpressionMessagePackSerializer(SerializationContext context, SerializingMember[] members)
            : base((context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions)
        {
            if (typeof(T).GetIsAbstract() || typeof(T).GetIsInterface())
            {
                throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(typeof(T));
            }

            this._createInstance =
                Expression.Lambda <Func <T> >(
                    typeof(T).GetIsValueType()
                                                ? Expression.Default(typeof(T)) as Expression
                                                : Expression.New(typeof(T).GetConstructor(ReflectionAbstractions.EmptyTypes))
                    ).Compile();
            var isPackable   = typeof(IPackable).IsAssignableFrom(typeof(T));
            var isUnpackable = typeof(IUnpackable).IsAssignableFrom(typeof(T));

            var targetParameter = Expression.Parameter(typeof(T), "target");

            if (isPackable && isUnpackable)
            {
                this._memberSerializers = null;
                this._indexMap          = null;
                this._isCollection      = null;
                this._nilImplications   = null;
                this._memberNames       = null;
            }
            else
            {
                this._memberSerializers =
                    members.Select(
                        m => m.Member == null ? NullSerializer.Instance : context.GetSerializer(m.Member.GetMemberValueType())).ToArray
                    (

                    );
                this._indexMap =
                    members
                    .Zip(Enumerable.Range(0, members.Length), (m, i) => new KeyValuePair <SerializingMember, int>(m, i))
                    .Where(kv => kv.Key.Member != null)
                    .ToDictionary(kv => kv.Key.Contract.Name, kv => kv.Value);

                this._isCollection =
                    members.Select(
                        m => m.Member == null ? CollectionTraits.NotCollection : m.Member.GetMemberValueType().GetCollectionTraits()).
                    Select(t => t.CollectionType != CollectionKind.NotCollection).ToArray();

                // NilImplication validity check
                foreach (var member in members)
                {
                    switch (member.Contract.NilImplication)
                    {
                    case NilImplication.Null:
                    {
                        if (member.Member.GetMemberValueType().GetIsValueType() &&
                            Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)
                        {
                            throw SerializationExceptions.NewValueTypeCannotBeNull(
                                      member.Contract.Name, member.Member.GetMemberValueType(), member.Member.DeclaringType
                                      );
                        }

                        if (!member.Member.CanSetValue())
                        {
                            throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(member.Contract.Name);
                        }

                        break;
                    }
                    }
                }

                this._nilImplications = members.Select(m => m.Contract.NilImplication).ToArray();
                this._memberNames     = members.Select(m => m.Contract.Name).ToArray();
            }

            if (isPackable)
            {
                var packerParameter  = Expression.Parameter(typeof(Packer), "packer");
                var optionsParameter = Expression.Parameter(typeof(PackingOptions), "options");
                this._packToMessage =
                    Expression.Lambda <Action <T, Packer, PackingOptions> >(
                        Expression.Call(
                            targetParameter,
                            typeof(T).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single(),
                            packerParameter,
                            optionsParameter
                            ),
                        targetParameter, packerParameter, optionsParameter
                        ).Compile();
                this._memberGetters = null;
            }
            else
            {
                this._packToMessage = null;
                this._memberGetters =
                    members.Select(
                        m =>
                        m.Member == null
                                                ? Expression.Lambda <Func <T, object> >(
                            Expression.Constant(null),
                            targetParameter
                            ).Compile()
                                                : CreateMemberGetter(targetParameter, m)
                        ).ToArray();
            }

            var refTargetParameter = Expression.Parameter(typeof(T).MakeByRefType(), "target");

            if (isUnpackable)
            {
                var unpackerParameter = Expression.Parameter(typeof(Unpacker), "unpacker");
                this._unpackFromMessage =
                    Expression.Lambda <UnpackFromMessageInvocation>(
                        Expression.Call(
                            refTargetParameter,
                            typeof(T).GetInterfaceMap(typeof(IUnpackable)).TargetMethods.Single(),
                            unpackerParameter
                            ),
                        refTargetParameter, unpackerParameter
                        ).Compile();
                this._memberSetters = null;
            }
            else
            {
                this._unpackFromMessage = null;

                var valueParameter = Expression.Parameter(typeof(object), "value");
                this._memberSetters =
                    members.Select(
                        m =>
                        m.Member == null
                                                ? Expression.Lambda <MemberSetter>(
                            Expression.Empty(),
                            refTargetParameter,
                            valueParameter
                            ).Compile()
                                                : m.Member.CanSetValue()
                                                ? Expression.Lambda <MemberSetter>(
                            Expression.Assign(
                                Expression.PropertyOrField(
                                    refTargetParameter,
                                    m.Member.Name
                                    ),
                                Expression.Call(
                                    Metadata._UnpackHelpers.ConvertWithEnsuringNotNull_1Method.MakeGenericMethod(m.Member.GetMemberValueType()),
                                    valueParameter,
                                    Expression.Constant(m.Member.Name),
                                    Expression.Call(                                     // Using RuntimeTypeHandle to avoid WinRT expression tree issue.
                                        null,
                                        Metadata._Type.GetTypeFromHandle,
                                        Expression.Constant(m.Member.DeclaringType.TypeHandle)
                                        )
                                    )
                                ),
                            refTargetParameter,
                            valueParameter
                            ).Compile()
                                                : UnpackHelpers.IsReadOnlyAppendableCollectionMember(m.Member)
                                                ? default(MemberSetter)
                                                : ThrowGetOnlyMemberIsInvalid(m.Member)
                        ).ToArray();
            }
        }