public static bool IsReadOnlyAppendableCollectionMember( MemberInfo memberInfo )
		{
			Contract.Requires( memberInfo != null );

			if ( memberInfo.CanSetValue() )
			{
				// Not read only
				return false;
			}

			Type memberValueType = memberInfo.GetMemberValueType();
			if ( memberValueType.IsArray )
			{
				// Not appendable
				return false;
			}

			CollectionTraits traits = memberValueType.GetCollectionTraits();
			return traits.CollectionType != CollectionKind.NotCollection && traits.AddMethod != null;
		}
Example #2
0
		public static void EmitDeserializeValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder result, MemberInfo member, string memberName, NilImplication nilImplication, Action<TracingILGenerator, int> customUnpackerReading )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( result != null );
			Contract.Requires( member != null );

			if ( customUnpackerReading != null )
			{
				customUnpackerReading( il, unpackerArgumentIndex );
			}

			var endOfDeserialization = il.DefineLabel( "END_OF_DESERIALIZATION" );
			if ( memberName != null )
			{
				EmitNilImplication( il, unpackerArgumentIndex, memberName, nilImplication, endOfDeserialization );
			}

			/*
			 * 
			 * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
			 * {
			 *		valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 * }
			 * else
			 * {
			 *		using( var subtreeUnpacker = unpacker.ReadSubtree )
			 *		{
			 *			valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 *		}
			 * }
			 * 
			 * isValueNUnpacked = true;
			 * END_OF_DESERIALIZATION:
			 */

			var then = il.DefineLabel( "THEN" );
			var endIf = il.DefineLabel( "END_IF" );
			var value = il.DeclareLocal( member.GetMemberValueType(), "value" );
			var serializerGetter = emitter.RegisterSerializer( value.LocalType );

			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.IsArrayHeader );
			il.EmitBrtrue_S( then );
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.IsMapHeader );
			il.EmitBrtrue_S( then );
			// else
			serializerGetter( il, 0 );
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitAnyCall( typeof( MessagePackSerializer<> ).MakeGenericType( value.LocalType ).GetMethod( "UnpackFrom" ) );
			il.EmitAnyStloc( value );
			il.EmitBr_S( endIf );
			// then
			var subtreeUnpacker = il.DeclareLocal( typeof( Unpacker ), "subtreeUnpacker" );
			il.MarkLabel( then );
			EmitUnpackerBeginReadSubtree( il, unpackerArgumentIndex, subtreeUnpacker );
			serializerGetter( il, 0 );
			il.EmitAnyLdloc( subtreeUnpacker );
			il.EmitAnyCall( typeof( MessagePackSerializer<> ).MakeGenericType( value.LocalType ).GetMethod( "UnpackFrom" ) );
			il.EmitAnyStloc( value );
			EmitUnpackerEndReadSubtree( il, subtreeUnpacker );
			il.MarkLabel( endIf );

			if ( result.LocalType.IsValueType )
			{
				il.EmitAnyLdloca( result );
			}
			else
			{
				il.EmitAnyLdloc( result );
			}

			il.EmitAnyLdloc( value );
			Emittion.EmitStoreValue( il, member );

			il.MarkLabel( endOfDeserialization );
		}