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]); } } } }
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 }); } }; } }
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); } }