| Index: third_party/protobuf/python/google/protobuf/internal/encoder.py
|
| diff --git a/third_party/protobuf/python/google/protobuf/internal/encoder.py b/third_party/protobuf/python/google/protobuf/internal/encoder.py
|
| index 777975e82e042b277be6ff6b1dae3b4f5cf6fa57..48ef2df31c21dae7cb5b8c813a38613da63a22e6 100755
|
| --- a/third_party/protobuf/python/google/protobuf/internal/encoder.py
|
| +++ b/third_party/protobuf/python/google/protobuf/internal/encoder.py
|
| @@ -1,6 +1,6 @@
|
| # Protocol Buffers - Google's data interchange format
|
| # Copyright 2008 Google Inc. All rights reserved.
|
| -# http://code.google.com/p/protobuf/
|
| +# https://developers.google.com/protocol-buffers/
|
| #
|
| # Redistribution and use in source and binary forms, with or without
|
| # modification, are permitted provided that the following conditions are
|
| @@ -41,7 +41,7 @@ FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The
|
| sizer takes a value of this field's type and computes its byte size. The
|
| encoder takes a writer function and a value. It encodes the value into byte
|
| strings and invokes the writer function to write those strings. Typically the
|
| -writer function is the write() method of a cStringIO.
|
| +writer function is the write() method of a BytesIO.
|
|
|
| We try to do as much work as possible when constructing the writer and the
|
| sizer rather than when calling them. In particular:
|
| @@ -67,6 +67,9 @@ sizer rather than when calling them. In particular:
|
| __author__ = 'kenton@google.com (Kenton Varda)'
|
|
|
| import struct
|
| +
|
| +import six
|
| +
|
| from google.protobuf.internal import wire_format
|
|
|
|
|
| @@ -308,7 +311,7 @@ def MessageSizer(field_number, is_repeated, is_packed):
|
|
|
|
|
| # --------------------------------------------------------------------
|
| -# MessageSet is special.
|
| +# MessageSet is special: it needs custom logic to compute its size properly.
|
|
|
|
|
| def MessageSetItemSizer(field_number):
|
| @@ -333,6 +336,32 @@ def MessageSetItemSizer(field_number):
|
| return FieldSize
|
|
|
|
|
| +# --------------------------------------------------------------------
|
| +# Map is special: it needs custom logic to compute its size properly.
|
| +
|
| +
|
| +def MapSizer(field_descriptor):
|
| + """Returns a sizer for a map field."""
|
| +
|
| + # Can't look at field_descriptor.message_type._concrete_class because it may
|
| + # not have been initialized yet.
|
| + message_type = field_descriptor.message_type
|
| + message_sizer = MessageSizer(field_descriptor.number, False, False)
|
| +
|
| + def FieldSize(map_value):
|
| + total = 0
|
| + for key in map_value:
|
| + value = map_value[key]
|
| + # It's wasteful to create the messages and throw them away one second
|
| + # later since we'll do the same for the actual encode. But there's not an
|
| + # obvious way to avoid this within the current design without tons of code
|
| + # duplication.
|
| + entry_msg = message_type._concrete_class(key=key, value=value)
|
| + total += message_sizer(entry_msg)
|
| + return total
|
| +
|
| + return FieldSize
|
| +
|
| # ====================================================================
|
| # Encoders!
|
|
|
| @@ -340,15 +369,14 @@ def MessageSetItemSizer(field_number):
|
| def _VarintEncoder():
|
| """Return an encoder for a basic varint value (does not include tag)."""
|
|
|
| - local_chr = chr
|
| def EncodeVarint(write, value):
|
| bits = value & 0x7f
|
| value >>= 7
|
| while value:
|
| - write(local_chr(0x80|bits))
|
| + write(six.int2byte(0x80|bits))
|
| bits = value & 0x7f
|
| value >>= 7
|
| - return write(local_chr(bits))
|
| + return write(six.int2byte(bits))
|
|
|
| return EncodeVarint
|
|
|
| @@ -357,17 +385,16 @@ def _SignedVarintEncoder():
|
| """Return an encoder for a basic signed varint value (does not include
|
| tag)."""
|
|
|
| - local_chr = chr
|
| def EncodeSignedVarint(write, value):
|
| if value < 0:
|
| value += (1 << 64)
|
| bits = value & 0x7f
|
| value >>= 7
|
| while value:
|
| - write(local_chr(0x80|bits))
|
| + write(six.int2byte(0x80|bits))
|
| bits = value & 0x7f
|
| value >>= 7
|
| - return write(local_chr(bits))
|
| + return write(six.int2byte(bits))
|
|
|
| return EncodeSignedVarint
|
|
|
| @@ -382,7 +409,7 @@ def _VarintBytes(value):
|
|
|
| pieces = []
|
| _EncodeVarint(pieces.append, value)
|
| - return "".join(pieces)
|
| + return b"".join(pieces)
|
|
|
|
|
| def TagBytes(field_number, wire_type):
|
| @@ -525,21 +552,21 @@ def _FloatingPointEncoder(wire_type, format):
|
| def EncodeNonFiniteOrRaise(write, value):
|
| # Remember that the serialized form uses little-endian byte order.
|
| if value == _POS_INF:
|
| - write('\x00\x00\x80\x7F')
|
| + write(b'\x00\x00\x80\x7F')
|
| elif value == _NEG_INF:
|
| - write('\x00\x00\x80\xFF')
|
| + write(b'\x00\x00\x80\xFF')
|
| elif value != value: # NaN
|
| - write('\x00\x00\xC0\x7F')
|
| + write(b'\x00\x00\xC0\x7F')
|
| else:
|
| raise
|
| elif value_size == 8:
|
| def EncodeNonFiniteOrRaise(write, value):
|
| if value == _POS_INF:
|
| - write('\x00\x00\x00\x00\x00\x00\xF0\x7F')
|
| + write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
|
| elif value == _NEG_INF:
|
| - write('\x00\x00\x00\x00\x00\x00\xF0\xFF')
|
| + write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
|
| elif value != value: # NaN
|
| - write('\x00\x00\x00\x00\x00\x00\xF8\x7F')
|
| + write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
|
| else:
|
| raise
|
| else:
|
| @@ -615,8 +642,8 @@ DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
|
| def BoolEncoder(field_number, is_repeated, is_packed):
|
| """Returns an encoder for a boolean field."""
|
|
|
| - false_byte = chr(0)
|
| - true_byte = chr(1)
|
| + false_byte = b'\x00'
|
| + true_byte = b'\x01'
|
| if is_packed:
|
| tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
| local_EncodeVarint = _EncodeVarint
|
| @@ -752,7 +779,7 @@ def MessageSetItemEncoder(field_number):
|
| }
|
| }
|
| """
|
| - start_bytes = "".join([
|
| + start_bytes = b"".join([
|
| TagBytes(1, wire_format.WIRETYPE_START_GROUP),
|
| TagBytes(2, wire_format.WIRETYPE_VARINT),
|
| _VarintBytes(field_number),
|
| @@ -767,3 +794,30 @@ def MessageSetItemEncoder(field_number):
|
| return write(end_bytes)
|
|
|
| return EncodeField
|
| +
|
| +
|
| +# --------------------------------------------------------------------
|
| +# As before, Map is special.
|
| +
|
| +
|
| +def MapEncoder(field_descriptor):
|
| + """Encoder for extensions of MessageSet.
|
| +
|
| + Maps always have a wire format like this:
|
| + message MapEntry {
|
| + key_type key = 1;
|
| + value_type value = 2;
|
| + }
|
| + repeated MapEntry map = N;
|
| + """
|
| + # Can't look at field_descriptor.message_type._concrete_class because it may
|
| + # not have been initialized yet.
|
| + message_type = field_descriptor.message_type
|
| + encode_message = MessageEncoder(field_descriptor.number, False, False)
|
| +
|
| + def EncodeField(write, value):
|
| + for key in value:
|
| + entry_msg = message_type._concrete_class(key=key, value=value[key])
|
| + encode_message(write, entry_msg)
|
| +
|
| + return EncodeField
|
|
|