1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville"""Code for encoding protocol message primitives. 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleContains the logic for encoding every logical protocol field type 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinto one of the 5 physical wire types. 35d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 36d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThis code is designed to push the Python interpreter's performance to the 37d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillelimits. 38d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThe basic idea is that at startup time, for every field (i.e. every 40d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFieldDescriptor) we construct two functions: a "sizer" and an "encoder". The 41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillesizer takes a value of this field's type and computes its byte size. The 42d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleencoder takes a writer function and a value. It encodes the value into byte 43d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestrings and invokes the writer function to write those strings. Typically the 44d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillewriter function is the write() method of a cStringIO. 45d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 46d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleWe try to do as much work as possible when constructing the writer and the 47d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillesizer rather than when calling them. In particular: 48d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* We copy any needed global functions to local variables, so that we do not need 49d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville to do costly global table lookups at runtime. 50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* Similarly, we try to do any attribute lookups at startup time if possible. 51d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* Every field's tag is encoded to bytes at startup, since it can't change at 52d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville runtime. 53d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* Whatever component of the field size we can compute at startup, we do. 54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* We *avoid* sharing code if doing so would make the code slower and not sharing 55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville does not burden us too much. For example, encoders for repeated fields do 56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville not just call the encoders for singular fields in a loop because this would 57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville add an extra function call overhead for every loop iteration; instead, we 58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville manually inline the single-value encoder into the loop. 59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* If a Python function lacks a return statement, Python actually generates 60d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville instructions to pop the result of the last statement off the stack, push 61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville None onto the stack, and then return that. If we really don't care what 62d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value is returned, then we can save two instructions by returning the 63d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result of the last statement. It looks funny but it helps. 64d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville* We assume that type and bounds checking has happened at a higher level. 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville""" 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 67d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville__author__ = 'kenton@google.com (Kenton Varda)' 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport struct 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import wire_format 71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 72d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 73d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _VarintSize(value): 74d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Compute the size of a varint value.""" 75d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x7f: return 1 76d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x3fff: return 2 77d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x1fffff: return 3 78d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0xfffffff: return 4 79d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x7ffffffff: return 5 80d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x3ffffffffff: return 6 81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x1ffffffffffff: return 7 82d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0xffffffffffffff: return 8 83d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x7fffffffffffffff: return 9 84d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return 10 85d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 86d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 87d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SignedVarintSize(value): 88d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Compute the size of a signed varint value.""" 89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value < 0: return 10 90d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x7f: return 1 91d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x3fff: return 2 92d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x1fffff: return 3 93d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0xfffffff: return 4 94d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x7ffffffff: return 5 95d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x3ffffffffff: return 6 96d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x1ffffffffffff: return 7 97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0xffffffffffffff: return 8 98d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value <= 0x7fffffffffffffff: return 9 99d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return 10 100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _TagSize(field_number): 103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns the number of bytes required to serialize a tag with this field 104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville number.""" 105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Just pass in type 0, since the type won't affect the tag+type size. 106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return _VarintSize(wire_format.PackTag(field_number, 0)) 107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# In this section we define some generic sizers. Each of these functions 111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# takes parameters specific to a particular field type, e.g. int32 or fixed64. 112d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# It returns another function which in turn takes parameters specific to a 113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# particular field, e.g. the field number and whether it is repeated or packed. 114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Look at the next section to see how these are used. 115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SimpleSizer(compute_value_size): 118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """A sizer which uses the function compute_value_size to compute the size of 119d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville each value. Typically compute_value_size is _VarintSize.""" 120d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 121d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificSizer(field_number, is_repeated, is_packed): 122d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) 123d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 124d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 125d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def PackedFieldSize(value): 126d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = 0 127d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 128d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += compute_value_size(element) 129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result + local_VarintSize(result) + tag_size 130d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return PackedFieldSize 131d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 132d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 133d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = tag_size * len(value) 134d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 135d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += compute_value_size(element) 136d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 137d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 138d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 139d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 140d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag_size + compute_value_size(value) 141d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 142d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 143d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificSizer 144d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 145d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 146d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _ModifiedSizer(compute_value_size, modify_value): 147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Like SimpleSizer, but modify_value is invoked on each value before it is 148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville passed to compute_value_size. modify_value is typically ZigZagEncode.""" 149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificSizer(field_number, is_repeated, is_packed): 151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) 152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def PackedFieldSize(value): 155d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = 0 156d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 157d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += compute_value_size(modify_value(element)) 158d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result + local_VarintSize(result) + tag_size 159d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return PackedFieldSize 160d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 161d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 162d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = tag_size * len(value) 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 164d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += compute_value_size(modify_value(element)) 165d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 166d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 167d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 168d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 169d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag_size + compute_value_size(modify_value(value)) 170d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 171d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 172d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificSizer 173d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 174d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 175d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _FixedSizer(value_size): 176d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Like _SimpleSizer except for a fixed-size field. The input is the size 177d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville of one value.""" 178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificSizer(field_number, is_repeated, is_packed): 180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) 181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def PackedFieldSize(value): 184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = len(value) * value_size 185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result + local_VarintSize(result) + tag_size 186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return PackedFieldSize 187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville element_size = value_size + tag_size 189d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return len(value) * element_size 191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 193d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_size = value_size + tag_size 194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 195d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return field_size 196d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 197d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 198d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificSizer 199d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 200d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 201d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# ==================================================================== 202d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Here we declare a sizer constructor for each field type. Each "sizer 203d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# constructor" is a function that takes (field_number, is_repeated, is_packed) 204d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# as parameters and returns a sizer, which in turn takes a field value as 205d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# a parameter and returns its encoded size. 206d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 207d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 208d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleInt32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize) 209d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 210d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleUInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize) 211d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 212d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSInt32Sizer = SInt64Sizer = _ModifiedSizer( 213d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _SignedVarintSize, wire_format.ZigZagEncode) 214d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 215d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4) 216d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8) 217d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 218d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleBoolSizer = _FixedSizer(1) 219d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 220d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 221d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef StringSizer(field_number, is_repeated, is_packed): 222d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a sizer for a string field.""" 223d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 224d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) 225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 226d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_len = len 227d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 229d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 230d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = tag_size * len(value) 231d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 232d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = local_len(element.encode('utf-8')) 233d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += local_VarintSize(l) + l 234d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 235d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 236d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 237d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 238d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = local_len(value.encode('utf-8')) 239d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag_size + local_VarintSize(l) + l 240d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 241d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 242d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 243d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef BytesSizer(field_number, is_repeated, is_packed): 244d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a sizer for a bytes field.""" 245d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 246d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) 247d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 248d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_len = len 249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = tag_size * len(value) 253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = local_len(element) 255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += local_VarintSize(l) + l 256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 258d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = local_len(value) 261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag_size + local_VarintSize(l) + l 262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 265d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef GroupSizer(field_number, is_repeated, is_packed): 266d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a sizer for a group field.""" 267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) * 2 269d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 270d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 271d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 272d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = tag_size * len(value) 273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += element.ByteSize() 275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag_size + value.ByteSize() 280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 283d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef MessageSizer(field_number, is_repeated, is_packed): 284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a sizer for a message field.""" 285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 286d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_size = _TagSize(field_number) 287d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 289d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 290d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def RepeatedFieldSize(value): 291d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = tag_size * len(value) 292d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 293d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = element.ByteSize() 294d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result += local_VarintSize(l) + l 295d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 296d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return RepeatedFieldSize 297d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 298d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 299d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = value.ByteSize() 300d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag_size + local_VarintSize(l) + l 301d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 302d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 303d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 304d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# MessageSet is special. 306d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef MessageSetItemSizer(field_number): 309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a sizer for extensions of MessageSet. 310d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville The message set message looks like this: 312d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message MessageSet { 313d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville repeated group Item = 1 { 314d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required int32 type_id = 2; 315d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required string message = 3; 316d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 317d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 318d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 319d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) + 320d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _TagSize(3)) 321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_VarintSize = _VarintSize 322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FieldSize(value): 324d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville l = value.ByteSize() 325d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return static_size + local_VarintSize(l) + l 326d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 327d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return FieldSize 328d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 329d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 330d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# ==================================================================== 331d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Encoders! 332d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 333d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 334d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _VarintEncoder(): 335d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return an encoder for a basic varint value (does not include tag).""" 336d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 337d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_chr = chr 338d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeVarint(write, value): 339d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bits = value & 0x7f 340d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value >>= 7 341d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while value: 342d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(local_chr(0x80|bits)) 343d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bits = value & 0x7f 344d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value >>= 7 345d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(local_chr(bits)) 346d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 347d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeVarint 348d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 349d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 350d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SignedVarintEncoder(): 351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return an encoder for a basic signed varint value (does not include 352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag).""" 353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_chr = chr 355d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeSignedVarint(write, value): 356d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value < 0: 357d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value += (1 << 64) 358d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bits = value & 0x7f 359d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value >>= 7 360d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while value: 361d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(local_chr(0x80|bits)) 362d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bits = value & 0x7f 363d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value >>= 7 364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(local_chr(bits)) 365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeSignedVarint 367d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 369d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_EncodeVarint = _VarintEncoder() 370d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_EncodeSignedVarint = _SignedVarintEncoder() 371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 372d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _VarintBytes(value): 374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Encode the given integer as a varint and return the bytes. This is only 375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville called at startup time so it doesn't need to be fast.""" 376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pieces = [] 378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _EncodeVarint(pieces.append, value) 379d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return "".join(pieces) 380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef TagBytes(field_number, wire_type): 383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Encode the given tag and return the bytes. Only called at startup.""" 384d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return _VarintBytes(wire_format.PackTag(field_number, wire_type)) 386d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 387d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 388d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# As with sizers (see above), we have a number of common encoder 389d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# implementations. 390d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 391d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 392d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SimpleEncoder(wire_type, encode_value, compute_value_size): 393d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return a constructor for an encoder for fields of a particular type. 394d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 395d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Args: 396d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_type: The field's wire type, for encoding tags. 397d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encode_value: A function which encodes an individual value, e.g. 398d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _EncodeVarint(). 399d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville compute_value_size: A function which computes the size of an individual 400d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value, e.g. _VarintSize(). 401d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 402d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 403d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificEncoder(field_number, is_repeated, is_packed): 404d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 405d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodePackedField(write, value): 408d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 409d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size = 0 410d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 411d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size += compute_value_size(element) 412d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, size) 413d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 414d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encode_value(write, element) 415d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodePackedField 416d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 417d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_type) 418d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 419d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 420d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 421d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encode_value(write, element) 422d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 423d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 424d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_type) 425d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 426d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 427d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return encode_value(write, value) 428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 429d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 430d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificEncoder 431d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 432d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 433d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): 434d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Like SimpleEncoder but additionally invokes modify_value on every value 435d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville before passing it to encode_value. Usually modify_value is ZigZagEncode.""" 436d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 437d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificEncoder(field_number, is_repeated, is_packed): 438d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 439d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 440d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 441d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodePackedField(write, value): 442d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 443d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size = 0 444d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 445d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size += compute_value_size(modify_value(element)) 446d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, size) 447d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 448d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encode_value(write, modify_value(element)) 449d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodePackedField 450d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 451d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_type) 452d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 453d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 454d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 455d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encode_value(write, modify_value(element)) 456d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 457d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 458d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_type) 459d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 460d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 461d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return encode_value(write, modify_value(value)) 462d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 463d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 464d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificEncoder 465d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 466d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 467d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _StructPackEncoder(wire_type, format): 468d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return a constructor for an encoder for a fixed-width field. 469d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 470d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Args: 471d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_type: The field's wire type, for encoding tags. 472d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville format: The format string to pass to struct.pack(). 473d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 474d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 475d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value_size = struct.calcsize(format) 476d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 477d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificEncoder(field_number, is_repeated, is_packed): 478d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_struct_pack = struct.pack 479d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 480d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 481d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 482d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodePackedField(write, value): 483d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 484d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, len(value) * value_size) 485d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 486d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(local_struct_pack(format, element)) 487d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodePackedField 488d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 489d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_type) 490d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 491d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 492d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 493d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(local_struct_pack(format, element)) 494d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 495d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 496d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_type) 497d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 498d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 499d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(local_struct_pack(format, value)) 500d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 501d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 502d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificEncoder 503d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 504d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 505d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# ==================================================================== 506d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Here we declare an encoder constructor for each field type. These work 507d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# very similarly to sizer constructors, described earlier. 508d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 509d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 510d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleInt32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( 511d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) 512d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 513d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleUInt32Encoder = UInt64Encoder = _SimpleEncoder( 514d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) 515d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 516d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSInt32Encoder = SInt64Encoder = _ModifiedEncoder( 517d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, 518d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.ZigZagEncode) 519d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 520d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Note that Python conveniently guarantees that when using the '<' prefix on 521d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# formats, they will also have the same size across all platforms (as opposed 522d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# to without the prefix, where their sizes depend on the C compiler's basic 523d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# type sizes). 524d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I') 525d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q') 526d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i') 527d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q') 528d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<f') 529d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleDoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<d') 530d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 531d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 532d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef BoolEncoder(field_number, is_repeated, is_packed): 533d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns an encoder for a boolean field.""" 534d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 535d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville false_byte = chr(0) 536d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville true_byte = chr(1) 537d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 538d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 539d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 540d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodePackedField(write, value): 541d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 542d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, len(value)) 543d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 544d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if element: 545d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(true_byte) 546d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 547d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(false_byte) 548d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodePackedField 549d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 550d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) 551d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 552d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 553d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 554d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if element: 555d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(true_byte) 556d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 557d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(false_byte) 558d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 559d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 560d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) 561d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 562d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag_bytes) 563d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value: 564d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(true_byte) 565d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(false_byte) 566d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 567d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 568d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 569d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef StringEncoder(field_number, is_repeated, is_packed): 570d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns an encoder for a string field.""" 571d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 572d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 573d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 574d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_len = len 575d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 576d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 577d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 578d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 579d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encoded = element.encode('utf-8') 580d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag) 581d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, local_len(encoded)) 582d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(encoded) 583d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 584d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 585d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 586d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville encoded = value.encode('utf-8') 587d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag) 588d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, local_len(encoded)) 589d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(encoded) 590d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 591d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 592d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 593d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef BytesEncoder(field_number, is_repeated, is_packed): 594d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns an encoder for a bytes field.""" 595d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 596d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 597d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 598d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_len = len 599d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 600d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 601d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 602d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 603d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag) 604d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, local_len(element)) 605d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(element) 606d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 607d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 608d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 609d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag) 610d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, local_len(value)) 611d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(value) 612d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 613d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 614d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 615d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef GroupEncoder(field_number, is_repeated, is_packed): 616d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns an encoder for a group field.""" 617d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 618d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP) 619d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP) 620d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 621d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 622d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 623d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 624d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(start_tag) 625d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville element._InternalSerialize(write) 626d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(end_tag) 627d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 628d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 629d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 630d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(start_tag) 631d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value._InternalSerialize(write) 632d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(end_tag) 633d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 634d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 635d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 636d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef MessageEncoder(field_number, is_repeated, is_packed): 637d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns an encoder for a message field.""" 638d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 639d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) 640d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 641d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 642d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 643d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeRepeatedField(write, value): 644d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 645d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag) 646d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, element.ByteSize()) 647d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville element._InternalSerialize(write) 648d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeRepeatedField 649d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 650d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 651d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(tag) 652d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, value.ByteSize()) 653d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return value._InternalSerialize(write) 654d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 655d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 656d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 657d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 658d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# As before, MessageSet is special. 659d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 660d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 661d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef MessageSetItemEncoder(field_number): 662d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Encoder for extensions of MessageSet. 663d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 664d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville The message set message looks like this: 665d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message MessageSet { 666d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville repeated group Item = 1 { 667d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required int32 type_id = 2; 668d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required string message = 3; 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 670d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 671d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 672d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville start_bytes = "".join([ 673d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TagBytes(1, wire_format.WIRETYPE_START_GROUP), 674d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TagBytes(2, wire_format.WIRETYPE_VARINT), 675d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _VarintBytes(field_number), 676d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)]) 677d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP) 678d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint = _EncodeVarint 679d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 680d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def EncodeField(write, value): 681d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville write(start_bytes) 682d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_EncodeVarint(write, value.ByteSize()) 683d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value._InternalSerialize(write) 684d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return write(end_bytes) 685d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 686d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return EncodeField 687