From 26de9f81c5dffeafe751b9c8e3c5a5f1f5985f11 Mon Sep 17 00:00:00 2001 From: Randy Stauner Date: Thu, 2 Jan 2025 16:41:47 -0700 Subject: [PATCH] Include unknown fields from decoding into output when re-encoding When a message is decoded that has fields the current module doesn't utilize, just append them to the end of the message when re-encoding a message from this instance. The conformance suite tests for this. --- lib/protoboeuf/codegen.rb | 50 +- lib/protoboeuf/protobuf/any.rb | 44 +- lib/protoboeuf/protobuf/boolvalue.rb | 44 +- lib/protoboeuf/protobuf/bytesvalue.rb | 44 +- lib/protoboeuf/protobuf/descriptor.rb | 1452 ++++++++++++++++++++---- lib/protoboeuf/protobuf/doublevalue.rb | 44 +- lib/protoboeuf/protobuf/duration.rb | 44 +- lib/protoboeuf/protobuf/field_mask.rb | 44 +- lib/protoboeuf/protobuf/floatvalue.rb | 44 +- lib/protoboeuf/protobuf/int32value.rb | 44 +- lib/protoboeuf/protobuf/int64value.rb | 44 +- lib/protoboeuf/protobuf/stringvalue.rb | 44 +- lib/protoboeuf/protobuf/struct.rb | 132 ++- lib/protoboeuf/protobuf/timestamp.rb | 44 +- lib/protoboeuf/protobuf/uint32value.rb | 44 +- lib/protoboeuf/protobuf/uint64value.rb | 44 +- test/codegen_compatibility_test.rb | 2 - test/codegen_test.rb | 23 +- test/fixtures/typed_test.correct.rb | 44 +- 19 files changed, 1943 insertions(+), 332 deletions(-) diff --git a/lib/protoboeuf/codegen.rb b/lib/protoboeuf/codegen.rb index 978b0c1..f1155b9 100644 --- a/lib/protoboeuf/codegen.rb +++ b/lib/protoboeuf/codegen.rb @@ -173,7 +173,7 @@ def encode type_signature(params: { buff: "String" }, returns: "String", newline: true) + "def _encode(buff)\n" + fields.map { |field| encode_subtype(field) }.compact.join("\n") + - "\nbuff\n end\n\n" + "buff << @_unknown_fields if @_unknown_fields\nbuff\n end\n\n" end def encode_subtype(field, value_expr = iv_name(field), tagged = true) @@ -469,18 +469,24 @@ def encode_int64(field, value_expr, tagged) val = #{value_expr} if val != 0 #{encode_tag_and_length(field, tagged)} - while val != 0 - byte = val & 0x7F + #{encode_varint} + end + RUBY + end - val >>= 7 - # This drops the top bits, - # Otherwise, with a signed right shift, - # we get infinity one bits at the top - val &= (1 << 57) - 1 + def encode_varint(dest = "buff") + <<~RUBY + while val != 0 + byte = val & 0x7F - byte |= 0x80 if val != 0 - buff << byte - end + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + #{dest} << byte end RUBY end @@ -1103,27 +1109,41 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + <%= encode_varint("unknown_bytes") %> + case wire_type when <%= VARINT %> i = 0 while true newbyte = buff.getbyte(index) index += 1 - if newbyte.nil? || newbyte < 0x80 - break - end + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when <%= I64 %> + unknown_bytes << buff.byteslice(index, 8) index += 8 when <%= LEN %> - <%= pull_bytes("", "") %> + value = <%= pull_varint %> + + val = value + <%= encode_varint("unknown_bytes") %> + + unknown_bytes << buff.byteslice(index, value) + index += value when <%= I32 %> + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type \#{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len <%= pull_tag %> end diff --git a/lib/protoboeuf/protobuf/any.rb b/lib/protoboeuf/protobuf/any.rb index e907fc9..5e22d7d 100644 --- a/lib/protoboeuf/protobuf/any.rb +++ b/lib/protoboeuf/protobuf/any.rb @@ -99,20 +99,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -168,15 +186,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -514,7 +546,7 @@ def _encode(buff) buff.concat(val.b) end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/boolvalue.rb b/lib/protoboeuf/protobuf/boolvalue.rb index 3bf0157..a55de76 100644 --- a/lib/protoboeuf/protobuf/boolvalue.rb +++ b/lib/protoboeuf/protobuf/boolvalue.rb @@ -90,20 +90,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -159,15 +177,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -310,7 +342,7 @@ def _encode(buff) else raise "bool values should be true or false" end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/bytesvalue.rb b/lib/protoboeuf/protobuf/bytesvalue.rb index c8dd025..81495dc 100644 --- a/lib/protoboeuf/protobuf/bytesvalue.rb +++ b/lib/protoboeuf/protobuf/bytesvalue.rb @@ -90,20 +90,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -159,15 +177,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -369,7 +401,7 @@ def _encode(buff) buff.concat(val.b) end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/descriptor.rb b/lib/protoboeuf/protobuf/descriptor.rb index 884bfe5..24b97c5 100644 --- a/lib/protoboeuf/protobuf/descriptor.rb +++ b/lib/protoboeuf/protobuf/descriptor.rb @@ -161,20 +161,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -230,15 +248,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -493,7 +525,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -804,20 +836,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -873,15 +923,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -3279,7 +3343,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -3471,20 +3535,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -3540,15 +3622,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -4089,7 +4185,7 @@ def _encode(buff) buff end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -4245,20 +4341,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -4314,15 +4428,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -4686,7 +4814,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -4896,20 +5024,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -4965,15 +5111,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -6826,7 +6986,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -7049,20 +7209,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -7118,15 +7296,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -7771,7 +7963,7 @@ def _encode(buff) else raise "bool values should be true or false" end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -7950,20 +8142,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -8019,15 +8229,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -8799,7 +9023,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -9262,20 +9486,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -9331,15 +9573,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -10941,7 +11197,7 @@ def _encode(buff) else raise "bool values should be true or false" end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -11085,20 +11341,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -11154,15 +11428,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -11541,7 +11829,7 @@ def _encode(buff) buff end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -11703,20 +11991,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -11772,15 +12078,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -12144,7 +12464,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -12304,20 +12624,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -12373,15 +12711,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -13289,7 +13641,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -13455,20 +13807,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -13524,15 +13894,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -14060,7 +14444,7 @@ def _encode(buff) buff end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -14205,20 +14589,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -14274,15 +14676,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -14850,7 +15266,7 @@ def _encode(buff) buff end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -15069,20 +15485,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -15138,15 +15572,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -15955,7 +16403,7 @@ def _encode(buff) else raise "bool values should be true or false" end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -16495,20 +16943,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -16564,15 +17030,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -19163,7 +19643,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -19413,20 +19893,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -19482,15 +19980,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -20313,7 +20825,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -20463,20 +20975,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -20532,15 +21062,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -20892,7 +21436,7 @@ def _encode(buff) buff << (val.ascii_only? ? val : val.b) end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -21068,20 +21612,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -21137,15 +21699,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -21795,7 +22371,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -22276,20 +22852,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -22345,15 +22939,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -24234,7 +24842,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -24371,20 +24979,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -24440,15 +25066,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -24881,7 +25521,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -25070,20 +25710,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -25139,15 +25797,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -25814,7 +26486,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -26007,20 +26679,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -26076,15 +26766,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -26850,7 +27554,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -26997,20 +27701,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -27066,15 +27788,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -27587,7 +28323,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -27785,20 +28521,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -27854,15 +28608,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -28525,7 +29293,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -28641,20 +29409,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -28710,15 +29496,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -28997,7 +29797,7 @@ def _encode(buff) else raise "bool values should be true or false" end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -29237,20 +30037,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -29306,15 +30124,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -30332,7 +31164,7 @@ def _encode(buff) buff << (val.ascii_only? ? val : val.b) end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -30711,20 +31543,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -30780,15 +31630,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -31748,7 +32612,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -31916,20 +32780,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -31985,15 +32867,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -32562,7 +33458,7 @@ def _encode(buff) buff end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -32690,20 +33586,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -32759,15 +33673,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -33320,7 +34248,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -33523,20 +34451,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -33592,15 +34538,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -34603,7 +35563,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -34697,20 +35657,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -34766,15 +35744,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -35029,7 +36021,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -35288,20 +36280,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -35357,15 +36367,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -36271,7 +37295,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -36363,20 +37387,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -36432,15 +37474,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -36695,7 +37751,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/doublevalue.rb b/lib/protoboeuf/protobuf/doublevalue.rb index 9a71f23..d5fe24e 100644 --- a/lib/protoboeuf/protobuf/doublevalue.rb +++ b/lib/protoboeuf/protobuf/doublevalue.rb @@ -90,20 +90,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -159,15 +177,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -304,7 +336,7 @@ def _encode(buff) [val].pack("E", buffer: buff) end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/duration.rb b/lib/protoboeuf/protobuf/duration.rb index 35c7748..d645e6e 100644 --- a/lib/protoboeuf/protobuf/duration.rb +++ b/lib/protoboeuf/protobuf/duration.rb @@ -118,20 +118,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -187,15 +205,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -557,7 +589,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/field_mask.rb b/lib/protoboeuf/protobuf/field_mask.rb index 294f235..c1d1f65 100644 --- a/lib/protoboeuf/protobuf/field_mask.rb +++ b/lib/protoboeuf/protobuf/field_mask.rb @@ -90,20 +90,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -159,15 +177,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -384,7 +416,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/floatvalue.rb b/lib/protoboeuf/protobuf/floatvalue.rb index d6e604e..43c1173 100644 --- a/lib/protoboeuf/protobuf/floatvalue.rb +++ b/lib/protoboeuf/protobuf/floatvalue.rb @@ -90,20 +90,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -159,15 +177,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -304,7 +336,7 @@ def _encode(buff) [val].pack("e", buffer: buff) end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/int32value.rb b/lib/protoboeuf/protobuf/int32value.rb index b0f4ef6..c6b5d9c 100644 --- a/lib/protoboeuf/protobuf/int32value.rb +++ b/lib/protoboeuf/protobuf/int32value.rb @@ -99,20 +99,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -168,15 +186,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -390,7 +422,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/int64value.rb b/lib/protoboeuf/protobuf/int64value.rb index eccb77b..df4e1e0 100644 --- a/lib/protoboeuf/protobuf/int64value.rb +++ b/lib/protoboeuf/protobuf/int64value.rb @@ -100,20 +100,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -169,15 +187,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -391,7 +423,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/stringvalue.rb b/lib/protoboeuf/protobuf/stringvalue.rb index bbf4d28..2a55130 100644 --- a/lib/protoboeuf/protobuf/stringvalue.rb +++ b/lib/protoboeuf/protobuf/stringvalue.rb @@ -90,20 +90,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -159,15 +177,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -369,7 +401,7 @@ def _encode(buff) buff << (val.ascii_only? ? val : val.b) end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/struct.rb b/lib/protoboeuf/protobuf/struct.rb index e778189..e4c496d 100644 --- a/lib/protoboeuf/protobuf/struct.rb +++ b/lib/protoboeuf/protobuf/struct.rb @@ -102,20 +102,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -171,15 +189,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end - ## END PULL_BYTES + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -580,7 +612,7 @@ def _encode(buff) old_buff.concat(new_buffer) end end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -772,20 +804,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -841,15 +891,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -1704,7 +1768,7 @@ def _encode(buff) buff end - + buff << @_unknown_fields if @_unknown_fields buff end @@ -1800,20 +1864,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -1869,15 +1951,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 - ## END PULL_BYTES + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -2132,7 +2228,7 @@ def _encode(buff) end end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/timestamp.rb b/lib/protoboeuf/protobuf/timestamp.rb index 9dbaaae..3ffb4a6 100644 --- a/lib/protoboeuf/protobuf/timestamp.rb +++ b/lib/protoboeuf/protobuf/timestamp.rb @@ -118,20 +118,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -187,15 +205,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -557,7 +589,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/uint32value.rb b/lib/protoboeuf/protobuf/uint32value.rb index 383897c..1bc5c9c 100644 --- a/lib/protoboeuf/protobuf/uint32value.rb +++ b/lib/protoboeuf/protobuf/uint32value.rb @@ -99,20 +99,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -168,15 +186,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -373,7 +405,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/lib/protoboeuf/protobuf/uint64value.rb b/lib/protoboeuf/protobuf/uint64value.rb index 1496a7c..98aec17 100644 --- a/lib/protoboeuf/protobuf/uint64value.rb +++ b/lib/protoboeuf/protobuf/uint64value.rb @@ -99,20 +99,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -168,15 +186,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -373,7 +405,7 @@ def _encode(buff) buff << byte end end - + buff << @_unknown_fields if @_unknown_fields buff end diff --git a/test/codegen_compatibility_test.rb b/test/codegen_compatibility_test.rb index 120bc8d..4ae9041 100644 --- a/test/codegen_compatibility_test.rb +++ b/test/codegen_compatibility_test.rb @@ -57,8 +57,6 @@ def test_bounds end def test_unknown_fields - skip("FIXME: our to_proto doesn't currently preserve unknown fields") - our_m1, their_m1 = codegen_string(<<~EOPROTO) syntax = "proto3"; message M1 { diff --git a/test/codegen_test.rb b/test/codegen_test.rb index fd06908..964e1ab 100644 --- a/test/codegen_test.rb +++ b/test/codegen_test.rb @@ -542,7 +542,7 @@ def test_generate_types # The goal of this test is to ensure that we generate valid sorbet signatures. # - # This tests will break whenever any implementation of field encoding/deconding etc changes. + # This tests will break whenever any implementation of field encoding/decoding etc changes. # While this is not great, writing tests that ensure that signatures are generated # correctly without pulling in all of sorbet is at the very least incredibly complex. # So this is the solution for now. @@ -666,6 +666,12 @@ def test_unknown_fields m2_decoded = less::M2.decode(msg) assert_equal({ a: "A", sint64: -2**63 }, m2_decoded.to_h) + + assert_equal( + attr, + more::M1.decode(m2_decoded.to_proto).to_h, + "expected unknown fields to be present in encoded message", + ) end def test_high_field_number @@ -865,20 +871,7 @@ def parse_string(string) end def parse_file(path) - string = File.binread(path) - - begin - binfile = Tempfile.new - Tempfile.create do |f| - f.write(string) - f.flush - system("protoc -o #{binfile.path} -I/:'#{import_path}' #{f.path}") - end - binfile.rewind - Google::Protobuf::FileDescriptorSet.decode(binfile.read) - ensure - binfile.unlink - end + parse_string(File.binread(path)) end end end diff --git a/test/fixtures/typed_test.correct.rb b/test/fixtures/typed_test.correct.rb index 3a8f7c6..5676e52 100644 --- a/test/fixtures/typed_test.correct.rb +++ b/test/fixtures/typed_test.correct.rb @@ -291,20 +291,38 @@ def decode_from(buff, index, len) # unexpected, so discard it and continue. if !found wire_type = tag & 0x7 + + unknown_bytes = +"".b + val = tag + while val != 0 + byte = val & 0x7F + + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + case wire_type when 0 i = 0 while true newbyte = buff.getbyte(index) index += 1 - break if newbyte.nil? || newbyte < 0x80 + break if newbyte.nil? + unknown_bytes << newbyte + break if newbyte < 0x80 i += 1 break if i > 9 end when 1 + unknown_bytes << buff.byteslice(index, 8) index += 8 when 2 - ## PULL_BYTES value = if (byte0 = buff.getbyte(index)) < 0x80 index += 1 @@ -354,15 +372,29 @@ def decode_from(buff, index, len) raise "integer decoding error" end - buff.byteslice(index, value) - index += value + val = value + while val != 0 + byte = val & 0x7F - ## END PULL_BYTES + val >>= 7 + # This drops the top bits, + # Otherwise, with a signed right shift, + # we get infinity one bits at the top + val &= (1 << 57) - 1 + + byte |= 0x80 if val != 0 + unknown_bytes << byte + end + + unknown_bytes << buff.byteslice(index, value) + index += value when 5 + unknown_bytes << buff.byteslice(index, 4) index += 4 else raise "unknown wire type #{wire_type}" end + (@_unknown_fields ||= +"".b) << unknown_bytes return self if index >= len ## PULL_UINT64 tag = @@ -1608,7 +1640,7 @@ def _encode(buff) buff.concat(val.b) end - + buff << @_unknown_fields if @_unknown_fields buff end