1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- #if !NO_RUNTIME
- using System;
- using ProtoBuf.Meta;
- #if FEAT_IKVM
- using Type = IKVM.Reflection.Type;
- using IKVM.Reflection;
- #else
- using System.Reflection;
- #endif
- namespace ProtoBuf.Serializers
- {
- sealed class MemberSpecifiedDecorator : ProtoDecoratorBase
- {
- public override Type ExpectedType { get { return Tail.ExpectedType; } }
- public override bool RequiresOldValue { get { return Tail.RequiresOldValue; } }
- public override bool ReturnsValue { get { return Tail.ReturnsValue; } }
- private readonly MethodInfo getSpecified, setSpecified;
- public MemberSpecifiedDecorator(MethodInfo getSpecified, MethodInfo setSpecified, IProtoSerializer tail)
- : base(tail)
- {
- if (getSpecified == null && setSpecified == null) throw new InvalidOperationException();
- this.getSpecified = getSpecified;
- this.setSpecified = setSpecified;
- }
- #if !FEAT_IKVM
- public override void Write(object value, ProtoWriter dest)
- {
- if(getSpecified == null || (bool)getSpecified.Invoke(value, null))
- {
- Tail.Write(value, dest);
- }
- }
- public override object Read(object value, ProtoReader source)
- {
- object result = Tail.Read(value, source);
- if (setSpecified != null) setSpecified.Invoke(value, new object[] { true });
- return result;
- }
- #endif
- #if FEAT_COMPILER
- protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
- {
- if (getSpecified == null)
- {
- Tail.EmitWrite(ctx, valueFrom);
- return;
- }
- using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom))
- {
- ctx.LoadAddress(loc, ExpectedType);
- ctx.EmitCall(getSpecified);
- Compiler.CodeLabel done = ctx.DefineLabel();
- ctx.BranchIfFalse(done, false);
- Tail.EmitWrite(ctx, loc);
- ctx.MarkLabel(done);
- }
- }
- protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
- {
- if (setSpecified == null)
- {
- Tail.EmitRead(ctx, valueFrom);
- return;
- }
- using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom))
- {
- Tail.EmitRead(ctx, loc);
- ctx.LoadAddress(loc, ExpectedType);
- ctx.LoadValue(1); // true
- ctx.EmitCall(setSpecified);
- }
- }
- #endif
- }
- }
- #endif
|