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