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