public ListReflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits)
            : base(type, context, traits)
        {
            if (type.GetIsAbstract())
            {
                type = context.DefaultCollectionTypes.GetConcreteType(type) ?? type;
            }

            if (type.IsArray)
            {
                var elementType = type.GetElementType();
                this._createInstanceWithCapacity = length =>
                {
                    return(Array.CreateInstance(elementType, length));
                };
                this._createInstance = null;
            }
            else if (type.GetIsAbstract())
            {
                this._createInstance             = () => { throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(type); };
                this._createInstanceWithCapacity = null;
            }
            else
            {
                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]);
                    }
                }
            }
        }
Example #2
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 });
                    }
                };
            }
        }
Example #3
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);
            }
        }