Пример #1
0
        private void SkipGroup()
        {
            var startGroupTag = _lastTag;

            while (true)
            {
                var tag = ReadTag();
                if (tag == 0U)
                {
                    throw OutOfInputException();
                }
                if (WireFormat.GetWireType(tag) != WireType.EndGroup)
                {
                    SkipField();
                    continue;
                }
                var startGroupFieldNumber = WireFormat.GetFieldNumber(startGroupTag);
                var endGroupFieldNumber   = WireFormat.GetFieldNumber(tag);
                if (startGroupFieldNumber == endGroupFieldNumber)
                {
                    return;
                }

                var message =
                    $"Mismatched end-group tag. Started with field {startGroupFieldNumber}; ended with field {endGroupFieldNumber}";
                throw new InvalidDataException(message);
            }
        }
Пример #2
0
 internal static bool IsPackedRepeatedField(uint tag)
 {
     if (TypeCanBePacked)
     {
         return(WireFormat.GetWireType(tag) == WireType.LengthDelimited);
     }
     return(false);
 }
Пример #3
0
        private static void AssertTagOk(int field, WireType wireType)
        {
            var tag = WireFormat.MakeTag(field, wireType);

            Assert.Equal(field, WireFormat.GetFieldNumber(tag));
            Assert.Equal(wireType, WireFormat.GetWireType(tag));
            Assert.Equal(wireType, (WireType)(tag & 7));
            Assert.Equal(field, (int)(tag >> 3));
        }
Пример #4
0
        public void SkipField()
        {
            if (_lastTag == 0U)
            {
                if (End)
                {
                    throw new InvalidOperationException("SkipField cannot be called at the end of a stream");
                }
                throw new InvalidOperationException("SkipField cannot be called when tag have not been read");
            }
            switch (WireFormat.GetWireType(_lastTag))
            {
            case WireType.Varint:
                SkipVarInt();
                break;

            case WireType.Fixed32:
                SkipBytes(4);
                break;

            case WireType.Fixed64:
                SkipBytes(8);
                break;

            case WireType.LengthDelimited:
                SkipBytes(ReadByteSize());
                break;

            case WireType.StartGroup:
                SkipGroup();
                break;

            case WireType.EndGroup:
                throw new InvalidDataException(
                          "SkipField called on an end-group tag. Most likely start group was missing.");
            }
        }
        private void GenerateBuilderParsingMethods(TextGenerator writer)
        {
            List <FieldDescriptor> sortedFields = new List <FieldDescriptor>(Descriptor.Fields);

            sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));

            writer.WriteLine("public override Builder MergeFrom(pb::ICodedInputStream input) {");
            writer.WriteLine("  return MergeFrom(input, pb::ExtensionRegistry.Empty);");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine(
                "public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
            writer.Indent();
            writer.WriteLine("PrepareBuilder();");
            if (!UseLiteRuntime)
            {
                writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
            }
            writer.WriteLine("uint tag;");
            writer.WriteLine("string field_name;");
            writer.WriteLine("while (input.ReadTag(out tag, out field_name)) {");
            writer.Indent();
            writer.WriteLine("if(tag == 0 && field_name != null) {");
            writer.Indent();
            //if you change from StringComparer.Ordinal, the array sort in FieldNames { get; } must also change
            writer.WriteLine(
                "int field_ordinal = global::System.Array.BinarySearch(_{0}FieldNames, field_name, global::System.StringComparer.Ordinal);",
                NameHelpers.UnderscoresToCamelCase(ClassName));
            writer.WriteLine("if(field_ordinal >= 0)");
            writer.WriteLine("  tag = _{0}FieldTags[field_ordinal];", NameHelpers.UnderscoresToCamelCase(ClassName));
            writer.WriteLine("else {");
            if (!UseLiteRuntime)
            {
                writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
                writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
                writer.WriteLine("  }");
            }
            writer.WriteLine("  ParseUnknownField(input, {0}extensionRegistry, tag, field_name);",
                             UseLiteRuntime ? "" : "unknownFields, ");
            writer.WriteLine("  continue;");
            writer.WriteLine("}");
            writer.Outdent();
            writer.WriteLine("}");

            writer.WriteLine("switch (tag) {");
            writer.Indent();
            writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
            writer.WriteLine("  throw pb::InvalidProtocolBufferException.InvalidTag();");
            writer.WriteLine("}");
            writer.WriteLine("default: {");
            writer.WriteLine("  if (pb::WireFormat.IsEndGroupTag(tag)) {");
            if (!UseLiteRuntime)
            {
                writer.WriteLine("    if (unknownFields != null) {");
                writer.WriteLine("      this.UnknownFields = unknownFields.Build();");
                writer.WriteLine("    }");
            }
            writer.WriteLine("    return this;"); // it's an endgroup tag
            writer.WriteLine("  }");
            if (!UseLiteRuntime)
            {
                writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
                writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
                writer.WriteLine("  }");
            }
            writer.WriteLine("  ParseUnknownField(input, {0}extensionRegistry, tag, field_name);",
                             UseLiteRuntime ? "" : "unknownFields, ");
            writer.WriteLine("  break;");
            writer.WriteLine("}");
            foreach (FieldDescriptor field in sortedFields)
            {
                WireFormat.WireType wt = WireFormat.GetWireType(field.FieldType);
                uint tag = WireFormat.MakeTag(field.FieldNumber, wt);

                if (field.IsRepeated &&
                    (wt == WireFormat.WireType.Varint || wt == WireFormat.WireType.Fixed32 ||
                     wt == WireFormat.WireType.Fixed64))
                {
                    writer.WriteLine("case {0}:",
                                     WireFormat.MakeTag(field.FieldNumber, WireFormat.WireType.LengthDelimited));
                }

                writer.WriteLine("case {0}: {{", tag);
                writer.Indent();
                CreateFieldGenerator(field).GenerateParsingCode(writer);
                writer.WriteLine("break;");
                writer.Outdent();
                writer.WriteLine("}");
            }
            writer.Outdent();
            writer.WriteLine("}");
            writer.Outdent();
            writer.WriteLine("}");
            writer.WriteLine();
            if (!UseLiteRuntime)
            {
                writer.WriteLine("if (unknownFields != null) {");
                writer.WriteLine("  this.UnknownFields = unknownFields.Build();");
                writer.WriteLine("}");
            }
            writer.WriteLine("return this;");
            writer.Outdent();
            writer.WriteLine("}");
            writer.WriteLine();
        }