Index: third_party/protobuf/python/google/protobuf/internal/decoder.py |
diff --git a/third_party/protobuf/python/google/protobuf/internal/decoder.py b/third_party/protobuf/python/google/protobuf/internal/decoder.py |
index 3837eaea39884a858c1abaad5fa159e9697f71e9..cb6f5729dd765e7105a993c6f3060555d5abb6a4 100755 |
--- a/third_party/protobuf/python/google/protobuf/internal/decoder.py |
+++ b/third_party/protobuf/python/google/protobuf/internal/decoder.py |
@@ -1,6 +1,6 @@ |
# Protocol Buffers - Google's data interchange format |
# Copyright 2008 Google Inc. All rights reserved. |
-# https://developers.google.com/protocol-buffers/ |
+# http://code.google.com/p/protobuf/ |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are |
@@ -28,10 +28,6 @@ |
# (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 decoding protocol buffer primitives. |
This code is very similar to encoder.py -- read the docs for that module first. |
@@ -85,8 +81,6 @@ we repeatedly read a tag, look up the corresponding decoder, and invoke it. |
__author__ = 'kenton@google.com (Kenton Varda)' |
import struct |
-import sys ##PY25 |
-_PY2 = sys.version_info[0] < 3 ##PY25 |
from google.protobuf.internal import encoder |
from google.protobuf.internal import wire_format |
from google.protobuf import message |
@@ -104,7 +98,7 @@ _NAN = _POS_INF * 0 |
_DecodeError = message.DecodeError |
-def _VarintDecoder(mask, result_type): |
+def _VarintDecoder(mask): |
"""Return an encoder for a basic varint value (does not include tag). |
Decoded values will be bitwise-anded with the given mask before being |
@@ -115,18 +109,15 @@ def _VarintDecoder(mask, result_type): |
""" |
local_ord = ord |
- py2 = _PY2 ##PY25 |
-##!PY25 py2 = str is bytes |
def DecodeVarint(buffer, pos): |
result = 0 |
shift = 0 |
while 1: |
- b = local_ord(buffer[pos]) if py2 else buffer[pos] |
+ b = local_ord(buffer[pos]) |
result |= ((b & 0x7f) << shift) |
pos += 1 |
if not (b & 0x80): |
result &= mask |
- result = result_type(result) |
return (result, pos) |
shift += 7 |
if shift >= 64: |
@@ -134,17 +125,15 @@ def _VarintDecoder(mask, result_type): |
return DecodeVarint |
-def _SignedVarintDecoder(mask, result_type): |
+def _SignedVarintDecoder(mask): |
"""Like _VarintDecoder() but decodes signed values.""" |
local_ord = ord |
- py2 = _PY2 ##PY25 |
-##!PY25 py2 = str is bytes |
def DecodeVarint(buffer, pos): |
result = 0 |
shift = 0 |
while 1: |
- b = local_ord(buffer[pos]) if py2 else buffer[pos] |
+ b = local_ord(buffer[pos]) |
result |= ((b & 0x7f) << shift) |
pos += 1 |
if not (b & 0x80): |
@@ -153,23 +142,19 @@ def _SignedVarintDecoder(mask, result_type): |
result |= ~mask |
else: |
result &= mask |
- result = result_type(result) |
return (result, pos) |
shift += 7 |
if shift >= 64: |
raise _DecodeError('Too many bytes when decoding varint.') |
return DecodeVarint |
-# We force 32-bit values to int and 64-bit values to long to make |
-# alternate implementations where the distinction is more significant |
-# (e.g. the C++ implementation) simpler. |
-_DecodeVarint = _VarintDecoder((1 << 64) - 1, long) |
-_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1, long) |
+_DecodeVarint = _VarintDecoder((1 << 64) - 1) |
+_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1) |
# Use these versions for values which must be limited to 32 bits. |
-_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) |
-_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1, int) |
+_DecodeVarint32 = _VarintDecoder((1 << 32) - 1) |
+_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1) |
def ReadTag(buffer, pos): |
@@ -183,10 +168,8 @@ def ReadTag(buffer, pos): |
use that, but not in Python. |
""" |
- py2 = _PY2 ##PY25 |
-##!PY25 py2 = str is bytes |
start = pos |
- while (ord(buffer[pos]) if py2 else buffer[pos]) & 0x80: |
+ while ord(buffer[pos]) & 0x80: |
pos += 1 |
pos += 1 |
return (buffer[start:pos], pos) |
@@ -301,7 +284,6 @@ def _FloatDecoder(): |
""" |
local_unpack = struct.unpack |
- b = (lambda x:x) if _PY2 else lambda x:x.encode('latin1') ##PY25 |
def InnerDecode(buffer, pos): |
# We expect a 32-bit value in little-endian byte order. Bit 1 is the sign |
@@ -312,17 +294,13 @@ def _FloatDecoder(): |
# If this value has all its exponent bits set, then it's non-finite. |
# In Python 2.4, struct.unpack will convert it to a finite 64-bit value. |
# To avoid that, we parse it specially. |
- if ((float_bytes[3:4] in b('\x7F\xFF')) ##PY25 |
-##!PY25 if ((float_bytes[3:4] in b'\x7F\xFF') |
- and (float_bytes[2:3] >= b('\x80'))): ##PY25 |
-##!PY25 and (float_bytes[2:3] >= b'\x80')): |
+ if ((float_bytes[3] in '\x7F\xFF') |
+ and (float_bytes[2] >= '\x80')): |
# If at least one significand bit is set... |
- if float_bytes[0:3] != b('\x00\x00\x80'): ##PY25 |
-##!PY25 if float_bytes[0:3] != b'\x00\x00\x80': |
+ if float_bytes[0:3] != '\x00\x00\x80': |
return (_NAN, new_pos) |
# If sign bit is set... |
- if float_bytes[3:4] == b('\xFF'): ##PY25 |
-##!PY25 if float_bytes[3:4] == b'\xFF': |
+ if float_bytes[3] == '\xFF': |
return (_NEG_INF, new_pos) |
return (_POS_INF, new_pos) |
@@ -341,7 +319,6 @@ def _DoubleDecoder(): |
""" |
local_unpack = struct.unpack |
- b = (lambda x:x) if _PY2 else lambda x:x.encode('latin1') ##PY25 |
def InnerDecode(buffer, pos): |
# We expect a 64-bit value in little-endian byte order. Bit 1 is the sign |
@@ -352,12 +329,9 @@ def _DoubleDecoder(): |
# If this value has all its exponent bits set and at least one significand |
# bit set, it's not a number. In Python 2.4, struct.unpack will treat it |
# as inf or -inf. To avoid that, we treat it specially. |
-##!PY25 if ((double_bytes[7:8] in b'\x7F\xFF') |
-##!PY25 and (double_bytes[6:7] >= b'\xF0') |
-##!PY25 and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')): |
- if ((double_bytes[7:8] in b('\x7F\xFF')) ##PY25 |
- and (double_bytes[6:7] >= b('\xF0')) ##PY25 |
- and (double_bytes[0:7] != b('\x00\x00\x00\x00\x00\x00\xF0'))): ##PY25 |
+ if ((double_bytes[7] in '\x7F\xFF') |
+ and (double_bytes[6] >= '\xF0') |
+ and (double_bytes[0:7] != '\x00\x00\x00\x00\x00\x00\xF0')): |
return (_NAN, new_pos) |
# Note that we expect someone up-stack to catch struct.error and convert |
@@ -368,86 +342,10 @@ def _DoubleDecoder(): |
return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode) |
-def EnumDecoder(field_number, is_repeated, is_packed, key, new_default): |
- enum_type = key.enum_type |
- if is_packed: |
- local_DecodeVarint = _DecodeVarint |
- def DecodePackedField(buffer, pos, end, message, field_dict): |
- value = field_dict.get(key) |
- if value is None: |
- value = field_dict.setdefault(key, new_default(message)) |
- (endpoint, pos) = local_DecodeVarint(buffer, pos) |
- endpoint += pos |
- if endpoint > end: |
- raise _DecodeError('Truncated message.') |
- while pos < endpoint: |
- value_start_pos = pos |
- (element, pos) = _DecodeSignedVarint32(buffer, pos) |
- if element in enum_type.values_by_number: |
- value.append(element) |
- else: |
- if not message._unknown_fields: |
- message._unknown_fields = [] |
- tag_bytes = encoder.TagBytes(field_number, |
- wire_format.WIRETYPE_VARINT) |
- message._unknown_fields.append( |
- (tag_bytes, buffer[value_start_pos:pos])) |
- if pos > endpoint: |
- if element in enum_type.values_by_number: |
- del value[-1] # Discard corrupt value. |
- else: |
- del message._unknown_fields[-1] |
- raise _DecodeError('Packed element was truncated.') |
- return pos |
- return DecodePackedField |
- elif is_repeated: |
- tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) |
- tag_len = len(tag_bytes) |
- def DecodeRepeatedField(buffer, pos, end, message, field_dict): |
- value = field_dict.get(key) |
- if value is None: |
- value = field_dict.setdefault(key, new_default(message)) |
- while 1: |
- (element, new_pos) = _DecodeSignedVarint32(buffer, pos) |
- if element in enum_type.values_by_number: |
- value.append(element) |
- else: |
- if not message._unknown_fields: |
- message._unknown_fields = [] |
- message._unknown_fields.append( |
- (tag_bytes, buffer[pos:new_pos])) |
- # Predict that the next tag is another copy of the same repeated |
- # field. |
- pos = new_pos + tag_len |
- if buffer[new_pos:pos] != tag_bytes or new_pos >= end: |
- # Prediction failed. Return. |
- if new_pos > end: |
- raise _DecodeError('Truncated message.') |
- return new_pos |
- return DecodeRepeatedField |
- else: |
- def DecodeField(buffer, pos, end, message, field_dict): |
- value_start_pos = pos |
- (enum_value, pos) = _DecodeSignedVarint32(buffer, pos) |
- if pos > end: |
- raise _DecodeError('Truncated message.') |
- if enum_value in enum_type.values_by_number: |
- field_dict[key] = enum_value |
- else: |
- if not message._unknown_fields: |
- message._unknown_fields = [] |
- tag_bytes = encoder.TagBytes(field_number, |
- wire_format.WIRETYPE_VARINT) |
- message._unknown_fields.append( |
- (tag_bytes, buffer[value_start_pos:pos])) |
- return pos |
- return DecodeField |
- |
- |
# -------------------------------------------------------------------- |
-Int32Decoder = _SimpleDecoder( |
+Int32Decoder = EnumDecoder = _SimpleDecoder( |
wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) |
Int64Decoder = _SimpleDecoder( |
@@ -482,14 +380,6 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default): |
local_DecodeVarint = _DecodeVarint |
local_unicode = unicode |
- def _ConvertToUnicode(byte_str): |
- try: |
- return local_unicode(byte_str, 'utf-8') |
- except UnicodeDecodeError, e: |
- # add more information to the error message and re-raise it. |
- e.reason = '%s in field: %s' % (e, key.full_name) |
- raise |
- |
assert not is_packed |
if is_repeated: |
tag_bytes = encoder.TagBytes(field_number, |
@@ -504,7 +394,7 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default): |
new_pos = pos + size |
if new_pos > end: |
raise _DecodeError('Truncated string.') |
- value.append(_ConvertToUnicode(buffer[pos:new_pos])) |
+ value.append(local_unicode(buffer[pos:new_pos], 'utf-8')) |
# Predict that the next tag is another copy of the same repeated field. |
pos = new_pos + tag_len |
if buffer[new_pos:pos] != tag_bytes or new_pos == end: |
@@ -517,7 +407,7 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default): |
new_pos = pos + size |
if new_pos > end: |
raise _DecodeError('Truncated string.') |
- field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) |
+ field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8') |
return new_pos |
return DecodeField |
@@ -621,6 +511,9 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): |
if value is None: |
value = field_dict.setdefault(key, new_default(message)) |
while 1: |
+ value = field_dict.get(key) |
+ if value is None: |
+ value = field_dict.setdefault(key, new_default(message)) |
# Read length. |
(size, pos) = local_DecodeVarint(buffer, pos) |
new_pos = pos + size |
@@ -733,59 +626,13 @@ def MessageSetItemDecoder(extensions_by_number): |
return DecodeItem |
# -------------------------------------------------------------------- |
- |
-def MapDecoder(field_descriptor, new_default, is_message_map): |
- """Returns a decoder for a map field.""" |
- |
- key = field_descriptor |
- tag_bytes = encoder.TagBytes(field_descriptor.number, |
- wire_format.WIRETYPE_LENGTH_DELIMITED) |
- tag_len = len(tag_bytes) |
- local_DecodeVarint = _DecodeVarint |
- # Can't read _concrete_class yet; might not be initialized. |
- message_type = field_descriptor.message_type |
- |
- def DecodeMap(buffer, pos, end, message, field_dict): |
- submsg = message_type._concrete_class() |
- value = field_dict.get(key) |
- if value is None: |
- value = field_dict.setdefault(key, new_default(message)) |
- while 1: |
- # Read length. |
- (size, pos) = local_DecodeVarint(buffer, pos) |
- new_pos = pos + size |
- if new_pos > end: |
- raise _DecodeError('Truncated message.') |
- # Read sub-message. |
- submsg.Clear() |
- if submsg._InternalParse(buffer, pos, new_pos) != new_pos: |
- # The only reason _InternalParse would return early is if it |
- # encountered an end-group tag. |
- raise _DecodeError('Unexpected end-group tag.') |
- |
- if is_message_map: |
- value[submsg.key].MergeFrom(submsg.value) |
- else: |
- value[submsg.key] = submsg.value |
- |
- # Predict that the next tag is another copy of the same repeated field. |
- pos = new_pos + tag_len |
- if buffer[new_pos:pos] != tag_bytes or new_pos == end: |
- # Prediction failed. Return. |
- return new_pos |
- |
- return DecodeMap |
- |
-# -------------------------------------------------------------------- |
# Optimization is not as heavy here because calls to SkipField() are rare, |
# except for handling end-group tags. |
def _SkipVarint(buffer, pos, end): |
"""Skip a varint value. Returns the new position.""" |
- # Previously ord(buffer[pos]) raised IndexError when pos is out of range. |
- # With this code, ord(b'') raises TypeError. Both are handled in |
- # python_message.py to generate a 'Truncated message' error. |
- while ord(buffer[pos:pos+1]) & 0x80: |
+ |
+ while ord(buffer[pos]) & 0x80: |
pos += 1 |
pos += 1 |
if pos > end: |
@@ -852,6 +699,7 @@ def _FieldSkipper(): |
] |
wiretype_mask = wire_format.TAG_TYPE_MASK |
+ local_ord = ord |
def SkipField(buffer, pos, end, tag_bytes): |
"""Skips a field with the specified tag. |
@@ -864,7 +712,7 @@ def _FieldSkipper(): |
""" |
# The wire type is always in the first byte since varints are little-endian. |
- wire_type = ord(tag_bytes[0:1]) & wiretype_mask |
+ wire_type = local_ord(tag_bytes[0]) & wiretype_mask |
return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end) |
return SkipField |