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 decoding protocol buffer primitives. 32d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 33d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThis code is very similar to encoder.py -- read the docs for that module first. 34d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 35d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleA "decoder" is a function with the signature: 36d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Decode(buffer, pos, end, message, field_dict) 37d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThe arguments are: 38d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer: The string containing the encoded message. 39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos: The current position in the string. 40d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville end: The position in the string where the current message ends. May be 41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville less than len(buffer) if we're reading a sub-message. 42d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message: The message object into which we're parsing. 43d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_dict: message._fields (avoids a hashtable lookup). 44d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThe decoder reads the field and stores it into field_dict, returning the new 45d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebuffer position. A decoder for a repeated field may proactively decode all of 46d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillethe elements of that field, if they appear consecutively. 47d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 48d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleNote that decoders may throw any of the following: 49d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville IndexError: Indicates a truncated message. 50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville struct.error: Unpacking of a fixed-width field failed. 51d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message.DecodeError: Other errors. 52d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 53d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleDecoders are expected to raise an exception if they are called with pos > end. 54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThis allows callers to be lax about bounds checking: it's fineto read past 55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville"end" as long as you are sure that someone else will notice and throw an 56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleexception later on. 57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSomething up the call stack is expected to catch IndexError and struct.error 59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleand convert them to message.DecodeError. 60d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleDecoders are constructed using decoder constructors with the signature: 62d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville MakeDecoder(field_number, is_repeated, is_packed, key, new_default) 63d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThe arguments are: 64d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_number: The field number of the field we want to decode. 65d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville is_repeated: Is the field a repeated field? (bool) 66d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville is_packed: Is the field a packed field? (bool) 67d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville key: The key to use when looking up the field within field_dict. 68d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (This is actually the FieldDescriptor but nothing in this 69d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville file should depend on that.) 70d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_default: A function which takes a message object as a parameter and 71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville returns a new instance of the default value for this field. 72d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (This is called for repeated fields and sub-messages, when an 73d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville instance does not already exist.) 74d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 75d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleAs with encoders, we define a decoder constructor for every type of field. 76d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThen, for every field of every message class we construct an actual decoder. 77d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleThat decoder goes into a dict indexed by tag, so when we decode a message 78d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillewe repeatedly read a tag, look up the corresponding decoder, and invoke it. 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville""" 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville__author__ = 'kenton@google.com (Kenton Varda)' 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport struct 84d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillefrom google.protobuf.internal import encoder 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import wire_format 86d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillefrom google.protobuf import message 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# This is not for optimization, but rather to avoid conflicts with local 90d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# variables named "message". 91d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_DecodeError = message.DecodeError 92d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 93d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 94d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _VarintDecoder(mask): 95d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return an encoder for a basic varint value (does not include tag). 96d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Decoded values will be bitwise-anded with the given mask before being 98d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville returned, e.g. to limit them to 32 bits. The returned decoder does not 99d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville take the usual "end" parameter -- the caller is expected to do bounds checking 100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville after the fact (often the caller can defer such checking until later). The 101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville decoder returns a (value, new_pos) pair. 102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_ord = ord 105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeVarint(buffer, pos): 106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = 0 107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville shift = 0 108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville b = local_ord(buffer[pos]) 110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result |= ((b & 0x7f) << shift) 111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 1 112d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not (b & 0x80): 113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result &= mask 114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return (result, pos) 115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville shift += 7 116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if shift >= 64: 117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Too many bytes when decoding varint.') 118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeVarint 119d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 120d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 121d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SignedVarintDecoder(mask): 122d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Like _VarintDecoder() but decodes signed values.""" 123d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 124d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_ord = ord 125d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeVarint(buffer, pos): 126d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = 0 127d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville shift = 0 128d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville b = local_ord(buffer[pos]) 130d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result |= ((b & 0x7f) << shift) 131d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 1 132d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not (b & 0x80): 133d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if result > 0x7fffffffffffffff: 134d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result -= (1 << 64) 135d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result |= ~mask 136d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 137d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result &= mask 138d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return (result, pos) 139d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville shift += 7 140d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if shift >= 64: 141d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Too many bytes when decoding varint.') 142d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeVarint 143d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 144d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 145d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_DecodeVarint = _VarintDecoder((1 << 64) - 1) 146d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1) 147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Use these versions for values which must be limited to 32 bits. 149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_DecodeVarint32 = _VarintDecoder((1 << 32) - 1) 150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1) 151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef ReadTag(buffer, pos): 154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple. 155d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 156d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville We return the raw bytes of the tag rather than decoding them. The raw 157d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville bytes can then be used to look up the proper decoder. This effectively allows 158d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville us to trade some work that would be done in pure-python (decoding a varint) 159d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for work that is done in C (searching for a byte string in a hash table). 160d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville In a low-level language it would be much cheaper to decode the varint and 161d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville use that, but not in Python. 162d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 164d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville start = pos 165d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while ord(buffer[pos]) & 0x80: 166d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 1 167d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 1 168d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return (buffer[start:pos], pos) 169d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 170d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 171d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 172d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 173d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 174d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SimpleDecoder(wire_type, decode_value): 175d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return a constructor for a decoder for fields of a particular type. 176d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 177d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Args: 178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_type: The field's wire type. 179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville decode_value: A function which decodes an individual value, e.g. 180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _DecodeVarint() 181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default): 184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_packed: 185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_DecodeVarint = _DecodeVarint 186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodePackedField(buffer, pos, end, message, field_dict): 187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 189d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (endpoint, pos) = local_DecodeVarint(buffer, pos) 191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville endpoint += pos 192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if endpoint > end: 193d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while pos < endpoint: 195d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (element, pos) = decode_value(buffer, pos) 196d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value.append(element) 197d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > endpoint: 198d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville del value[-1] # Discard corrupt value. 199d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Packed element was truncated.') 200d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 201d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodePackedField 202d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif is_repeated: 203d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = encoder.TagBytes(field_number, wire_type) 204d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_len = len(tag_bytes) 205d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeRepeatedField(buffer, pos, end, message, field_dict): 206d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 207d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 208d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 209d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 210d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (element, new_pos) = decode_value(buffer, pos) 211d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value.append(element) 212d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Predict that the next tag is another copy of the same repeated 213d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # field. 214d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos + tag_len 215d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[new_pos:pos] != tag_bytes or new_pos >= end: 216d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Prediction failed. Return. 217d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 218d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 219d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 220d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeRepeatedField 221d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 222d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeField(buffer, pos, end, message, field_dict): 223d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (field_dict[key], pos) = decode_value(buffer, pos) 224d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > end: 225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville del field_dict[key] # Discard corrupt value. 226d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 227d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeField 229d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 230d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SpecificDecoder 231d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 232d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 233d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _ModifiedDecoder(wire_type, decode_value, modify_value): 234d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Like SimpleDecoder but additionally invokes modify_value on every value 235d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville before storing it. Usually modify_value is ZigZagDecode. 236d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 237d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 238d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but 239d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # not enough to make a significant difference. 240d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 241d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def InnerDecode(buffer, pos): 242d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (result, new_pos) = decode_value(buffer, pos) 243d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return (modify_value(result), new_pos) 244d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return _SimpleDecoder(wire_type, InnerDecode) 245d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 246d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 247d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _StructPackDecoder(wire_type, format): 248d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Return a constructor for a decoder for a fixed-width field. 249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Args: 251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_type: The field's wire type. 252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville format: The format string to pass to struct.unpack(). 253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value_size = struct.calcsize(format) 256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_unpack = struct.unpack 257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 258d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but 259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # not enough to make a significant difference. 260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Note that we expect someone up-stack to catch struct.error and convert 262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # it to _DecodeError -- this way we don't have to set up exception- 263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # handling blocks every time we parse one value. 264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 265d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def InnerDecode(buffer, pos): 266d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + value_size 267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = local_unpack(format, buffer[pos:new_pos])[0] 268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return (result, new_pos) 269d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return _SimpleDecoder(wire_type, InnerDecode) 270d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 271d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 272d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleInt32Decoder = EnumDecoder = _SimpleDecoder( 276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) 277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleInt64Decoder = _SimpleDecoder( 279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _DecodeSignedVarint) 280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleUInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) 282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleUInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint) 283d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSInt32Decoder = _ModifiedDecoder( 285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode) 286d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSInt64Decoder = _ModifiedDecoder( 287d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode) 288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 289d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Note that Python conveniently guarantees that when using the '<' prefix on 290d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# formats, they will also have the same size across all platforms (as opposed 291d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# to without the prefix, where their sizes depend on the C compiler's basic 292d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# type sizes). 293d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<I') 294d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<Q') 295d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<i') 296d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<q') 297d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleFloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<f') 298d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleDoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<d') 299d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 300d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleBoolDecoder = _ModifiedDecoder( 301d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_VARINT, _DecodeVarint, bool) 302d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 303d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 304d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef StringDecoder(field_number, is_repeated, is_packed, key, new_default): 305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a decoder for a string field.""" 306d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_DecodeVarint = _DecodeVarint 308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_unicode = unicode 309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 310d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 312d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = encoder.TagBytes(field_number, 313d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_LENGTH_DELIMITED) 314d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_len = len(tag_bytes) 315d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeRepeatedField(buffer, pos, end, message, field_dict): 316d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 317d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 318d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 319d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 320d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = local_DecodeVarint(buffer, pos) 321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + size 322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated string.') 324d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value.append(local_unicode(buffer[pos:new_pos], 'utf-8')) 325d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Predict that the next tag is another copy of the same repeated field. 326d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos + tag_len 327d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[new_pos:pos] != tag_bytes or new_pos == end: 328d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Prediction failed. Return. 329d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 330d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeRepeatedField 331d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 332d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeField(buffer, pos, end, message, field_dict): 333d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = local_DecodeVarint(buffer, pos) 334d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + size 335d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 336d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated string.') 337d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8') 338d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 339d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeField 340d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 341d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 342d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef BytesDecoder(field_number, is_repeated, is_packed, key, new_default): 343d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a decoder for a bytes field.""" 344d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 345d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_DecodeVarint = _DecodeVarint 346d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 347d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 348d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 349d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = encoder.TagBytes(field_number, 350d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_LENGTH_DELIMITED) 351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_len = len(tag_bytes) 352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeRepeatedField(buffer, pos, end, message, field_dict): 353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 355d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 356d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 357d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = local_DecodeVarint(buffer, pos) 358d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + size 359d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 360d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated string.') 361d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value.append(buffer[pos:new_pos]) 362d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Predict that the next tag is another copy of the same repeated field. 363d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos + tag_len 364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[new_pos:pos] != tag_bytes or new_pos == end: 365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Prediction failed. Return. 366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 367d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeRepeatedField 368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 369d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeField(buffer, pos, end, message, field_dict): 370d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = local_DecodeVarint(buffer, pos) 371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + size 372d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated string.') 374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_dict[key] = buffer[pos:new_pos] 375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeField 377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 379d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef GroupDecoder(field_number, is_repeated, is_packed, key, new_default): 380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a decoder for a group field.""" 381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville end_tag_bytes = encoder.TagBytes(field_number, 383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_END_GROUP) 384d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville end_tag_len = len(end_tag_bytes) 385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 386d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 387d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 388d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = encoder.TagBytes(field_number, 389d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_START_GROUP) 390d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_len = len(tag_bytes) 391d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeRepeatedField(buffer, pos, end, message, field_dict): 392d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 393d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 394d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 395d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 396d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 397d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 398d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 399d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read sub-message. 400d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = value.add()._InternalParse(buffer, pos, end) 401d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read end tag. 402d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos+end_tag_len 403d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: 404d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Missing group end tag.') 405d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Predict that the next tag is another copy of the same repeated field. 406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos + tag_len 407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[new_pos:pos] != tag_bytes or new_pos == end: 408d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Prediction failed. Return. 409d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 410d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeRepeatedField 411d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 412d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeField(buffer, pos, end, message, field_dict): 413d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 414d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 415d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 416d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read sub-message. 417d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = value._InternalParse(buffer, pos, end) 418d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read end tag. 419d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos+end_tag_len 420d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: 421d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Missing group end tag.') 422d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 423d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeField 424d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 425d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 426d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef MessageDecoder(field_number, is_repeated, is_packed, key, new_default): 427d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a decoder for a message field.""" 428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 429d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_DecodeVarint = _DecodeVarint 430d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 431d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville assert not is_packed 432d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated: 433d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = encoder.TagBytes(field_number, 434d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_format.WIRETYPE_LENGTH_DELIMITED) 435d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_len = len(tag_bytes) 436d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeRepeatedField(buffer, pos, end, message, field_dict): 437d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 438d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 439d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 440d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 441d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 442d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 443d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 444d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read length. 445d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = local_DecodeVarint(buffer, pos) 446d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + size 447d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 448d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 449d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read sub-message. 450d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value.add()._InternalParse(buffer, pos, new_pos) != new_pos: 451d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # The only reason _InternalParse would return early is if it 452d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # encountered an end-group tag. 453d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Unexpected end-group tag.') 454d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Predict that the next tag is another copy of the same repeated field. 455d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos + tag_len 456d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if buffer[new_pos:pos] != tag_bytes or new_pos == end: 457d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Prediction failed. Return. 458d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 459d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeRepeatedField 460d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 461d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeField(buffer, pos, end, message, field_dict): 462d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(key) 463d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 464d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault(key, new_default(message)) 465d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read length. 466d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = local_DecodeVarint(buffer, pos) 467d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = pos + size 468d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos > end: 469d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 470d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Read sub-message. 471d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value._InternalParse(buffer, pos, new_pos) != new_pos: 472d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # The only reason _InternalParse would return early is if it encountered 473d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # an end-group tag. 474d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Unexpected end-group tag.') 475d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return new_pos 476d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeField 477d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 478d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 479d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 480d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 481d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleMESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) 482d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 483d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef MessageSetItemDecoder(extensions_by_number): 484d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a decoder for a MessageSet item. 485d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 486d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville The parameter is the _extensions_by_number map for the message class. 487d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 488d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville The message set message looks like this: 489d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message MessageSet { 490d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville repeated group Item = 1 { 491d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required int32 type_id = 2; 492d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required string message = 3; 493d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 494d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 495d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 496d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 497d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) 498d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) 499d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) 500d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 501d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_ReadTag = ReadTag 502d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_DecodeVarint = _DecodeVarint 503d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_SkipField = SkipField 504d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 505d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def DecodeItem(buffer, pos, end, message, field_dict): 506d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville type_id = -1 507d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message_start = -1 508d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message_end = -1 509d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 510d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Technically, type_id and message can appear in any order, so we need 511d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # a little loop here. 512d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 513d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (tag_bytes, pos) = local_ReadTag(buffer, pos) 514d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if tag_bytes == type_id_tag_bytes: 515d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (type_id, pos) = local_DecodeVarint(buffer, pos) 516d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif tag_bytes == message_tag_bytes: 517d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, message_start) = local_DecodeVarint(buffer, pos) 518d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = message_end = message_start + size 519d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif tag_bytes == item_end_tag_bytes: 520d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville break 521d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 522d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = SkipField(buffer, pos, end, tag_bytes) 523d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos == -1: 524d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Missing group end tag.') 525d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 526d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > end: 527d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 528d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 529d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if type_id == -1: 530d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('MessageSet item missing type_id.') 531d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if message_start == -1: 532d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('MessageSet item missing message.') 533d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 534d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension = extensions_by_number.get(type_id) 535d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if extension is not None: 536d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.get(extension) 537d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value is None: 538d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = field_dict.setdefault( 539d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension, extension.message_type._concrete_class()) 540d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if value._InternalParse(buffer, message_start,message_end) != message_end: 541d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # The only reason _InternalParse would return early is if it encountered 542d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # an end-group tag. 543d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Unexpected end-group tag.') 544d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 545d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 546d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 547d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return DecodeItem 548d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 549d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# -------------------------------------------------------------------- 550d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# Optimization is not as heavy here because calls to SkipField() are rare, 551d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# except for handling end-group tags. 552d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 553d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SkipVarint(buffer, pos, end): 554d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skip a varint value. Returns the new position.""" 555d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 556d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while ord(buffer[pos]) & 0x80: 557d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 1 558d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 1 559d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > end: 560d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 561d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 562d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 563d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SkipFixed64(buffer, pos, end): 564d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skip a fixed64 value. Returns the new position.""" 565d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 566d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 8 567d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > end: 568d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 569d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 570d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 571d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SkipLengthDelimited(buffer, pos, end): 572d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skip a length-delimited value. Returns the new position.""" 573d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 574d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (size, pos) = _DecodeVarint(buffer, pos) 575d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += size 576d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > end: 577d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 578d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 579d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 580d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SkipGroup(buffer, pos, end): 581d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skip sub-group. Returns the new position.""" 582d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 583d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while 1: 584d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (tag_bytes, pos) = ReadTag(buffer, pos) 585d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = SkipField(buffer, pos, end, tag_bytes) 586d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos == -1: 587d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 588d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos 589d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 590d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _EndGroup(buffer, pos, end): 591d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skipping an END_GROUP tag returns -1 to tell the parent loop to break.""" 592d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 593d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return -1 594d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 595d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _SkipFixed32(buffer, pos, end): 596d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skip a fixed32 value. Returns the new position.""" 597d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 598d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos += 4 599d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if pos > end: 600d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Truncated message.') 601d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 602d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 603d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _RaiseInvalidWireType(buffer, pos, end): 604d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skip function for unknown wire types. Raises an exception.""" 605d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 606d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise _DecodeError('Tag had invalid wire type.') 607d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 608d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _FieldSkipper(): 609d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Constructs the SkipField function.""" 610d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 611d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville WIRETYPE_TO_SKIPPER = [ 612d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _SkipVarint, 613d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _SkipFixed64, 614d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _SkipLengthDelimited, 615d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _SkipGroup, 616d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _EndGroup, 617d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _SkipFixed32, 618d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _RaiseInvalidWireType, 619d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _RaiseInvalidWireType, 620d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ] 621d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 622d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wiretype_mask = wire_format.TAG_TYPE_MASK 623d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_ord = ord 624d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 625d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def SkipField(buffer, pos, end, tag_bytes): 626d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Skips a field with the specified tag. 627d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 628d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville |pos| should point to the byte immediately after the tag. 629d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 630d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Returns: 631d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville The new position (after the tag value), or -1 if the tag is an end-group 632d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag (in which case the calling loop should break). 633d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 635d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # The wire type is always in the first byte since varints are little-endian. 636d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville wire_type = local_ord(tag_bytes[0]) & wiretype_mask 637d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end) 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 639d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return SkipField 640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 641d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleSkipField = _FieldSkipper() 642