17e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# Protocol Buffers - Google's data interchange format 27e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# Copyright 2008 Google Inc. All rights reserved. 37e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# http://code.google.com/p/protobuf/ 47e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# 57e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# Redistribution and use in source and binary forms, with or without 67e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# modification, are permitted provided that the following conditions are 77e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# met: 87e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# 97e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# * Redistributions of source code must retain the above copyright 107e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# notice, this list of conditions and the following disclaimer. 117e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# * Redistributions in binary form must reproduce the above 127e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# copyright notice, this list of conditions and the following disclaimer 137e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# in the documentation and/or other materials provided with the 147e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# distribution. 157e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# * Neither the name of Google Inc. nor the names of its 167e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# contributors may be used to endorse or promote products derived from 177e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# this software without specific prior written permission. 187e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# 197e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 207e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 217e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 227e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 237e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 247e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 257e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 267e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 277e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 287e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 297e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 307e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 317e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang"""Constants and static functions to support protocol buffer wire format.""" 327e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 337e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang__author__ = 'robinson@google.com (Will Robinson)' 347e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 357e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangimport struct 367e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangfrom google.protobuf import descriptor 377e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangfrom google.protobuf import message 387e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 397e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 407e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangTAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. 417e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangTAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 427e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 437e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# These numbers identify the wire type of a protocol buffer value. 447e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded 457e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# tag-and-type to store one of these WIRETYPE_* constants. 467e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# These values must match WireType enum in google/protobuf/wire_format.h. 477e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangWIRETYPE_VARINT = 0 487e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangWIRETYPE_FIXED64 = 1 497e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangWIRETYPE_LENGTH_DELIMITED = 2 507e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangWIRETYPE_START_GROUP = 3 517e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangWIRETYPE_END_GROUP = 4 527e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangWIRETYPE_FIXED32 = 5 537e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang_WIRETYPE_MAX = 5 547e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 557e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 567e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# Bounds for various integer types. 577e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangINT32_MAX = int((1 << 31) - 1) 587e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangINT32_MIN = int(-(1 << 31)) 597e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangUINT32_MAX = (1 << 32) - 1 607e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 617e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangINT64_MAX = (1 << 63) - 1 627e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangINT64_MIN = -(1 << 63) 637e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangUINT64_MAX = (1 << 64) - 1 647e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 657e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# "struct" format strings that will encode/decode the specified formats. 667e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangFORMAT_UINT32_LITTLE_ENDIAN = '<I' 677e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangFORMAT_UINT64_LITTLE_ENDIAN = '<Q' 687e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangFORMAT_FLOAT_LITTLE_ENDIAN = '<f' 697e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangFORMAT_DOUBLE_LITTLE_ENDIAN = '<d' 707e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 717e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 727e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# We'll have to provide alternate implementations of AppendLittleEndian*() on 737e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# any architectures where these checks fail. 747e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangif struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4: 757e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang raise AssertionError('Format "I" is not a 32-bit number.') 767e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangif struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8: 777e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang raise AssertionError('Format "Q" is not a 64-bit number.') 787e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 797e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 807e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef PackTag(field_number, wire_type): 817e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """Returns an unsigned 32-bit integer that encodes the field number and 827e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang wire type information in standard protocol message wire format. 837e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 847e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang Args: 857e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang field_number: Expected to be an integer in the range [1, 1 << 29) 867e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang wire_type: One of the WIRETYPE_* constants. 877e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """ 887e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if not 0 <= wire_type <= _WIRETYPE_MAX: 897e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang raise message.EncodeError('Unknown wire type: %d' % wire_type) 907e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (field_number << TAG_TYPE_BITS) | wire_type 917e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 927e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 937e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef UnpackTag(tag): 947e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """The inverse of PackTag(). Given an unsigned 32-bit number, 957e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang returns a (field_number, wire_type) tuple. 967e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """ 977e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (tag >> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) 987e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 997e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1007e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef ZigZagEncode(value): 1017e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """ZigZag Transform: Encodes signed integers so that they can be 1027e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang effectively used with varint encoding. See wire_format.h for 1037e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang more details. 1047e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """ 1057e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if value >= 0: 1067e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return value << 1 1077e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (value << 1) ^ (~0) 1087e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1097e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1107e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef ZigZagDecode(value): 1117e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """Inverse of ZigZagEncode().""" 1127e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if not value & 0x1: 1137e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return value >> 1 1147e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (value >> 1) ^ (~0) 1157e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1167e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1177e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1187e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# The *ByteSize() functions below return the number of bytes required to 1197e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# serialize "field number + type" information and then serialize the value. 1207e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1217e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1227e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef Int32ByteSize(field_number, int32): 1237e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return Int64ByteSize(field_number, int32) 1247e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1257e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1267e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef Int32ByteSizeNoTag(int32): 1277e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32) 1287e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1297e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1307e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef Int64ByteSize(field_number, int64): 1317e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # Have to convert to uint before calling UInt64ByteSize(). 1327e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return UInt64ByteSize(field_number, 0xffffffffffffffff & int64) 1337e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1347e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1357e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef UInt32ByteSize(field_number, uint32): 1367e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return UInt64ByteSize(field_number, uint32) 1377e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1387e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1397e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef UInt64ByteSize(field_number, uint64): 1407e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) 1417e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1427e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1437e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef SInt32ByteSize(field_number, int32): 1447e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return UInt32ByteSize(field_number, ZigZagEncode(int32)) 1457e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1467e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1477e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef SInt64ByteSize(field_number, int64): 1487e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return UInt64ByteSize(field_number, ZigZagEncode(int64)) 1497e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1507e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1517e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef Fixed32ByteSize(field_number, fixed32): 1527e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 4 1537e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1547e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1557e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef Fixed64ByteSize(field_number, fixed64): 1567e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 8 1577e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1587e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1597e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef SFixed32ByteSize(field_number, sfixed32): 1607e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 4 1617e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1627e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1637e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef SFixed64ByteSize(field_number, sfixed64): 1647e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 8 1657e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1667e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1677e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef FloatByteSize(field_number, flt): 1687e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 4 1697e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1707e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1717e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef DoubleByteSize(field_number, double): 1727e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 8 1737e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1747e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1757e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef BoolByteSize(field_number, b): 1767e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return TagByteSize(field_number) + 1 1777e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1787e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1797e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef EnumByteSize(field_number, enum): 1807e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return UInt32ByteSize(field_number, enum) 1817e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1827e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1837e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef StringByteSize(field_number, string): 1847e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return BytesByteSize(field_number, string.encode('utf-8')) 1857e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1867e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1877e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef BytesByteSize(field_number, b): 1887e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (TagByteSize(field_number) 1897e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang + _VarUInt64ByteSizeNoTag(len(b)) 1907e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang + len(b)) 1917e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1927e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1937e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef GroupByteSize(field_number, message): 1947e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (2 * TagByteSize(field_number) # START and END group. 1957e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang + message.ByteSize()) 1967e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1977e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 1987e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef MessageByteSize(field_number, message): 1997e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return (TagByteSize(field_number) 2007e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang + _VarUInt64ByteSizeNoTag(message.ByteSize()) 2017e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang + message.ByteSize()) 2027e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2037e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2047e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef MessageSetItemByteSize(field_number, msg): 2057e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # First compute the sizes of the tags. 2067e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # There are 2 tags for the beginning and ending of the repeated group, that 2077e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # is field number 1, one with field number 2 (type_id) and one with field 2087e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # number 3 (message). 2097e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3)) 2107e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2117e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # Add the number of bytes for type_id. 2127e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang total_size += _VarUInt64ByteSizeNoTag(field_number) 2137e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2147e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang message_size = msg.ByteSize() 2157e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2167e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # The number of bytes for encoding the length of the message. 2177e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang total_size += _VarUInt64ByteSizeNoTag(message_size) 2187e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2197e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # The size of the message. 2207e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang total_size += message_size 2217e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return total_size 2227e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2237e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2247e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef TagByteSize(field_number): 2257e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """Returns the bytes required to serialize a tag with this field number.""" 2267e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang # Just pass in type 0, since the type won't affect the tag+type size. 2277e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) 2287e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2297e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2307e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang# Private helper function for the *ByteSize() functions above. 2317e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2327e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef _VarUInt64ByteSizeNoTag(uint64): 2337e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """Returns the number of bytes required to serialize a single varint 2347e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang using boundary value comparisons. (unrolled loop optimization -WPierce) 2357e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang uint64 must be unsigned. 2367e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """ 2377e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x7f: return 1 2387e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x3fff: return 2 2397e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x1fffff: return 3 2407e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0xfffffff: return 4 2417e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x7ffffffff: return 5 2427e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x3ffffffffff: return 6 2437e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x1ffffffffffff: return 7 2447e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0xffffffffffffff: return 8 2457e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 <= 0x7fffffffffffffff: return 9 2467e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang if uint64 > UINT64_MAX: 2477e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang raise message.EncodeError('Value out of range: %d' % uint64) 2487e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return 10 2497e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2507e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2517e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing WangNON_PACKABLE_TYPES = ( 2527e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang descriptor.FieldDescriptor.TYPE_STRING, 2537e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang descriptor.FieldDescriptor.TYPE_GROUP, 2547e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang descriptor.FieldDescriptor.TYPE_MESSAGE, 2557e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang descriptor.FieldDescriptor.TYPE_BYTES 2567e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang) 2577e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2587e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2597e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wangdef IsTypePackable(field_type): 2607e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """Return true iff packable = true is valid for fields of this type. 2617e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2627e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang Args: 2637e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang field_type: a FieldDescriptor::Type value. 2647e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang 2657e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang Returns: 2667e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang True iff fields of this type are packable. 2677e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang """ 2687e7f2e9122af6c7e7e7d4ba205fdf46d50b95eefYing Wang return field_type not in NON_PACKABLE_TYPES 269