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