Ejemplo n.º 1
0
        protected internal override async Task <TCollection> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            if (this._isAsyncUnpackable)
            {
                var result = this.CreateInstance(0);
                await(( IAsyncUnpackable )result).UnpackFromMessageAsync(unpacker, cancellationToken).ConfigureAwait(false);
                return(result);
            }

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

            var itemsCount = UnpackHelpers.GetItemsCount(unpacker);
            var collection = this.CreateInstance(itemsCount);

            await this.UnpackToAsyncCore(unpacker, collection, itemsCount, cancellationToken).ConfigureAwait(false);

            return(collection);
        }
Ejemplo n.º 2
0
        protected internal override object UnpackFromCore(Unpacker unpacker)
#endif // !UNITY
        {
            if (this._isUnpackable)
            {
                var result = this.CreateInstance(0);
                (( IUnpackable )result).UnpackFromMessage(unpacker);
                return(result);
            }

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

            var itemsCount = UnpackHelpers.GetItemsCount(unpacker);
            var collection = this.CreateInstance(itemsCount);

            this.UnpackToCore(unpacker, collection, itemsCount);
            return(collection);
        }
        protected internal override T UnpackFromCore(Unpacker unpacker)
        {
            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }

            if (this._collectionDeserializer != null)
            {
                // Fast path:
                return(( T )this._collectionDeserializer.UnpackFrom(unpacker));
            }

            var itemsCount = UnpackHelpers.GetItemsCount(unpacker);
            var collection =
                ( T )(this._collectionConstructorWithoutCapacity != null
                                        ? this._collectionConstructorWithoutCapacity.Invoke(null)
                                        : this._collectionConstructorWithCapacity.Invoke(new object[] { itemsCount }));

            this.UnpackToCore(unpacker, collection, itemsCount);
            return(collection);
        }
        protected internal override void UnpackToCore(Unpacker unpacker, T collection)
        {
            if (this._collectionDeserializer != null)
            {
                // Fast path:
                this._collectionDeserializer.UnpackTo(unpacker, collection);
            }
            else
            {
                if (this._addItem == null)
                {
                    throw SerializationExceptions.NewUnpackToIsNotSupported(typeof(T), null);
                }

                if (!unpacker.IsArrayHeader)
                {
                    throw SerializationExceptions.NewIsNotArrayHeader();
                }

                this.UnpackToCore(unpacker, collection, UnpackHelpers.GetItemsCount(unpacker));
            }
        }
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            LocalBuilder itemsCount = localHolder.ItemsCount;
            LocalBuilder local      = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);
            for (int i = 0; i < entries.Length; i++)
            {
                Label endOfDeserialization = unpackerIL.DefineLabel("END_IF");
                Label target = unpackerIL.DefineLabel("ELSE");
                unpackerIL.EmitAnyLdloc(local);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBlt(target);
                if (entries[i].Member != null)
                {
                    Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endOfDeserialization, localHolder);
                }
                unpackerIL.EmitBr(endOfDeserialization);
                unpackerIL.MarkLabel(target);
                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder);
                }
                else
                {
                    Emittion.EmitDeserializeValue(emitter, unpackerIL, 1, result, entries[i], localHolder);
                }
                unpackerIL.EmitAnyLdloc(local);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(local);
                unpackerIL.MarkLabel(endOfDeserialization);
            }
        }
Ejemplo n.º 6
0
        private static async Task UnpackToAsyncCore(Unpacker unpacker, NameValueCollection collection, int keyCount, CancellationToken cancellationToken)
        {
            for (var k = 0; k < keyCount; k++)
            {
                var key = await unpacker.ReadStringAsync(cancellationToken).ConfigureAwait(false);

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

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

                if (!unpacker.IsArrayHeader)
                {
                    throw new SerializationException("Invalid NameValueCollection value.");
                }

                var itemsCount = UnpackHelpers.GetItemsCount(unpacker);
                using (var valuesUnpacker = unpacker.ReadSubtree())
                {
                    for (var v = 0; v < itemsCount; v++)
                    {
                        var value = await valuesUnpacker.ReadStringAsync(cancellationToken).ConfigureAwait(false);

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

                        collection.Add(key.Value, value.Value);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        protected internal override Vector3 UnpackFromCore(Unpacker unpacker)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Vector3), 3);
            }

            var length = UnpackHelpers.GetItemsCount(unpacker);

            if (length != 3)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Vector3), 3);
            }

            float x;

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

            float y;

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

            float z;

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


            return(new Vector3(x, y, z));
        }
        protected internal override Version UnpackFromCore(Unpacker unpacker)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Version), 4);
            }

            long length = UnpackHelpers.GetItemsCount(unpacker);

            if (length != 4)
            {
                SerializationExceptions.ThrowInvalidArrayItemsCount(unpacker, typeof(Version), 4);
            }

            int major, minor, build, revision;

            if (!unpacker.ReadInt32(out major))
            {
                SerializationExceptions.ThrowMissingItem(0, unpacker);
            }

            if (!unpacker.ReadInt32(out minor))
            {
                SerializationExceptions.ThrowMissingItem(1, unpacker);
            }

            if (!unpacker.ReadInt32(out build))
            {
                SerializationExceptions.ThrowMissingItem(2, unpacker);
            }

            if (!unpacker.ReadInt32(out revision))
            {
                SerializationExceptions.ThrowMissingItem(3, unpacker);
            }

            return(new Version(major, minor, build, revision));
        }
Ejemplo n.º 9
0
        private static void UnpackToCore(Unpacker unpacker, NameValueCollection collection, int keyCount)
        {
            for (var k = 0; k < keyCount; k++)
            {
                string key;
                if (!unpacker.ReadString(out key))
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!unpacker.Read())
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                }

                if (!unpacker.IsArrayHeader)
                {
                    throw new SerializationException("Invalid NameValueCollection value.");
                }

                var itemsCount = UnpackHelpers.GetItemsCount(unpacker);
                using (var valuesUnpacker = unpacker.ReadSubtree())
                {
                    for (var v = 0; v < itemsCount; v++)
                    {
                        string value;

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

                        collection.Add(key, value);
                    }
                }
            }
        }
        protected override T[] UnpackFromCore(Unpacker unpacker)
        {
            MessagePackSerializer <T> serializer = base.OwnerContext.GetSerializer <T>();

            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }
            int itemsCount = UnpackHelpers.GetItemsCount(unpacker);

            T[] array = new T[itemsCount];
            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }
            for (int i = 0; i < itemsCount; i++)
            {
                if (!unpacker.Read())
                {
                    throw SerializationExceptions.NewMissingItem(i);
                }
                T val = default(T);
                if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                {
                    val = serializer.UnpackFrom(unpacker);
                }
                else
                {
                    using (Unpacker unpacker2 = unpacker.ReadSubtree())
                    {
                        val = serializer.UnpackFrom(unpacker2);
                    }
                }
                array[i] = val;
            }
            return(array);
        }
        private void BuildCollectionCreateInstance(TContext context, Type concreteType)
        {
            context.BeginMethodOverride(MethodName.CreateInstance);

            var instanceType = concreteType ?? this.TargetType;
            var collection   =
                this.DeclareLocal(
                    context,
                    this.TargetType,
                    "collection"
                    );
            var ctor          = UnpackHelpers.GetCollectionConstructor(instanceType);
            var ctorArguments = this.DetermineCollectionConstructorArguments(context, ctor);

            context.EndMethodOverride(
                MethodName.CreateInstance,
                this.EmitSequentialStatements(
                    context,
                    this.TargetType,
                    collection,
                    this.EmitStoreVariableStatement(
                        context,
                        collection,
                        this.EmitCreateNewObjectExpression(
                            context,
                            collection,
                            ctor,
                            ctorArguments
                            )
                        ),
                    this.EmitRetrunStatement(
                        context,
                        this.EmitLoadVariableExpression(context, collection)
                        )
                    )
                );
        }
Ejemplo n.º 12
0
        protected override List <T> UnpackFromCore(Unpacker unpacker)
        {
            MessagePackSerializer <T> serializer = base.OwnerContext.GetSerializer <T>();

            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }
            int      itemsCount = UnpackHelpers.GetItemsCount(unpacker);
            List <T> list       = new List <T>();

            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }
            for (int i = 0; i < itemsCount; i++)
            {
                if (!unpacker.Read())
                {
                    throw SerializationExceptions.NewMissingItem(i);
                }
                T item = default(T);
                if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                {
                    item = serializer.UnpackFrom(unpacker);
                }
                else
                {
                    using (Unpacker unpacker2 = unpacker.ReadSubtree())
                    {
                        item = serializer.UnpackFrom(unpacker2);
                    }
                }
                list.Add(item);
            }
            return(list);
        }
        protected internal override async Task <T> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
            }

            var buffer = new TItem[UnpackHelpers.GetItemsCount(unpacker)];

            using (var subTreeUnpacker = unpacker.ReadSubtree())
            {
                for (int i = 0; i < buffer.Length; i++)
                {
                    if (!await subTreeUnpacker.ReadAsync(cancellationToken).ConfigureAwait(false))
                    {
                        SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                    }

                    buffer[i] = await this.ItemSerializer.UnpackFromAsync(subTreeUnpacker, cancellationToken).ConfigureAwait(false);
                }
            }

            return(this.Factory(buffer));
        }
        protected internal override T UnpackFromCore(Unpacker unpacker)
        {
            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(unpacker);
            }

            var buffer = new TItem[UnpackHelpers.GetItemsCount(unpacker)];

            using (var subTreeUnpacker = unpacker.ReadSubtree())
            {
                for (int i = 0; i < buffer.Length; i++)
                {
                    if (!subTreeUnpacker.Read())
                    {
                        SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker);
                    }

                    buffer[i] = this.ItemSerializer.UnpackFrom(subTreeUnpacker);
                }
            }

            return(this.Factory(buffer));
        }
Ejemplo n.º 15
0
        public static async Task <T> DecodeAsync <T>(Unpacker unpacker, Func <Unpacker, CancellationToken, Task <Type> > asyncTypeDecoder, Func <Type, Unpacker, CancellationToken, Task <object> > unpackingAsync, CancellationToken cancellationToken)
        {
            if (!unpacker.IsArrayHeader || UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                throw SerializationExceptions.NewUnknownTypeEmbedding();
            }

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

                var type = await asyncTypeDecoder(subTreeUnpacker, cancellationToken).ConfigureAwait(false);

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

                return((T) await unpackingAsync(type, subTreeUnpacker, cancellationToken).ConfigureAwait(false));
            }
        }
Ejemplo n.º 16
0
        public static T Decode <T>(Unpacker unpacker, Func <Unpacker, Type> typeDecoder, Func <Type, Unpacker, T> unpacking)
        {
            if (!unpacker.IsArrayHeader || UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                throw SerializationExceptions.NewUnknownTypeEmbedding();
            }

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

                var type = typeDecoder(subTreeUnpacker);

                if (!subTreeUnpacker.Read())
                {
                    SerializationExceptions.ThrowUnexpectedEndOfStream(subTreeUnpacker);
                }

                return(unpacking(type, subTreeUnpacker));
            }
        }
        public static MessagePackSerializer CreateCollectionSerializer <T>(
#endif // !UNITY
            SerializationContext context,
            Type targetType,
            CollectionTraits traits,
            PolymorphismSchema schema
            )
        {
            var targetInfo = UnpackHelpers.DetermineCollectionSerializationStrategy(targetType, context.CompatibilityOptions.AllowAsymmetricSerializer);

            switch (traits.DetailedCollectionType)
            {
            case CollectionDetailedKind.Array:
            {
                return(ArraySerializer.Create <T>(context, schema));
            }

            case CollectionDetailedKind.GenericList:
#if !NETFX_35 && !UNITY
            case CollectionDetailedKind.GenericSet:
#endif // !NETFX_35 && !UNITY
            case CollectionDetailedKind.GenericCollection:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(CollectionSerializerFactory <,>).MakeGenericType(typeof(T), traits.ElementType)
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionCollectionMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.GenericEnumerable:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(EnumerableSerializerFactory <,>).MakeGenericType(typeof(T), traits.ElementType)
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionEnumerableMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !Enumerable
            }

            case CollectionDetailedKind.GenericDictionary:
            {
                var genericArgumentOfKeyValuePair = traits.ElementType.GetGenericArguments();
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(DictionarySerializerFactory <, ,>).MakeGenericType(
                             typeof(T),
                             genericArgumentOfKeyValuePair[0],
                             genericArgumentOfKeyValuePair[1]
                             )
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionDictionaryMessagePackSerializer(
                         context,
                         typeof(T),
                         targetType,
                         genericArgumentOfKeyValuePair[0],
                         genericArgumentOfKeyValuePair[1],
                         traits,
                         schema,
                         targetInfo
                         );
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericList:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericListSerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericListMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericCollection:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericCollectionSerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericCollectionMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericEnumerable:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericEnumerableSerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericEnumerableMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            case CollectionDetailedKind.NonGenericDictionary:
            {
                return
                    (#if !UNITY
                     (MessagePackSerializer <T>)
                     ReflectionExtensions.CreateInstancePreservingExceptionType <IVariantReflectionSerializerFactory>(
                         typeof(NonGenericDictionarySerializerFactory <>).MakeGenericType(typeof(T))
                         ).Create(context, targetType, traits, schema, targetInfo));
#else
                     new ReflectionNonGenericDictionaryMessagePackSerializer(context, typeof(T), targetType, traits, schema, targetInfo);
#endif // !UNITY
            }

            default:
            {
                return(null);
            }
            }
        }
        public void UnpackFromMessage(Unpacker unpacker)
        {
            // Unpack fields are here:

            // temp variables
            long   id;
            string name;

            // It should be packed as array because we use hand-made packing implementation above.
            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }

            // Check items count.
            if (UnpackHelpers.GetItemsCount(unpacker) != 2)
            {
                throw SerializationExceptions.NewUnexpectedArrayLength(2, UnpackHelpers.GetItemsCount(unpacker));
            }

            // Unpack fields here:
            if (!unpacker.ReadInt64(out id))
            {
                throw SerializationExceptions.NewMissingProperty("Id");
            }

            this.Id = id;

            if (!unpacker.ReadString(out name))
            {
                throw SerializationExceptions.NewMissingProperty("Name");
            }

            this.Name = name;

            // ...Instead, you can unpack from map as follows:
            //if ( !unpacker.IsMapHeader )
            //{
            //	throw SerializationExceptions.NewIsNotMapHeader();
            //}

            //// Check items count.
            //if ( UnpackHelpers.GetItemsCount( unpacker ) != 2 )
            //{
            //	throw SerializationExceptions.NewUnexpectedArrayLength( 2, UnpackHelpers.GetItemsCount( unpacker ) );
            //}

            //// Unpack fields here:
            //for ( int i = 0; i < 2 /* known count of fields */; i++ )
            //{
            //	// Unpack and verify key of entry in map.
            //	string key;
            //	if ( !unpacker.ReadString( out key ) )
            //	{
            //		// Missing key, incorrect.
            //		throw SerializationExceptions.NewUnexpectedEndOfStream();
            //	}

            //	switch ( key )
            //	{
            //		case "Id":
            //		{
            //			if ( !unpacker.ReadInt64( out id ) )
            //			{
            //				throw SerializationExceptions.NewMissingProperty( "Id" );
            //			}
            //
            //          this.Id = id;
            //			break;
            //		}
            //		case "Name":
            //		{
            //			if ( !unpacker.ReadString( out name ) )
            //			{
            //				throw SerializationExceptions.NewMissingProperty( "Name" );
            //			}
            //
            //          this.Name = name;
            //			break;
            //		}

            //		// Note: You should ignore unknown fields for forward compatibility.
            //	}
            //}
        }
Ejemplo n.º 19
0
        public static Func <int, object> CreateCollectionInstanceFactory(Type abstractType, Type targetType, Type comparisonType)
#endif // !UNITY
        {
            var constructor = UnpackHelpers.GetCollectionConstructor(targetType);
            var parameters = constructor.GetParameters();

            switch (parameters.Length)
            {
            case 0:
            {
                return(_ =>
#if !UNITY
                       (T)
#endif // !UNITY
                       constructor.InvokePreservingExceptionType());
            }

            case 1:
            {
                if (parameters[0].ParameterType == typeof(int))
                {
                    return(capacity =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(capacity));
                }
                else if (UnpackHelpers.IsIEqualityComparer(parameters[0].ParameterType))
                {
                    var comparer =
#if !UNITY
                        EqualityComparer <TKey> .Default;
#else
                        UnpackHelpers.GetEqualityComparer(comparisonType);
#endif // !UNITY
                    return(_ =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(comparer));
                }

                break;
            }

            case 2:
            {
                var comparer =
#if !UNITY
                    EqualityComparer <TKey> .Default;
#else
                    UnpackHelpers.GetEqualityComparer(comparisonType);
#endif // !UNITY
                if (parameters[0].ParameterType == typeof(int) &&
                    UnpackHelpers.IsIEqualityComparer(parameters[1].ParameterType))
                {
                    return(capacity =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(capacity, comparer));
                }
                else if (UnpackHelpers.IsIEqualityComparer(parameters[0].ParameterType) &&
                         parameters[0].ParameterType == typeof(int))
                {
                    return(capacity =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(comparer, capacity));
                }

                break;
            }
            }

            throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(
#if !UNITY
                      typeof(T)
#else
                      abstractType
#endif // !UNITY
                      );
        }
Ejemplo n.º 20
0
        protected SequenceReflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits)
            : base(type, (context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions)
        {
            Contract.Assert(type.IsArray || typeof(IEnumerable).IsAssignableFrom(type), type + " is not array nor IEnumerable");
            this._traits            = traits;
            this._elementSerializer = context.GetSerializer(traits.ElementType);
            this._getCount          = ReflectionSerializerLogics.CreateGetCount(type, traits);

            //var packerParameter = Expression.Parameter(typeof(Packer), "packer");
            //var objectTreeParameter = Expression.Parameter(typeof(T), "objectTree");
            //var elementSerializerParameter = Expression.Parameter(typeof(IMessagePackSerializer), "elementSerializer");

            this._packToCore = (Packer packer, object objectTree, IMessagePackSerializer elementSerializer) =>
            {
                var length = this._getCount(objectTree);
                packer.PackArrayHeader(length);
                foreach (var item in (IEnumerable)objectTree)
                {
                    elementSerializer.PackTo(packer, item);
                }
            };


            /*
             *	for ( int i = 0; i < count; i++ )
             *	{
             *		if ( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewMissingItem( i );
             *		}
             *
             *		T item;
             *		if ( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
             *		{
             *			item = this.ElementSerializer.UnpackFrom( unpacker );
             *		}
             *		else
             *		{
             *			using ( Unpacker subtreeUnpacker = unpacker.ReadSubtree() )
             *			{
             *				item = this.ElementSerializer.UnpackFrom( subtreeUnpacker );
             *			}
             *		}
             *
             *		instance[ i ] = item; -- OR -- instance.Add( item );
             *	}
             */

            // FIXME: use UnpackHelper

            if (type.IsArray)
            {
                var arrayUnpackerMethod = _UnpackHelpers.UnpackArrayTo_1.MakeGenericMethod(traits.ElementType);
                this._unpackToCore = (Unpacker unpacker, object instance, IMessagePackSerializer elementSerializer) =>
                {
                    arrayUnpackerMethod.Invoke(null, new object[] { unpacker, elementSerializer, instance });
                };
            }
            else
            {
                this._unpackToCore = (Unpacker unpacker, object instance, IMessagePackSerializer elementSerializer) =>
                {
                    var count = UnpackHelpers.GetItemsCount(unpacker);
                    for (int i = 0; i < count; i++)
                    {
                        if (!unpacker.Read())
                        {
                            throw SerializationExceptions.NewMissingItem(i);
                        }
                        object item;
                        if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                        {
                            item = elementSerializer.UnpackFrom(unpacker);
                        }
                        else
                        {
                            using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
                            {
                                item = elementSerializer.UnpackFrom(subtreeUnpacker);
                            }
                        }
                        traits.AddMethod.Invoke(instance, new object[] { item });
                    }
                };
            }
        }
        protected internal override T UnpackFromCore(Unpacker unpacker)
        {
            var result   = Activator.CreateInstance <T>();
            var unpacked = 0;

            var asUnpackable = result as IUnpackable;

            if (asUnpackable != null)
            {
                asUnpackable.UnpackFromMessage(unpacker);
                return(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);
#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);
                }
            }

            return(result);
        }
Ejemplo n.º 22
0
        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[]));
            }
        }
Ejemplo n.º 23
0
        protected internal override object UnpackFromCore(Unpacker unpacker)
#endif // !UNITY
        {
            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }

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

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

                MessagePackExtendedTypeObject metadata;
                try
                {
                    metadata = wholeUnpacker.LastReadData.AsMessagePackExtendedTypeObject();
                }
                catch (InvalidOperationException ex)
                {
                    throw new SerializationException("Multidimensional array must be encoded as ext type.", ex);
                }

                if (metadata.TypeCode != MultidimensionalArray)
                {
                    throw new SerializationException(
                              String.Format(
                                  CultureInfo.CurrentCulture,
                                  "Multidimensional array must be encoded as ext type {0}.",
                                  MultidimensionalArray
                                  )
                              );
                }

                int[] lengths, lowerBounds;

                using (var arrayMetadata = new MemoryStream(metadata.Body))
                    using (var metadataUnpacker = Unpacker.Create(arrayMetadata))
                    {
                        if (!metadataUnpacker.Read())
                        {
                            throw SerializationExceptions.NewUnexpectedEndOfStream();
                        }

                        if (!metadataUnpacker.IsArrayHeader)
                        {
                            throw SerializationExceptions.NewIsNotArrayHeader();
                        }

                        if (UnpackHelpers.GetItemsCount(metadataUnpacker) != 2)
                        {
                            throw new SerializationException("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.
                for (var i = 0; i < lowerBounds.Length; i++)
                {
                    lengths[i] += lowerBounds[i];
                }
#endif // SILVERLIGHT
                if (!wholeUnpacker.Read())
                {
                    throw SerializationExceptions.NewUnexpectedEndOfStream();
                }

                if (!wholeUnpacker.IsArrayHeader)
                {
                    throw SerializationExceptions.NewIsNotArrayHeader();
                }

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

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

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

#if !UNITY
                    return(( TArray )( object )result);
#else
                    return(result);
#endif // !UNITY
                }
            }
        }
Ejemplo n.º 24
0
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder, Label endOfDeserialization)
        {
            /*
             *  int unpacked = 0;
             *  int itemsCount = unpacker.ItemsCount;
             *
             *  :
             *  if( unpacked >= itemsCount )
             *  {
             *		HandleNilImplication(...);
             *  }
             *  else
             *  {
             *  #if PRIMITIVE
             *		if( !unpacker.ReadT( out local1 ) )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *  #else
             *		if( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *
             *		local1 = this._serializer1.Unpack
             *	#endif
             *		unpacked++;
             *	}
             *	:
             */

            // TODO: Supports ExtensionObject like round-tripping.

            var itemsCount = localHolder.ItemsCount;
            var unpacked   = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);

            for (int i = 0; i < entries.Length; i++)
            {
                var endIf0 = unpackerIL.DefineLabel("END_IF");
                var else0  = unpackerIL.DefineLabel("ELSE");

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBge(else0);

                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                    // Ignore undefined member -- Nop.
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i].Member,
                        entries[i].Member.GetMemberValueType(),
                        entries[i].Contract.NilImplication,
                        localHolder
                        );
                }
                else
                {
                    Emittion.EmitDeserializeValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i],
                        localHolder
                        );
                }

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(unpacked);

                unpackerIL.EmitBr(endIf0);

                unpackerIL.MarkLabel(else0);

                if (entries[i].Member != null)
                {
                    // Respect nil implication.
                    switch (entries[i].Contract.NilImplication)
                    {
                    case NilImplication.MemberDefault:
                    {
                        unpackerIL.EmitBr(endOfDeserialization);
                        break;
                    }

                    case NilImplication.Null:
                    {
                        if (entries[i].Member.GetMemberValueType().GetIsValueType())
                        {
                            if (Nullable.GetUnderlyingType(entries[i].Member.GetMemberValueType()) == null)
                            {
                                // val type

                                /*
                                 * if( value == null )
                                 * {
                                 *		throw SerializationEceptions.NewValueTypeCannotBeNull( "...", typeof( MEMBER ), typeof( TYPE ) );
                                 * }
                                 */
                                unpackerIL.EmitLdstr(entries[i].Contract.Name);
                                unpackerIL.EmitLdtoken(entries[i].Member.GetMemberValueType());
                                unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                                unpackerIL.EmitLdtoken(entries[i].Member.DeclaringType);
                                unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                                unpackerIL.EmitAnyCall(SerializationExceptions.NewValueTypeCannotBeNull3Method);
                                unpackerIL.EmitThrow();
                            }
                            else
                            {
                                // nullable
                                unpackerIL.EmitAnyLdloca(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType()));
                                unpackerIL.EmitInitobj(entries[i].Member.GetMemberValueType());
                                unpackerIL.EmitAnyLdloc(result);
                                unpackerIL.EmitAnyLdloc(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType()));
                                Emittion.EmitStoreValue(unpackerIL, entries[i].Member);
                            }
                        }
                        else
                        {
                            // ref type
                            unpackerIL.EmitAnyLdloc(result);
                            unpackerIL.EmitLdnull();
                            Emittion.EmitStoreValue(unpackerIL, entries[i].Member);
                        }

                        break;
                    }

                    case NilImplication.Prohibit:
                    {
                        unpackerIL.EmitLdstr(entries[i].Contract.Name);
                        unpackerIL.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                        unpackerIL.EmitThrow();
                        break;
                    }
                    }
                }

                unpackerIL.MarkLabel(endIf0);
            }
        }
        }         // UnpackAndAddCollectionItem

#if FEATURE_TAP
        protected internal override async Task <T> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken)
        {
            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 asAsyncUnpackable = result as IAsyncUnpackable;

            if (asAsyncUnpackable != null)
            {
                await asAsyncUnpackable.UnpackFromMessageAsync(unpacker, cancellationToken).ConfigureAwait(false);

                return(( T )result);
            }

            var asUnpackable = result as IUnpackable;

            if (asUnpackable != null)
            {
                await Task.Run(() => asUnpackable.UnpackFromMessage(unpacker), cancellationToken).ConfigureAwait(false);

                return(( T )result);
            }

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

                for (int i = 0; i < itemsCount; i++)
                {
                    result = await this.UnpackMemberValueAsync(result, unpacker, itemsCount, unpacked, i, i, cancellationToken).ConfigureAwait(false);

                    unpacked++;
                }
            }
            else
            {
#if DEBUG
                Contract.Assert(unpacker.IsMapHeader, "unpacker.IsMapHeader");
#endif // DEBUG
                var itemsCount = UnpackHelpers.GetItemsCount(unpacker);

                for (int i = 0; i < itemsCount; i++)
                {
                    var name = await unpacker.ReadStringAsync(cancellationToken).ConfigureAwait(false);

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

                    if (name.Value == null)
                    {
                        // missing member, drain the value and discard it.
                        if (!unpacker.Read() && i < itemsCount - 1)
                        {
                            SerializationExceptions.ThrowMissingKey(i + 1, unpacker);
                        }
                        continue;
                    }

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

                    result = await this.UnpackMemberValueAsync(result, unpacker, itemsCount, unpacked, index, i, cancellationToken).ConfigureAwait(false);

                    unpacked++;
                }
            }

            if (this._constructorParameters == null)
            {
                return(( T )result);
            }
            else
            {
                return(ReflectionExtensions.CreateInstancePreservingExceptionType <T>(typeof(T), result as object[]));
            }
        }
Ejemplo n.º 26
0
        private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            /*
             *		var memberName = unpacker.Data.AsString();
             *		if( memberName == "A" )
             *		{
             *			if( !unpacker.Read() )
             *			{
             *				throw SerializationExceptions.NewUnexpectedStreamEndsException();
             *			}
             *
             *			isAFound = true;
             *		}
             *		:
             */

            var beginLoop = unpackerIL.DefineLabel("BEGIN_LOOP");
            var endLoop   = unpackerIL.DefineLabel("END_LOOP");

            unpackerIL.MarkLabel(beginLoop);
            var memberName = localHolder.MemberName;

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitAnyLdloca(memberName);
            unpackerIL.EmitAnyCall(Metadata._Unpacker.ReadString);
            unpackerIL.EmitBrfalse(endLoop);

            for (int i = 0; i < entries.Length; i++)
            {
                if (entries[i].Contract.Name == null)
                {
                    // skip undefined member
                    continue;
                }

                // TODO: binary comparison

                // Is it current member?
                unpackerIL.EmitAnyLdloc(memberName);
                unpackerIL.EmitLdstr(entries[i].Contract.Name);
                unpackerIL.EmitAnyCall(Metadata._String.op_Equality);
                var endIfCurrentMember = unpackerIL.DefineLabel("END_IF_MEMBER_" + i);
                unpackerIL.EmitBrfalse(endIfCurrentMember);

                // Deserialize value
                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                    // Ignore undefined member -- Nop.
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i].Member,
                        entries[i].Member.GetMemberValueType(),
                        entries[i].Contract.NilImplication,
                        localHolder
                        );
                }
                else
                {
                    Emittion.EmitDeserializeValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i],
                        localHolder
                        );
                }

                // TOOD: Record for missing check

                unpackerIL.EmitBr(beginLoop);
                unpackerIL.MarkLabel(endIfCurrentMember);
            }

            // Drain next value with unpacker.Read()
            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitCallvirt(Metadata._Unpacker.Read);
            unpackerIL.EmitPop();
            unpackerIL.EmitBr(beginLoop);
            unpackerIL.MarkLabel(endLoop);
        }
        protected internal override object UnpackFromCore(Unpacker unpacker)
        {
            if (!unpacker.IsArrayHeader)
            {
                throw SerializationExceptions.NewIsNotArrayHeader();
            }

            var instance = this._createInstanceWithCapacity == null?this._createInstance() : this._createInstanceWithCapacity(UnpackHelpers.GetItemsCount(unpacker));

            this.UnpackToCore(unpacker, instance);
            return(instance);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Emits the deserialize value.
        /// </summary>
        /// <param name="emitter">The emitter.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
        /// <param name="value">The value local variable which stores unpacked value.</param>
        /// <param name="targetType">The type of deserialzing type.</param>
        /// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param>
        /// <param name="memberName">The name of the member.</param>
        /// <param name="endOfDeserialization">The end of deserialization label for nil implication.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        private static void EmitDeserializeValueCore(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, SerializingMember?member, string memberName, Label endOfDeserialization, LocalVariableHolder localHolder)
        {
            var directUnpacking = Metadata._Unpacker.GetDirectReadMethod(value.LocalType);

            if (directUnpacking != null && (member == null || !UnpackHelpers.IsReadOnlyAppendableCollectionMember(member.Value.Member)))
            {
                var isSuccess = localHolder.IsDeserializationSucceeded;
                il.EmitLdc_I4_0();
                il.EmitAnyStloc(isSuccess);

                il.BeginExceptionBlock();
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitAnyLdloca(value);
                il.EmitAnyCall(directUnpacking);
                il.EmitAnyStloc(isSuccess);
                il.BeginCatchBlock(typeof(MessageTypeException));
                var ex = localHolder.GetCatchedException(typeof(MessageTypeException));
                il.EmitAnyStloc(ex);
                il.EmitTypeOf(targetType);
                il.EmitLdstr(memberName);
                il.EmitAnyLdloc(ex);
                il.EmitAnyCall(SerializationExceptions.NewFailedToDeserializeMemberMethod);
                il.EmitThrow();
                il.EndExceptionBlock();
                var endIf0 = il.DefineLabel("END_IF");
                il.EmitAnyLdloc(isSuccess);
                il.EmitBrtrue_S(endIf0);
                il.EmitAnyCall(SerializationExceptions.NewUnexpectedEndOfStreamMethod);
                il.EmitThrow();
                il.MarkLabel(endIf0);
                if (member != null)
                {
                    // If null, nil implication is NOT needed.
                    EmitNilImplicationForPrimitive(il, member.Value, value, endOfDeserialization);
                }
            }
            else
            {
                EmitGeneralRead(il, unpackerArgumentIndex);
                if (member != null)
                {
                    // If null, nil implication is NOT needed.
                    EmitNilImplication(
                        il,
                        unpackerArgumentIndex,
                        member.Value.Contract.Name,
                        member.Value.Contract.NilImplication,
                        endOfDeserialization,
                        localHolder
                        );
                }

                var thenIffCollection = il.DefineLabel("THEN_IF_COLLECTION");
                var endIfCollection   = il.DefineLabel("END_IF_COLLECTION");

                /*
                 *	if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
                 *	{
                 *		value = GET_SERIALIZER().UnpackFrom( unpacker );
                 *	}
                 *	else
                 *	{
                 *		using( var subtreeUnpacker = unpacker.ReadSubtree() )
                 *		{
                 *			value = GET_SERIALIZER().UnpackFrom( subtreeUnpacker );
                 *		}
                 *	}
                 */

                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.IsArrayHeader);
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.IsMapHeader);
                il.EmitOr();
                il.EmitBrtrue_S(thenIffCollection);
                EmitUnpackFrom(emitter, il, value, unpackerArgumentIndex);
                il.EmitBr_S(endIfCollection);
                var subtreeUnpacker = localHolder.SubtreeUnpacker;
                il.MarkLabel(thenIffCollection);
                EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker);
                EmitUnpackFrom(emitter, il, value, subtreeUnpacker);
                EmitUnpackerEndReadSubtree(il, subtreeUnpacker);
                il.MarkLabel(endIfCollection);
            }
        }
        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 !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE)
            case CollectionDetailedKind.GenericReadOnlyDictionary:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = true;
                break;
            }

            case CollectionDetailedKind.GenericReadOnlyList:
            case CollectionDetailedKind.GenericReadOnlyCollection:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = true;
                break;
            }
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE )
            default:
            {
                isUnpackFromRequired = false;
                isAddItemRequired    = false;
                break;
            }
            }             // switch
        }
Ejemplo n.º 30
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);
                }
            }
        }