コード例 #1
0
        internal static void EmitReadList(ProtoBuf.Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd)
        {
            using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof(int)))
            {
                Compiler.CodeLabel readPacked = packedWireType == WireType.None ? new Compiler.CodeLabel() : ctx.DefineLabel();
                if (packedWireType != WireType.None)
                {
                    ctx.LoadReader(false);
                    ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType"));
                    ctx.LoadValue((int)WireType.String);
                    ctx.BranchIfEqual(readPacked, false);
                }
                ctx.LoadReader(false);
                ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber"));
                ctx.StoreValue(fieldNumber);

                Compiler.CodeLabel @continue = ctx.DefineLabel();
                ctx.MarkLabel(@continue);

                EmitReadAndAddItem(ctx, list, tail, add, castListForAdd);

                ctx.LoadReader(true);
                ctx.LoadValue(fieldNumber);
                ctx.EmitCall(typeof(ProtoReader).GetMethod("TryReadFieldHeader",
                                                           new[] { ProtoReader.State.ByRefStateType, typeof(int) }));
                ctx.BranchIfTrue(@continue, false);

                if (packedWireType != WireType.None)
                {
                    Compiler.CodeLabel allDone = ctx.DefineLabel();
                    ctx.Branch(allDone, false);
                    ctx.MarkLabel(readPacked);

                    ctx.LoadReader(true);
                    ctx.EmitCall(typeof(ProtoReader).GetMethod("StartSubItem",
                                                               ProtoReader.State.ReaderStateTypeArray));

                    Compiler.CodeLabel testForData = ctx.DefineLabel(), noMoreData = ctx.DefineLabel();
                    ctx.MarkLabel(testForData);
                    ctx.LoadValue((int)packedWireType);
                    ctx.LoadReader(false);
                    ctx.EmitCall(typeof(ProtoReader).GetMethod("HasSubValue"));
                    ctx.BranchIfFalse(noMoreData, false);

                    EmitReadAndAddItem(ctx, list, tail, add, castListForAdd);
                    ctx.Branch(testForData, false);

                    ctx.MarkLabel(noMoreData);
                    ctx.LoadReader(true);
                    ctx.EmitCall(typeof(ProtoReader).GetMethod("EndSubItem",
                                                               new[] { typeof(SubItemToken), typeof(ProtoReader), ProtoReader.State.ByRefStateType }));
                    ctx.MarkLabel(allDone);
                }
            }
        }
コード例 #2
0
 protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom)
 {
     if (strict || NeedsHint)
     {
         ctx.LoadReader(strict);
         ctx.LoadValue((int)wireType);
         if (strict)
         {
             ctx.EmitCall(typeof(ProtoReader).GetMethod("Assert",
                                                        new[] { ProtoReader.State.ByRefStateType, typeof(WireType) }));
         }
         else
         {
             ctx.EmitCall(typeof(ProtoReader).GetMethod("Hint"));
         }
     }
     Tail.EmitRead(ctx, valueFrom);
 }