PushLimit() public method

Sets currentLimit to (current position) + byteLimit. This is called when descending into a length-delimited embedded message. The previous limit is returned.
public PushLimit ( int byteLimit ) : int
byteLimit int
return int
示例#1
0
        public void SkipRawBytesBug()
        {
            byte[]           rawBytes = new byte[] { 1, 2 };
            CodedInputStream input    = CodedInputStream.CreateInstance(rawBytes);

            int limit = input.PushLimit(1);

            input.SkipRawBytes(1);
            input.PopLimit(limit);
            Assert.AreEqual(2, input.ReadRawByte());
        }
示例#2
0
            /// <summary>
            /// Like <see cref="MergeFrom(CodedInputStream, ExtensionRegistry, IBuilder)" />
            /// but parses a single field.
            /// </summary>
            /// <param name="input">The input to read the field from</param>
            /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
            /// <param name="builder">Builder to merge field into, if it's a known field</param>
            /// <param name="tag">The tag, which should already have been read from the input</param>
            /// <returns>true unless the tag is an end-group tag</returns>
            internal bool MergeFieldFrom(CodedInputStream input,
                                         ExtensionRegistry extensionRegistry, IBuilder builder, uint tag)
            {
                MessageDescriptor type = builder.DescriptorForType;

                if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart)
                {
                    MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
                    return(true);
                }

                WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
                int fieldNumber = WireFormat.GetTagFieldNumber(tag);

                FieldDescriptor field;
                IMessage        defaultFieldInstance = null;

                if (type.IsExtensionNumber(fieldNumber))
                {
                    ExtensionInfo extension = extensionRegistry[type, fieldNumber];
                    if (extension == null)
                    {
                        field = null;
                    }
                    else
                    {
                        field = extension.Descriptor;
                        defaultFieldInstance = extension.DefaultInstance;
                    }
                }
                else
                {
                    field = type.FindFieldByNumber(fieldNumber);
                }

                // Unknown field or wrong wire type. Skip.
                if (field == null || wireType != WireFormat.GetWireType(field))
                {
                    return(MergeFieldFrom(tag, input));
                }

                if (field.IsPacked)
                {
                    int length = (int)input.ReadRawVarint32();
                    int limit  = input.PushLimit(length);
                    if (field.FieldType == FieldType.Enum)
                    {
                        while (!input.ReachedLimit)
                        {
                            int    rawValue = input.ReadEnum();
                            object value    = field.EnumType.FindValueByNumber(rawValue);
                            if (value == null)
                            {
                                // If the number isn't recognized as a valid value for this
                                // enum, drop it (don't even add it to unknownFields).
                                return(true);
                            }
                            builder.WeakAddRepeatedField(field, value);
                        }
                    }
                    else
                    {
                        while (!input.ReachedLimit)
                        {
                            Object value = input.ReadPrimitiveField(field.FieldType);
                            builder.WeakAddRepeatedField(field, value);
                        }
                    }
                    input.PopLimit(limit);
                }
                else
                {
                    object value;
                    switch (field.FieldType)
                    {
                    case FieldType.Group:
                    case FieldType.Message: {
                        IBuilder subBuilder;
                        if (defaultFieldInstance != null)
                        {
                            subBuilder = defaultFieldInstance.WeakCreateBuilderForType();
                        }
                        else
                        {
                            subBuilder = builder.CreateBuilderForField(field);
                        }
                        if (!field.IsRepeated)
                        {
                            subBuilder.WeakMergeFrom((IMessage)builder[field]);
                        }
                        if (field.FieldType == FieldType.Group)
                        {
                            input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
                        }
                        else
                        {
                            input.ReadMessage(subBuilder, extensionRegistry);
                        }
                        value = subBuilder.WeakBuild();
                        break;
                    }

                    case FieldType.Enum: {
                        int rawValue = input.ReadEnum();
                        value = field.EnumType.FindValueByNumber(rawValue);
                        // If the number isn't recognized as a valid value for this enum,
                        // drop it.
                        if (value == null)
                        {
                            MergeVarintField(fieldNumber, (ulong)rawValue);
                            return(true);
                        }
                        break;
                    }

                    default:
                        value = input.ReadPrimitiveField(field.FieldType);
                        break;
                    }
                    if (field.IsRepeated)
                    {
                        builder.WeakAddRepeatedField(field, value);
                    }
                    else
                    {
                        builder[field] = value;
                    }
                }
                return(true);
            }
            /// <summary>
            /// Like <see cref="MergeFrom(CodedInputStream, ExtensionRegistry, IBuilder)" />
            /// but parses a single field.
            /// </summary>
            /// <param name="input">The input to read the field from</param>
            /// <param name="extensionRegistry">Registry to use when an extension field is encountered</param>
            /// <param name="builder">Builder to merge field into, if it's a known field</param>
            /// <param name="tag">The tag, which should already have been read from the input</param>
            /// <returns>true unless the tag is an end-group tag</returns>
            internal bool MergeFieldFrom(CodedInputStream input, 
          ExtensionRegistry extensionRegistry, IBuilder builder, uint tag)
            {
                MessageDescriptor type = builder.DescriptorForType;
                if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart) {
                  MergeMessageSetExtensionFromCodedStream(input, extensionRegistry, builder);
                  return true;
                }

                WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
                int fieldNumber = WireFormat.GetTagFieldNumber(tag);

                FieldDescriptor field;
                IMessage defaultFieldInstance = null;

                if (type.IsExtensionNumber(fieldNumber)) {
                  ExtensionInfo extension = extensionRegistry[type, fieldNumber];
                  if (extension == null) {
                field = null;
                  } else {
                field = extension.Descriptor;
                defaultFieldInstance = extension.DefaultInstance;
                  }
                } else {
                  field = type.FindFieldByNumber(fieldNumber);
                }

                // Unknown field or wrong wire type. Skip.
                if (field == null || wireType != WireFormat.GetWireType(field)) {
                  return MergeFieldFrom(tag, input);
                }

                if (field.IsPacked) {
                  int length = (int)input.ReadRawVarint32();
                  int limit = input.PushLimit(length);
                  if (field.FieldType == FieldType.Enum) {
                while (!input.ReachedLimit) {
                  int rawValue = input.ReadEnum();
                  object value = field.EnumType.FindValueByNumber(rawValue);
                  if (value == null) {
                // If the number isn't recognized as a valid value for this
                // enum, drop it (don't even add it to unknownFields).
                return true;
                  }
                  builder.WeakAddRepeatedField(field, value);
                }
                  } else {
                while (!input.ReachedLimit) {
                  Object value = input.ReadPrimitiveField(field.FieldType);
                  builder.WeakAddRepeatedField(field, value);
                }
                  }
                  input.PopLimit(limit);
                } else {
                  object value;
                  switch (field.FieldType) {
                case FieldType.Group:
                case FieldType.Message: {
                IBuilder subBuilder;
                if (defaultFieldInstance != null) {
                  subBuilder = defaultFieldInstance.WeakCreateBuilderForType();
                } else {
                  subBuilder = builder.CreateBuilderForField(field);
                }
                if (!field.IsRepeated) {
                  subBuilder.WeakMergeFrom((IMessage)builder[field]);
                }
                if (field.FieldType == FieldType.Group) {
                  input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);
                } else {
                  input.ReadMessage(subBuilder, extensionRegistry);
                }
                value = subBuilder.WeakBuild();
                break;
                  }
                case FieldType.Enum: {
                int rawValue = input.ReadEnum();
                value = field.EnumType.FindValueByNumber(rawValue);
                // If the number isn't recognized as a valid value for this enum,
                // drop it.
                if (value == null) {
                  MergeVarintField(fieldNumber, (ulong)rawValue);
                  return true;
                }
                break;
                  }
                default:
                  value = input.ReadPrimitiveField(field.FieldType);
                  break;
                  }
                  if (field.IsRepeated) {
                builder.WeakAddRepeatedField(field, value);
                  } else {
                builder[field] = value;
                  }
                }
                return true;
            }
        public void TestCodedInputOutputPosition()
        {
            byte[] content = new byte[110];
            for (int i = 0; i < content.Length; i++)
            {
                content[i] = (byte)i;
            }

            byte[] child = new byte[120];
            {
                MemoryStream      ms   = new MemoryStream(child);
                CodedOutputStream cout = CodedOutputStream.CreateInstance(ms, 20);
                // Field 11: numeric value: 500
                cout.WriteTag(11, WireFormat.WireType.Varint);
                Assert.AreEqual(1, cout.Position);
                cout.WriteInt32NoTag(500);
                Assert.AreEqual(3, cout.Position);
                //Field 12: length delimited 120 bytes
                cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
                Assert.AreEqual(4, cout.Position);
                cout.WriteBytesNoTag(ByteString.CopyFrom(content));
                Assert.AreEqual(115, cout.Position);
                // Field 13: fixed numeric value: 501
                cout.WriteTag(13, WireFormat.WireType.Fixed32);
                Assert.AreEqual(116, cout.Position);
                cout.WriteSFixed32NoTag(501);
                Assert.AreEqual(120, cout.Position);
                cout.Flush();
            }

            byte[] bytes = new byte[130];
            {
                CodedOutputStream cout = CodedOutputStream.CreateInstance(bytes);
                // Field 1: numeric value: 500
                cout.WriteTag(1, WireFormat.WireType.Varint);
                Assert.AreEqual(1, cout.Position);
                cout.WriteInt32NoTag(500);
                Assert.AreEqual(3, cout.Position);
                //Field 2: length delimited 120 bytes
                cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
                Assert.AreEqual(4, cout.Position);
                cout.WriteBytesNoTag(ByteString.CopyFrom(child));
                Assert.AreEqual(125, cout.Position);
                // Field 3: fixed numeric value: 500
                cout.WriteTag(3, WireFormat.WireType.Fixed32);
                Assert.AreEqual(126, cout.Position);
                cout.WriteSFixed32NoTag(501);
                Assert.AreEqual(130, cout.Position);
                cout.Flush();
            }
            //Now test Input stream:
            {
                CodedInputStream cin = CodedInputStream.CreateInstance(new MemoryStream(bytes), new byte[50]);
                uint             tag;
                int    intValue = 0;
                string ignore;
                Assert.AreEqual(0, cin.Position);
                // Field 1:
                Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 1);
                Assert.AreEqual(1, cin.Position);
                Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500);
                Assert.AreEqual(3, cin.Position);
                //Field 2:
                Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 2);
                Assert.AreEqual(4, cin.Position);
                uint childlen = cin.ReadRawVarint32();
                Assert.AreEqual(120u, childlen);
                Assert.AreEqual(5, cin.Position);
                int oldlimit = cin.PushLimit((int)childlen);
                Assert.AreEqual(5, cin.Position);
                // Now we are reading child message
                {
                    // Field 11: numeric value: 500
                    Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 11);
                    Assert.AreEqual(6, cin.Position);
                    Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500);
                    Assert.AreEqual(8, cin.Position);
                    //Field 12: length delimited 120 bytes
                    Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 12);
                    Assert.AreEqual(9, cin.Position);
                    ByteString bstr = null;
                    Assert.IsTrue(cin.ReadBytes(ref bstr) && bstr.Length == 110 && bstr.ToByteArray()[109] == 109);
                    Assert.AreEqual(120, cin.Position);
                    // Field 13: fixed numeric value: 501
                    Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 13);
                    // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
                    Assert.AreEqual(121, cin.Position);
                    Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501);
                    Assert.AreEqual(125, cin.Position);
                    Assert.IsTrue(cin.IsAtEnd);
                }
                cin.PopLimit(oldlimit);
                Assert.AreEqual(125, cin.Position);
                // Field 3: fixed numeric value: 501
                Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 3);
                Assert.AreEqual(126, cin.Position);
                Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501);
                Assert.AreEqual(130, cin.Position);
                Assert.IsTrue(cin.IsAtEnd);
            }
        }
        protected override bool ParseUnknownField(CodedInputStream input,
                                                  ExtensionRegistry extensionRegistry, uint tag)
        {
            FieldSet extensions = MessageBeingBuilt.Extensions;

            WireFormat.WireType wireType = WireFormat.GetTagWireType(tag);
            int fieldNumber = WireFormat.GetTagFieldNumber(tag);
            IGeneratedExtensionLite extension = extensionRegistry[DefaultInstanceForType, fieldNumber];

            bool unknown = false;
            bool packed  = false;

            if (extension == null)
            {
                unknown = true; // Unknown field.
            }
            else if (wireType == FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, false /* isPacked */))
            {
                packed = false; // Normal, unpacked value.
            }
            else if (extension.Descriptor.IsRepeated &&
                     //?? just returns true ?? extension.Descriptor.type.isPackable() &&
                     wireType == FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, true /* isPacked */))
            {
                packed = true; // Packed value.
            }
            else
            {
                unknown = true; // Wrong wire type.
            }

            if (unknown) // Unknown field or wrong wire type.  Skip.
            {
                return(input.SkipField(tag));
            }

            if (packed)
            {
                int length = (int)Math.Min(int.MaxValue, input.ReadRawVarint32());
                int limit  = input.PushLimit(length);
                if (extension.Descriptor.FieldType == FieldType.Enum)
                {
                    while (!input.ReachedLimit)
                    {
                        int    rawValue = input.ReadEnum();
                        Object value    =
                            extension.Descriptor.EnumType.FindValueByNumber(rawValue);
                        if (value == null)
                        {
                            // If the number isn't recognized as a valid value for this
                            // enum, drop it (don't even add it to unknownFields).
                            return(true);
                        }
                        extensions.AddRepeatedField(extension.Descriptor, value);
                    }
                }
                else
                {
                    while (!input.ReachedLimit)
                    {
                        Object value = input.ReadPrimitiveField(extension.Descriptor.FieldType);
                        extensions.AddRepeatedField(extension.Descriptor, value);
                    }
                }
                input.PopLimit(limit);
            }
            else
            {
                Object value;
                switch (extension.Descriptor.MappedType)
                {
                case MappedType.Message: {
                    IBuilderLite subBuilder = null;
                    if (!extension.Descriptor.IsRepeated)
                    {
                        IMessageLite existingValue = extensions[extension.Descriptor] as IMessageLite;
                        if (existingValue != null)
                        {
                            subBuilder = existingValue.WeakToBuilder();
                        }
                    }
                    if (subBuilder == null)
                    {
                        subBuilder = extension.MessageDefaultInstance.WeakCreateBuilderForType();
                    }
                    if (extension.Descriptor.FieldType == FieldType.Group)
                    {
                        input.ReadGroup(extension.Number, subBuilder, extensionRegistry);
                    }
                    else
                    {
                        input.ReadMessage(subBuilder, extensionRegistry);
                    }
                    value = subBuilder.WeakBuild();
                    break;
                }

                case MappedType.Enum:
                    int rawValue = input.ReadEnum();
                    value = extension.Descriptor.EnumType.FindValueByNumber(rawValue);
                    // If the number isn't recognized as a valid value for this enum,
                    // drop it.
                    if (value == null)
                    {
                        return(true);
                    }
                    break;

                default:
                    value = input.ReadPrimitiveField(extension.Descriptor.FieldType);
                    break;
                }

                if (extension.Descriptor.IsRepeated)
                {
                    extensions.AddRepeatedField(extension.Descriptor, value);
                }
                else
                {
                    extensions[extension.Descriptor] = value;
                }
            }

            return(true);
        }