| 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..752f4eabc201d3fa1256eb369537e002699d1f68 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
|
| @@ -28,6 +28,10 @@
|
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| +#PY25 compatible for GAE.
|
| +#
|
| +# Copyright 2009 Google Inc. All Rights Reserved.
|
| +
|
| """Code for encoding protocol message primitives.
|
|
|
| Contains the logic for encoding every logical protocol field type
|
| @@ -67,6 +71,8 @@ sizer rather than when calling them. In particular:
|
| __author__ = 'kenton@google.com (Kenton Varda)'
|
|
|
| import struct
|
| +import sys ##PY25
|
| +_PY2 = sys.version_info[0] < 3 ##PY25
|
| from google.protobuf.internal import wire_format
|
|
|
|
|
| @@ -308,7 +314,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 +339,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,7 +372,8 @@ def MessageSetItemSizer(field_number):
|
| def _VarintEncoder():
|
| """Return an encoder for a basic varint value (does not include tag)."""
|
|
|
| - local_chr = chr
|
| + local_chr = _PY2 and chr or (lambda x: bytes((x,))) ##PY25
|
| +##!PY25 local_chr = chr if bytes is str else lambda x: bytes((x,))
|
| def EncodeVarint(write, value):
|
| bits = value & 0x7f
|
| value >>= 7
|
| @@ -357,7 +390,8 @@ def _SignedVarintEncoder():
|
| """Return an encoder for a basic signed varint value (does not include
|
| tag)."""
|
|
|
| - local_chr = chr
|
| + local_chr = _PY2 and chr or (lambda x: bytes((x,))) ##PY25
|
| +##!PY25 local_chr = chr if bytes is str else lambda x: bytes((x,))
|
| def EncodeSignedVarint(write, value):
|
| if value < 0:
|
| value += (1 << 64)
|
| @@ -382,7 +416,8 @@ def _VarintBytes(value):
|
|
|
| pieces = []
|
| _EncodeVarint(pieces.append, value)
|
| - return "".join(pieces)
|
| + return "".encode("latin1").join(pieces) ##PY25
|
| +##!PY25 return b"".join(pieces)
|
|
|
|
|
| def TagBytes(field_number, wire_type):
|
| @@ -520,26 +555,33 @@ def _FloatingPointEncoder(wire_type, format):
|
| format: The format string to pass to struct.pack().
|
| """
|
|
|
| + b = _PY2 and (lambda x:x) or (lambda x:x.encode('latin1')) ##PY25
|
| value_size = struct.calcsize(format)
|
| if value_size == 4:
|
| 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')) ##PY25
|
| +##!PY25 write(b'\x00\x00\x80\x7F')
|
| elif value == _NEG_INF:
|
| - write('\x00\x00\x80\xFF')
|
| + write(b('\x00\x00\x80\xFF')) ##PY25
|
| +##!PY25 write(b'\x00\x00\x80\xFF')
|
| elif value != value: # NaN
|
| - write('\x00\x00\xC0\x7F')
|
| + write(b('\x00\x00\xC0\x7F')) ##PY25
|
| +##!PY25 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')) ##PY25
|
| +##!PY25 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')) ##PY25
|
| +##!PY25 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')) ##PY25
|
| +##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
|
| else:
|
| raise
|
| else:
|
| @@ -615,8 +657,10 @@ 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)
|
| +##!PY25 false_byte = b'\x00'
|
| +##!PY25 true_byte = b'\x01'
|
| + false_byte = '\x00'.encode('latin1') ##PY25
|
| + true_byte = '\x01'.encode('latin1') ##PY25
|
| if is_packed:
|
| tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
| local_EncodeVarint = _EncodeVarint
|
| @@ -752,7 +796,8 @@ def MessageSetItemEncoder(field_number):
|
| }
|
| }
|
| """
|
| - start_bytes = "".join([
|
| + start_bytes = "".encode("latin1").join([ ##PY25
|
| +##!PY25 start_bytes = b"".join([
|
| TagBytes(1, wire_format.WIRETYPE_START_GROUP),
|
| TagBytes(2, wire_format.WIRETYPE_VARINT),
|
| _VarintBytes(field_number),
|
| @@ -767,3 +812,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
|
|
|