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; } } } }
/// <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); }
/// <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); }
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 } } }
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); } } }
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); } } }
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); } }
protected virtual void AddItem(object collection, object item) { throw SerializationExceptions.NewUnpackToIsNotSupported(this.TargetType, null); }
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[])); } }
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); } }