protected internal override DictionaryEntry UnpackFromCore(Unpacker unpacker)
        {
            if (unpacker.IsArrayHeader)
            {
                MessagePackObject key;
                MessagePackObject value;

                if (!unpacker.ReadObject(out key))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!unpacker.ReadObject(out value))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                return(new DictionaryEntry(key, value));
            }
            else
            {
                // Previous DictionaryEntry serializer accidentally pack it as map...
                MessagePackObject key   = default(MessagePackObject);
                MessagePackObject value = default(MessagePackObject);
                bool   isKeyFound       = false;
                bool   isValueFound     = false;
                string propertyName;

                while ((!isKeyFound || !isValueFound) && unpacker.ReadString(out propertyName))
                {
                    switch (propertyName)
                    {
                    case "Key":
                    {
                        if (!unpacker.ReadObject(out key))
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        isKeyFound = true;
                        break;
                    }

                    case "Value":
                    {
                        if (!unpacker.ReadObject(out value))
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        isValueFound = true;
                        break;
                    }
                    }
                }

                if (!isKeyFound)
                {
                    SerializationExceptions.ThrowMissingProperty("Key");
                }

                if (!isValueFound)
                {
                    SerializationExceptions.ThrowMissingProperty("Value");
                }

                return(new DictionaryEntry(key, value));
            }
        }
        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();
            }
        }
        public MapExpressionMessagePackSerializer(SerializationContext context, CollectionTraits traits)
        {
            Contract.Assert(typeof(IEnumerable).IsAssignableFrom(typeof(T)), typeof(T) + " is IEnumerable");
            Contract.Assert(traits.ElementType == typeof(DictionaryEntry) || (traits.ElementType.GetIsGenericType() && traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)), "Element type " + traits.ElementType + " is not KeyValuePair<TKey,TValue>.");
            this._traits          = traits;
            this._keySerializer   = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[0]) : context.GetSerializer(typeof(MessagePackObject));
            this._valueSerializer = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[1]) : context.GetSerializer(typeof(MessagePackObject));
            this._getCount        = ExpressionSerializerLogics.CreateGetCount <T>(traits);

            var constructor = ExpressionSerializerLogics.GetCollectionConstructor <T>();

            if (constructor == null)
            {
                this._createInstance             = () => { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(typeof(T)); };
                this._createInstanceWithCapacity = null;
            }
            else if (constructor.GetParameters().Length == 1)
            {
                this._createInstance = null;

                var capacityParameter = Expression.Parameter(typeof(int), "parameter");
                this._createInstanceWithCapacity =
                    Expression.Lambda <Func <int, T> >(
                        Expression.New(constructor, capacityParameter),
                        capacityParameter
                        ).Compile();
            }
            else
            {
                this._createInstanceWithCapacity = null;
                this._createInstance             =
                    Expression.Lambda <Func <T> >(
                        Expression.New(constructor)
                        ).Compile();
            }

            var packerParameter          = Expression.Parameter(typeof(Packer), "packer");
            var objectTreeParameter      = Expression.Parameter(typeof(T), "objectTree");
            var keySerializerParameter   = Expression.Parameter(typeof(IMessagePackSerializer), "keySerializer");
            var valueSerializerParameter = Expression.Parameter(typeof(IMessagePackSerializer), "valueSerializer");
            var keyType             = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[0] : typeof(MessagePackObject);
            var valueType           = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[1] : typeof(MessagePackObject);
            var keySerializerType   = typeof(MessagePackSerializer <>).MakeGenericType(keyType);
            var valueSerializerType = typeof(MessagePackSerializer <>).MakeGenericType(valueType);

            /*
             *	packer.PackMapHeader( objectTree.Count() );
             *	foreach( var item in objectTree )
             *	{
             *		elementSerializer.PackTo( packer, item.Key );
             *		elementSerializer.PackTo( packer, item.Value );
             *	}
             */
            var packToCore =
                Expression.Lambda <Action <Packer, T, IMessagePackSerializer, IMessagePackSerializer> >(
                    Expression.Block(
                        Expression.Call(
                            packerParameter,
                            Metadata._Packer.PackMapHeader,
                            ExpressionSerializerLogics.CreateGetCountExpression <T>(traits, objectTreeParameter)
                            ),
                        ExpressionSerializerLogics.ForEach(
                            objectTreeParameter,
                            traits,
                            elementVariable =>
                            Expression.Block(
                                Expression.Call(
                                    Expression.TypeAs(keySerializerParameter, keySerializerType),
                                    typeof(MessagePackSerializer <>).MakeGenericType(keyType).GetMethod("PackTo"),
                                    packerParameter,
                                    traits.ElementType.GetIsGenericType()
                                                                                ? Expression.Property(elementVariable, traits.ElementType.GetProperty("Key")) as Expression
                                                                                : Expression.Unbox(Expression.Property(elementVariable, traits.ElementType.GetProperty("Key")), typeof(MessagePackObject))
                                    ),
                                Expression.Call(
                                    Expression.TypeAs(valueSerializerParameter, valueSerializerType),
                                    typeof(MessagePackSerializer <>).MakeGenericType(valueType).GetMethod("PackTo"),
                                    packerParameter,
                                    traits.ElementType.GetIsGenericType()
                                                                                ? Expression.Property(elementVariable, traits.ElementType.GetProperty("Value")) as Expression
                                                                                : Expression.Unbox(Expression.Property(elementVariable, traits.ElementType.GetProperty("Value")), typeof(MessagePackObject))
                                    )
                                )
                            )
                        ), packerParameter, objectTreeParameter, keySerializerParameter, valueSerializerParameter
                    );

#if !SILVERLIGHT
            if (context.GeneratorOption == SerializationMethodGeneratorOption.CanDump)
            {
                this._packToCoreExpression = packToCore;
            }
#endif

            this._packToCore = packToCore.Compile();

            var unpackerParameter = Expression.Parameter(typeof(Unpacker), "unpacker");
            var instanceParameter = Expression.Parameter(typeof(T), "instance");
            var countParamter     = Expression.Parameter(typeof(int), "count");

            Expression <Action <Unpacker, T, IMessagePackSerializer, IMessagePackSerializer> > unpackToCore;
            if (traits.ElementType.GetIsGenericType())
            {
                /*
                 * UnpackHelpers.UnpackMapTo<TKey,TValue>( unpacker, keySerializer, valueSerializer, instance );
                 */
                unpackToCore =
                    Expression.Lambda <Action <Unpacker, T, IMessagePackSerializer, IMessagePackSerializer> >(
                        Expression.Call(
                            Metadata._UnpackHelpers.UnpackMapTo_2.MakeGenericMethod(keyType, valueType),
                            unpackerParameter,
                            Expression.TypeAs(keySerializerParameter, keySerializerType),
                            Expression.TypeAs(valueSerializerParameter, valueSerializerType),
                            Expression.TypeAs(instanceParameter, typeof(IDictionary <,>).MakeGenericType(keyType, valueType))
                            ),
                        unpackerParameter, instanceParameter, keySerializerParameter, valueSerializerParameter
                        );
            }
            else
            {
                /*
                 * UnpackHelpers.UnpackNonGenericMapTo( unpacker, instance );
                 */
                unpackToCore =
                    Expression.Lambda <Action <Unpacker, T, IMessagePackSerializer, IMessagePackSerializer> >(
                        Expression.Call(
                            Metadata._UnpackHelpers.UnpackNonGenericMapTo,
                            unpackerParameter,
                            Expression.TypeAs(instanceParameter, typeof(IDictionary))
                            ),
                        unpackerParameter, instanceParameter, keySerializerParameter, valueSerializerParameter
                        );
            }

#if !SILVERLIGHT
            if (context.GeneratorOption == SerializationMethodGeneratorOption.CanDump)
            {
                this._unpackToCoreExpression = unpackToCore;
            }
#endif

            this._unpackToCore = unpackToCore.Compile();
        }
        protected internal override async Task <DictionaryEntry> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            if (unpacker.IsArrayHeader)
            {
                var key = await unpacker.ReadObjectAsync(cancellationToken).ConfigureAwait(false);

                if (!key.Success)
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                var value = await unpacker.ReadObjectAsync(cancellationToken).ConfigureAwait(false);

                if (!value.Success)
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                return(new DictionaryEntry(key.Value, value.Value));
            }
            else
            {
                // Previous DictionaryEntry serializer accidentally pack it as map...
                AsyncReadResult <MessagePackObject> key   = default(AsyncReadResult <MessagePackObject>);
                AsyncReadResult <MessagePackObject> value = default(AsyncReadResult <MessagePackObject>);

                for (var propertyName = await unpacker.ReadStringAsync(cancellationToken).ConfigureAwait(false);
                     (!key.Success || !value.Success) && propertyName.Success;
                     propertyName = await unpacker.ReadStringAsync(cancellationToken).ConfigureAwait(false))
                {
                    switch (propertyName.Value)
                    {
                    case "Key":
                    {
                        key = await unpacker.ReadObjectAsync(cancellationToken).ConfigureAwait(false);

                        if (!key.Success)
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        break;
                    }

                    case "Value":
                    {
                        value = await unpacker.ReadObjectAsync(cancellationToken).ConfigureAwait(false);

                        if (!value.Success)
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        break;
                    }
                    }
                }

                if (!key.Success)
                {
                    SerializationExceptions.ThrowMissingProperty("Key");
                }

                if (!value.Success)
                {
                    SerializationExceptions.ThrowMissingProperty("Value");
                }

                return(new DictionaryEntry(key.Value, value.Value));
            }
        }
        private object UnpackMemberValue(object objectGraph, Unpacker unpacker, int itemsCount, ref int unpacked, int index, int unpackerOffset)
        {
            object nullable = null;

            var setter = index < this._setters.Length ? this._setters[index] : null;

            if (unpacked < itemsCount)
            {
                if (!unpacker.Read())
                {
                    throw SerializationExceptions.NewMissingItem(unpackerOffset);
                }

                if (!unpacker.LastReadData.IsNil)
                {
                    if (setter != null || this._constructorParameters != null)
                    {
                        nullable = this.UnpackSingleValue(unpacker, index);
                    }
                    else if (this._getters[index] != null)                         // null getter supposes undeclared member (should be treated as nil)
                    {
                        this.UnpackAndAddCollectionItem(objectGraph, unpacker, index);
                    }
                }
            }

            if (this._constructorParameters != null)
            {
#if DEBUG && !UNITY
                Contract.Assert(objectGraph is object[], "objectGraph is object[]");
#endif // !UNITY

                int argumentIndex;
                if (this._constructorArgumentIndexes.TryGetValue(index, out argumentIndex))
                {
                    if (nullable == null)
                    {
                        ReflectionNilImplicationHandler.Instance.OnUnpacked(
                            new ReflectionSerializerNilImplicationHandlerOnUnpackedParameter(
                                this._memberInfos[index].GetMemberValueType(),
                                // ReSharper disable once PossibleNullReferenceException
                                value => (objectGraph as object[])[argumentIndex] = nullable,
                                this._contracts[index].Name,
                                this._memberInfos[index].DeclaringType
                                ),
                            this._contracts[index].NilImplication
                            )(null);
                    }
                    else
                    {
                        (objectGraph as object[])[argumentIndex] = nullable;
                    }
                }
            }
            else if (setter != null)
            {
                if (nullable == null)
                {
                    ReflectionNilImplicationHandler.Instance.OnUnpacked(
                        new ReflectionSerializerNilImplicationHandlerOnUnpackedParameter(
                            this._memberInfos[index].GetMemberValueType(),
                            value => setter(objectGraph, nullable),
                            this._contracts[index].Name,
                            this._memberInfos[index].DeclaringType
                            ),
                        this._contracts[index].NilImplication
                        )(null);
                }
                else
                {
                    setter(objectGraph, nullable);
                }
            }

            unpacked++;

            return(objectGraph);
        }
        private void UnpackAndAddCollectionItem(object objectGraph, Unpacker unpacker, int index)
        {
            var destination = this._getters[index](objectGraph);

            if (destination == null)
            {
                throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(this._contracts[index].Name);
            }

            var traits = destination.GetType().GetCollectionTraits();

            if (traits.AddMethod == null)
            {
                throw SerializationExceptions.NewUnpackToIsNotSupported(destination.GetType(), null);
            }

            var source = this._serializers[index].UnpackFrom(unpacker) as IEnumerable;

            if (source != null)
            {
                switch (traits.DetailedCollectionType)
                {
                case CollectionDetailedKind.GenericDictionary:
                    {
                        // item should be KeyValuePair<TKey, TValue>
                        var arguments = new object[2];
                        var key       = default(PropertyInfo);
                        var value     = default(PropertyInfo);
                        foreach (var item in source)
                        {
                            if (key == null)
                            {
                                key   = item.GetType().GetProperty("Key");
                                value = item.GetType().GetProperty("Value");
                            }

                            arguments[0] = key.GetValue(item, null);
                            arguments[1] = value.GetValue(item, null);
                            traits.AddMethod.InvokePreservingExceptionType(destination, arguments);
                        }
                        break;
                    }

                case CollectionDetailedKind.NonGenericDictionary:
                    {
                        // item should be DictionaryEntry
                        var arguments = new object[2];
                        foreach (var item in source)
                        {
                            arguments[0] = DictionaryEntryKeyProperty.GetValue(item, null);
                            arguments[1] = DictionaryEntryValueProperty.GetValue(item, null);
                            traits.AddMethod.InvokePreservingExceptionType(destination, arguments);
                        }
                        break;
                    }

                default:
                    {
                        var arguments = new object[1];
                        foreach (var item in source)
                        {
                            arguments[0] = item;
                            traits.AddMethod.InvokePreservingExceptionType(destination, arguments);
                        }
                        break;
                    }
                }
            }
        }
Esempio n. 7
0
 /// <summary>
 ///		When implemented by derive class,
 ///		adds the deserialized item to the collection on <typeparamref name="TDictionary"/> specific manner
 ///		to implement <see cref="UnpackToCore(Unpacker,TDictionary)"/>.
 /// </summary>
 /// <param name="dictionary">The dictionary to be added.</param>
 /// <param name="key">The key to be added.</param>
 /// <param name="value">The value to be added.</param>
 /// <exception cref="NotSupportedException">
 ///		This implementation always throws it.
 /// </exception>
 protected virtual void AddItem(TDictionary dictionary, TKey key, TValue value)
 {
     throw SerializationExceptions.NewUnpackToIsNotSupported(typeof(TDictionary), null);
 }
Esempio n. 8
0
 /// <summary>
 ///		When implemented by derive class,
 ///		adds the deserialized item to the collection on <typeparamref name="TCollection"/> specific manner
 ///		to implement <see cref="UnpackToCore(Unpacker,TCollection)"/>.
 /// </summary>
 /// <param name="collection">The collection to be added.</param>
 /// <param name="item">The item to be added.</param>
 /// <exception cref="NotSupportedException">
 ///		This implementation always throws it.
 /// </exception>
 protected virtual void AddItem(TCollection collection, object item)
 {
     throw SerializationExceptions.NewUnpackToIsNotSupported(typeof(TCollection), null);
 }
Esempio n. 9
0
        protected internal override object UnpackFromCore(Unpacker unpacker)
#endif // !UNITY
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
            }

            if (UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as 2 element array.");
            }

            using (var wholeUnpacker = unpacker.ReadSubtree())
            {
                if (!wholeUnpacker.Read())
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                MessagePackExtendedTypeObject metadata;
                try
                {
                    metadata = wholeUnpacker.LastReadData.AsMessagePackExtendedTypeObject();
                }
                catch (InvalidOperationException ex)
                {
                    SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as ext type.", ex);
                    metadata = default(MessagePackExtendedTypeObject);                        // never reaches
                }

                if (metadata.TypeCode != this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray])
                {
                    SerializationExceptions.ThrowSerializationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            "Multidimensional array must be encoded as ext type 0x{0:X2}.",
                            this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray]
                            )
                        );
                }

                int[] lengths, lowerBounds;

                using (var arrayMetadata = new MemoryStream(metadata.Body))
                    using (var metadataUnpacker = Unpacker.Create(arrayMetadata, false))
                    {
                        if (!metadataUnpacker.Read())
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        if (!metadataUnpacker.IsArrayHeader)
                        {
                            SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                        }

                        if (UnpackHelpers.GetItemsCount(metadataUnpacker) != 2)
                        {
                            SerializationExceptions.ThrowSerializationException("Multidimensional metadata array must be encoded as 2 element array.");
                        }

                        this.ReadArrayMetadata(metadataUnpacker, out lengths, out lowerBounds);
                    }

#if SILVERLIGHT
                // Simulate lowerbounds because Array.Initialize() in Silverlight does not support lowerbounds.
                var inflatedLengths = new int[lengths.Length];
                for (var i = 0; i < lowerBounds.Length; i++)
                {
                    inflatedLengths[i] = lengths[i] + lowerBounds[i];
                }
#endif // SILVERLIGHT
                if (!wholeUnpacker.Read())
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!wholeUnpacker.IsArrayHeader)
                {
                    SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                }

                using (var arrayUnpacker = wholeUnpacker.ReadSubtree())
                {
                    var result =
                        Array.CreateInstance(
#if !UNITY
                            typeof(TItem),
#else
                            this._itemType,
#endif // !UNITY
#if !SILVERLIGHT
                            lengths,
                            lowerBounds
#else
                            inflatedLengths
#endif // !SILVERLIGHT
                            );

                    var totalLength = UnpackHelpers.GetItemsCount(arrayUnpacker);
                    if (totalLength > 0)
                    {
                        ForEach(
                            result,
                            totalLength,
                            lowerBounds,
                            lengths,
                            indices =>
                        {
                            // ReSharper disable AccessToDisposedClosure
                            if (!arrayUnpacker.Read())
                            {
                                SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                            }

                            result.SetValue(
                                this._itemSerializer.UnpackFrom(arrayUnpacker),
                                indices
                                );
                            // ReSharper restore AccessToDisposedClosure
                        }
                            );
                    }

#if !UNITY
                    return(( TArray )( object )result);
#else
                    return(result);
#endif // !UNITY
                }
            }
        }
Esempio n. 10
0
        protected internal override async Task <TArray> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
            }

            if (UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as 2 element array.");
            }

            using (var wholeUnpacker = unpacker.ReadSubtree())
            {
                if (!await wholeUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                MessagePackExtendedTypeObject metadata;
                try
                {
                    metadata = wholeUnpacker.LastReadData.AsMessagePackExtendedTypeObject();
                }
                catch (InvalidOperationException ex)
                {
                    SerializationExceptions.ThrowSerializationException("Multidimensional array must be encoded as ext type.", ex);
                    metadata = default(MessagePackExtendedTypeObject);                       // never reaches
                }

                if (metadata.TypeCode != this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray])
                {
                    SerializationExceptions.ThrowSerializationException(
                        String.Format(
                            CultureInfo.CurrentCulture,
                            "Multidimensional array must be encoded as ext type 0x{0:X2}.",
                            this.OwnerContext.ExtTypeCodeMapping[KnownExtTypeName.MultidimensionalArray]
                            )
                        );
                }

                Tuple <int[], int[]> lengthsAndLowerBounds;

                using (var arrayMetadata = new MemoryStream(metadata.Body))
                    using (var metadataUnpacker = Unpacker.Create(arrayMetadata, false))
                    {
                        if (!metadataUnpacker.Read())
                        {
                            SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                        }

                        if (!metadataUnpacker.IsArrayHeader)
                        {
                            SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                        }

                        if (UnpackHelpers.GetItemsCount(metadataUnpacker) != 2)
                        {
                            SerializationExceptions.ThrowSerializationException("Multidimensional metadata array must be encoded as 2 element array.");
                        }

                        lengthsAndLowerBounds = await this.ReadArrayMetadataAsync(metadataUnpacker, cancellationToken).ConfigureAwait(false);
                    }

                if (!await wholeUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!wholeUnpacker.IsArrayHeader)
                {
                    SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
                }

                using (var arrayUnpacker = wholeUnpacker.ReadSubtree())
                {
                    var result =
                        Array.CreateInstance(typeof(TItem), lengthsAndLowerBounds.Item1, lengthsAndLowerBounds.Item2);

                    var totalLength = UnpackHelpers.GetItemsCount(arrayUnpacker);
                    if (totalLength > 0)
                    {
                        ForEach(
                            result,
                            totalLength,
                            lengthsAndLowerBounds.Item2,
                            lengthsAndLowerBounds.Item1,
                            async indices =>
                        {
                            // ReSharper disable AccessToDisposedClosure
                            if (!await arrayUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                            {
                                SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                            }

                            result.SetValue(
                                await this._itemSerializer.UnpackFromAsync(arrayUnpacker, cancellationToken).ConfigureAwait(false),
                                indices
                                );
                            // ReSharper restore AccessToDisposedClosure
                        }
                            );
                    }

                    return(( TArray )( object )result);
                }
            }
        }
Esempio n. 11
0
        private void UnpackFromMap(Unpacker unpacker, ref T instance)
        {
            while (unpacker.Read())
            {
                var memberName = GetMemberName(unpacker);
                int index;
                if (!this._indexMap.TryGetValue(memberName, out index))
                {
                    // Drains unused value.
                    if (!unpacker.Read())
                    {
                        throw SerializationExceptions.NewUnexpectedEndOfStream();
                    }

                    // TODO: unknown member handling.

                    continue;
                }

                // Fetches value
                if (!unpacker.Read())
                {
                    throw SerializationExceptions.NewUnexpectedEndOfStream();
                }

                if (unpacker.Data.Value.IsNil)
                {
                    switch (this._nilImplications[index])
                    {
                    case NilImplication.Null:
                    {
                        if (this._memberSetters[index] == null)
                        {
                            throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(this._memberNames[index]);
                        }

                        this._memberSetters[index](ref instance, null);
                        continue;
                    }

                    case NilImplication.MemberDefault:
                    {
                        continue;
                    }

                    case NilImplication.Prohibit:
                    {
                        throw SerializationExceptions.NewNullIsProhibited(this._memberNames[index]);
                    }
                    }
                }

                if (unpacker.IsArrayHeader || unpacker.IsMapHeader)
                {
                    using (var subtreeUnpacker = unpacker.ReadSubtree())
                    {
                        this.UnpackMemberInMap(subtreeUnpacker, ref instance, index);
                    }
                }
                else
                {
                    this.UnpackMemberInMap(unpacker, ref instance, index);
                }
            }
        }
Esempio n. 12
0
        public MapReflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits)
            : base(type, (context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions)
        {
            Contract.Assert(typeof(IEnumerable).IsAssignableFrom(type), type + " is IEnumerable");
            Contract.Assert(traits.ElementType == typeof(DictionaryEntry) || (traits.ElementType.GetIsGenericType() && traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)), "Element type " + traits.ElementType + " is not KeyValuePair<TKey,TValue>.");
            this._traits          = traits;
            this._keySerializer   = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[0]) : context.GetSerializer(typeof(MessagePackObject));
            this._valueSerializer = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[1]) : context.GetSerializer(typeof(MessagePackObject));
            this._getCount        = ReflectionSerializerLogics.CreateGetCount(type, traits);

            var constructor = ReflectionSerializerLogics.GetCollectionConstructor(context, type);

            if (constructor == null)
            {
                this._createInstance             = () => { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(type); };
                this._createInstanceWithCapacity = null;
            }
            else if (constructor.GetParameters().Length == 1)
            {
                this._createInstance = null;

                this._createInstanceWithCapacity = length => constructor.Invoke(new object[] { length });
            }
            else
            {
                this._createInstanceWithCapacity = null;
                this._createInstance             = () => constructor.Invoke(new object[0]);
            }

            var keyType       = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[0] : typeof(MessagePackObject);
            var valueType     = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[1] : typeof(MessagePackObject);
            var keyProperty   = traits.ElementType.GetProperty("Key");
            var valueProperty = traits.ElementType.GetProperty("Value");

            this._packToCore = (Packer packer, object objectTree, IMessagePackSerializer keySerializer, IMessagePackSerializer valueSerializer) =>
            {
                packer.PackMapHeader(this._getCount(objectTree));
                foreach (var kvp in (IEnumerable)objectTree)
                {
                    keySerializer.PackTo(packer, keyProperty.GetValue(kvp, new object[0]));
                    valueSerializer.PackTo(packer, valueProperty.GetValue(kvp, new object[0]));
                }
            };

            if (traits.ElementType.GetIsGenericType())
            {
                /*
                 * UnpackHelpers.UnpackMapTo<TKey,TValue>( unpacker, keySerializer, valueSerializer, instance );
                 */
                var unpackMapToMethod = Metadata._UnpackHelpers.UnpackMapTo_2;   //.MakeGenericMethod(keyType, valueType);
                this._unpackToCore = (Unpacker unpacker, object objectTree, IMessagePackSerializer keySerializer, IMessagePackSerializer valueSerializer) =>
                {
                    unpackMapToMethod.Invoke(null, new object[] { unpacker, keySerializer, valueSerializer, objectTree });
                };
            }
            else
            {
                /*
                 * UnpackHelpers.UnpackNonGenericMapTo( unpacker, instance );
                 */
                this._unpackToCore = (Unpacker unpacker, object objectTree, IMessagePackSerializer keySerializer, IMessagePackSerializer valueSerializer) => UnpackHelpers.UnpackMapTo(unpacker, (IDictionary)objectTree);
            }
        }
Esempio n. 13
0
 protected virtual void AddItem(object collection, object item)
 {
     throw SerializationExceptions.NewUnpackToIsNotSupported(this.TargetType, null);
 }
Esempio n. 14
0
        protected internal override Matrix4x4 UnpackFromCore(Unpacker unpacker)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Matrix4x4), 16);
            }

            var length = unpacker.LastReadData.AsInt64();

            if (length != 16)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Matrix4x4), 16);
            }

            float m11;

            if (!unpacker.ReadSingle(out m11))
            {
                SerializationExceptions.ThrowMissingItem(0, unpacker);
            }

            float m12;

            if (!unpacker.ReadSingle(out m12))
            {
                SerializationExceptions.ThrowMissingItem(1, unpacker);
            }

            float m13;

            if (!unpacker.ReadSingle(out m13))
            {
                SerializationExceptions.ThrowMissingItem(2, unpacker);
            }

            float m14;

            if (!unpacker.ReadSingle(out m14))
            {
                SerializationExceptions.ThrowMissingItem(3, unpacker);
            }

            float m21;

            if (!unpacker.ReadSingle(out m21))
            {
                SerializationExceptions.ThrowMissingItem(4, unpacker);
            }

            float m22;

            if (!unpacker.ReadSingle(out m22))
            {
                SerializationExceptions.ThrowMissingItem(5, unpacker);
            }

            float m23;

            if (!unpacker.ReadSingle(out m23))
            {
                SerializationExceptions.ThrowMissingItem(6, unpacker);
            }

            float m24;

            if (!unpacker.ReadSingle(out m24))
            {
                SerializationExceptions.ThrowMissingItem(7, unpacker);
            }

            float m31;

            if (!unpacker.ReadSingle(out m31))
            {
                SerializationExceptions.ThrowMissingItem(8, unpacker);
            }

            float m32;

            if (!unpacker.ReadSingle(out m32))
            {
                SerializationExceptions.ThrowMissingItem(9, unpacker);
            }

            float m33;

            if (!unpacker.ReadSingle(out m33))
            {
                SerializationExceptions.ThrowMissingItem(10, unpacker);
            }

            float m34;

            if (!unpacker.ReadSingle(out m34))
            {
                SerializationExceptions.ThrowMissingItem(11, unpacker);
            }

            float m41;

            if (!unpacker.ReadSingle(out m41))
            {
                SerializationExceptions.ThrowMissingItem(12, unpacker);
            }

            float m42;

            if (!unpacker.ReadSingle(out m42))
            {
                SerializationExceptions.ThrowMissingItem(13, unpacker);
            }

            float m43;

            if (!unpacker.ReadSingle(out m43))
            {
                SerializationExceptions.ThrowMissingItem(14, unpacker);
            }

            float m44;

            if (!unpacker.ReadSingle(out m44))
            {
                SerializationExceptions.ThrowMissingItem(15, unpacker);
            }


            return(new Matrix4x4(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44));
        }
        protected internal override T UnpackFromCore(Unpacker unpacker)
        {
            object result =
                this._constructorParameters == null
                                        ? ReflectionExtensions.CreateInstancePreservingExceptionType(typeof(T))
                                        : this._constructorParameters.Select(p =>
                                                                             p.GetHasDefaultValue()
                                                ? p.DefaultValue
                                                : p.ParameterType.GetIsValueType()
                                                ? ReflectionExtensions.CreateInstancePreservingExceptionType(p.ParameterType)
                                                : null
                                                                             ).ToArray();

            var unpacked = 0;

            var asUnpackable = result as IUnpackable;

            if (asUnpackable != null)
            {
                asUnpackable.UnpackFromMessage(unpacker);
                return(( T )result);
            }

            if (unpacker.IsArrayHeader)
            {
                var itemsCount = UnpackHelpers.GetItemsCount(unpacker);

                for (int i = 0; i < itemsCount; i++)
                {
                    result = this.UnpackMemberValue(result, unpacker, itemsCount, ref unpacked, i, i);
                }
            }
            else
            {
#if DEBUG && !UNITY
                Contract.Assert(unpacker.IsMapHeader, "unpacker.IsMapHeader");
#endif // DEBUG && !UNITY
                var itemsCount = UnpackHelpers.GetItemsCount(unpacker);

                for (int i = 0; i < itemsCount; i++)
                {
                    string name;
                    if (!unpacker.ReadString(out name))
                    {
                        throw SerializationExceptions.NewUnexpectedEndOfStream();
                    }

                    if (name == null)
                    {
                        // missing member, drain the value and discard it.
                        if (!unpacker.Read())
                        {
                            throw SerializationExceptions.NewMissingItem(i);
                        }
                        continue;
                    }

                    int index;
                    if (!this._memberIndexes.TryGetValue(name, out index))
                    {
                        // key does not exist in the object, skip the associated value
                        if (unpacker.Skip() == null)
                        {
                            throw SerializationExceptions.NewMissingItem(i);
                        }
                        continue;
                    }

                    result = this.UnpackMemberValue(result, unpacker, itemsCount, ref unpacked, index, i);
                }
            }

            if (this._constructorParameters == null)
            {
                return(( T )result);
            }
            else
            {
                return(ReflectionExtensions.CreateInstancePreservingExceptionType <T>(typeof(T), result as object[]));
            }
        }
Esempio n. 16
0
        protected internal override async Task <Matrix4x4> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Matrix4x4), 16);
            }

            var length = unpacker.LastReadData.AsInt64();

            if (length != 16)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Matrix4x4), 16);
            }

            var m11 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m11.Success)
            {
                SerializationExceptions.ThrowMissingItem(0, unpacker);
            }

            var m12 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m12.Success)
            {
                SerializationExceptions.ThrowMissingItem(1, unpacker);
            }

            var m13 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m13.Success)
            {
                SerializationExceptions.ThrowMissingItem(2, unpacker);
            }

            var m14 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m14.Success)
            {
                SerializationExceptions.ThrowMissingItem(3, unpacker);
            }

            var m21 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m21.Success)
            {
                SerializationExceptions.ThrowMissingItem(4, unpacker);
            }

            var m22 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m22.Success)
            {
                SerializationExceptions.ThrowMissingItem(5, unpacker);
            }

            var m23 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m23.Success)
            {
                SerializationExceptions.ThrowMissingItem(6, unpacker);
            }

            var m24 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m24.Success)
            {
                SerializationExceptions.ThrowMissingItem(7, unpacker);
            }

            var m31 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m31.Success)
            {
                SerializationExceptions.ThrowMissingItem(8, unpacker);
            }

            var m32 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m32.Success)
            {
                SerializationExceptions.ThrowMissingItem(9, unpacker);
            }

            var m33 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m33.Success)
            {
                SerializationExceptions.ThrowMissingItem(10, unpacker);
            }

            var m34 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m34.Success)
            {
                SerializationExceptions.ThrowMissingItem(11, unpacker);
            }

            var m41 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m41.Success)
            {
                SerializationExceptions.ThrowMissingItem(12, unpacker);
            }

            var m42 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m42.Success)
            {
                SerializationExceptions.ThrowMissingItem(13, unpacker);
            }

            var m43 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m43.Success)
            {
                SerializationExceptions.ThrowMissingItem(14, unpacker);
            }

            var m44 = await unpacker.ReadSingleAsync(cancellationToken).ConfigureAwait(false);

            if (!m44.Success)
            {
                SerializationExceptions.ThrowMissingItem(15, unpacker);
            }


            return(new Matrix4x4(m11.Value, m12.Value, m13.Value, m14.Value, m21.Value, m22.Value, m23.Value, m24.Value, m31.Value, m32.Value, m33.Value, m34.Value, m41.Value, m42.Value, m43.Value, m44.Value));
        }
        private void BuildMapUnpackFrom(TContext context)
        {
            this.EmitMethodPrologue(context, SerializerMethod.UnpackFromCore);
            TConstruct construct = null;

            try
            {
                Type instanceType;
                if (typeof(TObject).GetIsInterface() || typeof(TObject).GetIsAbstract())
                {
                    instanceType = context.SerializationContext.DefaultCollectionTypes.GetConcreteType(typeof(TObject));
                    if (instanceType == null)
                    {
                        throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(typeof(TObject));
                    }
                }
                else
                {
                    instanceType = typeof(TObject);
                }

                /*
                 *	if (!unpacker.IsMapHeader)
                 *	{
                 *		throw SerializationExceptions.NewIsNotMapHeader();
                 *	}
                 *	int capacity = ITEMS_COUNT(unpacker);
                 *
                 *	TDictionary<TKey, TValue> dictionary = new ...;
                 *	this.UnpackToCore(unpacker, dictionary);
                 *	return dictionary;
                 */
                var collection =
                    this.DeclareLocal(
                        context,
                        typeof(TObject),
                        "collection"
                        );

                construct =
                    this.EmitSequentialStatements(
                        context,
                        typeof(TObject),
                        this.EmitCheckIsMapHeaderExpression(context, context.Unpacker),
                        collection,
                        this.EmitUnpackCollectionWithUnpackToExpression(
                            context,
                            GetCollectionConstructor(instanceType),
                            this.EmitGetItemsCountExpression(context, context.Unpacker),
                            context.Unpacker,
                            collection
                            ),
                        this.EmitRetrunStatement(
                            context,
                            this.EmitLoadVariableExpression(context, collection)
                            )
                        );
            }
            finally
            {
                this.EmitMethodEpilogue(context, SerializerMethod.UnpackFromCore, construct);
            }
        }