protolib.py revision 10269:82773ace39fa
110779SCurtis.Dunham@arm.com#!/usr/bin/env python 210779SCurtis.Dunham@arm.com 310779SCurtis.Dunham@arm.com# Copyright (c) 2013 ARM Limited 410779SCurtis.Dunham@arm.com# All rights reserved 510779SCurtis.Dunham@arm.com# 610779SCurtis.Dunham@arm.com# The license below extends only to copyright in the software and shall 710779SCurtis.Dunham@arm.com# not be construed as granting a license to any other intellectual 810779SCurtis.Dunham@arm.com# property including but not limited to intellectual property relating 910779SCurtis.Dunham@arm.com# to a hardware implementation of the functionality of the software 1010779SCurtis.Dunham@arm.com# licensed hereunder. You may use the software subject to the license 1110779SCurtis.Dunham@arm.com# terms below provided that you ensure that this notice is replicated 1210779SCurtis.Dunham@arm.com# unmodified and in its entirety in all distributions of the software, 1310779SCurtis.Dunham@arm.com# modified or unmodified, in source code or in binary form. 1410779SCurtis.Dunham@arm.com# 1510779SCurtis.Dunham@arm.com# Redistribution and use in source and binary forms, with or without 1610779SCurtis.Dunham@arm.com# modification, are permitted provided that the following conditions are 1710779SCurtis.Dunham@arm.com# met: redistributions of source code must retain the above copyright 1810779SCurtis.Dunham@arm.com# notice, this list of conditions and the following disclaimer; 1910779SCurtis.Dunham@arm.com# redistributions in binary form must reproduce the above copyright 2010779SCurtis.Dunham@arm.com# notice, this list of conditions and the following disclaimer in the 2110779SCurtis.Dunham@arm.com# documentation and/or other materials provided with the distribution; 2210779SCurtis.Dunham@arm.com# neither the name of the copyright holders nor the names of its 2310779SCurtis.Dunham@arm.com# contributors may be used to endorse or promote products derived from 2410779SCurtis.Dunham@arm.com# this software without specific prior written permission. 2510779SCurtis.Dunham@arm.com# 2610779SCurtis.Dunham@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2710779SCurtis.Dunham@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2810779SCurtis.Dunham@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2910779SCurtis.Dunham@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3010779SCurtis.Dunham@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3110779SCurtis.Dunham@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3210779SCurtis.Dunham@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3310779SCurtis.Dunham@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3410779SCurtis.Dunham@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3510779SCurtis.Dunham@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3610779SCurtis.Dunham@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3710779SCurtis.Dunham@arm.com# 3810779SCurtis.Dunham@arm.com# Copyright 2008 Google Inc. All rights reserved. 3910779SCurtis.Dunham@arm.com# http://code.google.com/p/protobuf/ 4010779SCurtis.Dunham@arm.com# 4110779SCurtis.Dunham@arm.com# Redistribution and use in source and binary forms, with or without 4210779SCurtis.Dunham@arm.com# modification, are permitted provided that the following conditions are 4310779SCurtis.Dunham@arm.com# met: 4410779SCurtis.Dunham@arm.com# 4510779SCurtis.Dunham@arm.com# * Redistributions of source code must retain the above copyright 4610779SCurtis.Dunham@arm.com# notice, this list of conditions and the following disclaimer. 4710779SCurtis.Dunham@arm.com# * Redistributions in binary form must reproduce the above 4810779SCurtis.Dunham@arm.com# copyright notice, this list of conditions and the following disclaimer 4910779SCurtis.Dunham@arm.com# in the documentation and/or other materials provided with the 5010779SCurtis.Dunham@arm.com# distribution. 5110779SCurtis.Dunham@arm.com# * Neither the name of Google Inc. nor the names of its 5210779SCurtis.Dunham@arm.com# contributors may be used to endorse or promote products derived from 5310779SCurtis.Dunham@arm.com# this software without specific prior written permission. 5410779SCurtis.Dunham@arm.com# 5510779SCurtis.Dunham@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 5610779SCurtis.Dunham@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5710779SCurtis.Dunham@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 5810779SCurtis.Dunham@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 5910779SCurtis.Dunham@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 6010779SCurtis.Dunham@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 6110779SCurtis.Dunham@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 6210779SCurtis.Dunham@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 6310779SCurtis.Dunham@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 6410779SCurtis.Dunham@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 6510779SCurtis.Dunham@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6610779SCurtis.Dunham@arm.com# 6710779SCurtis.Dunham@arm.com# Authors: Andreas Hansson 6810779SCurtis.Dunham@arm.com# Radhika Jagtap 6910779SCurtis.Dunham@arm.com 7010779SCurtis.Dunham@arm.com# This file is a library of commonly used functions used when interfacing 7110779SCurtis.Dunham@arm.com# with protobuf python messages. For eg, the decode scripts for different 7210779SCurtis.Dunham@arm.com# types of proto objects can use the same function to decode a single message 7310779SCurtis.Dunham@arm.com 7410779SCurtis.Dunham@arm.comimport gzip 7510779SCurtis.Dunham@arm.comimport struct 7610779SCurtis.Dunham@arm.com 7710779SCurtis.Dunham@arm.comdef openFileRd(in_file): 7810779SCurtis.Dunham@arm.com """ 7910779SCurtis.Dunham@arm.com This opens the file passed as argument for reading using an appropriate 8010779SCurtis.Dunham@arm.com function depending on if it is gzipped or not. It returns the file 8110779SCurtis.Dunham@arm.com handle. 8210779SCurtis.Dunham@arm.com """ 8310779SCurtis.Dunham@arm.com try: 8410779SCurtis.Dunham@arm.com # First see if this file is gzipped 8510779SCurtis.Dunham@arm.com try: 8610779SCurtis.Dunham@arm.com # Opening the file works even if it is not a gzip file 8710779SCurtis.Dunham@arm.com proto_in = gzip.open(in_file, 'rb') 8810779SCurtis.Dunham@arm.com 8910779SCurtis.Dunham@arm.com # Force a check of the magic number by seeking in the 9010779SCurtis.Dunham@arm.com # file. If we do not do it here the error will occur when 9110779SCurtis.Dunham@arm.com # reading the first message. 9210779SCurtis.Dunham@arm.com proto_in.seek(1) 9310779SCurtis.Dunham@arm.com proto_in.seek(0) 9410779SCurtis.Dunham@arm.com except IOError: 9510779SCurtis.Dunham@arm.com proto_in = open(in_file, 'rb') 9610779SCurtis.Dunham@arm.com except IOError: 9710779SCurtis.Dunham@arm.com print "Failed to open ", in_file, " for reading" 9810779SCurtis.Dunham@arm.com exit(-1) 9910779SCurtis.Dunham@arm.com return proto_in 10010779SCurtis.Dunham@arm.com 10110779SCurtis.Dunham@arm.comdef DecodeVarint(in_file): 10210779SCurtis.Dunham@arm.com """ 10310779SCurtis.Dunham@arm.com The decoding of the Varint32 is copied from 10410779SCurtis.Dunham@arm.com google.protobuf.internal.decoder and is only repeated here to 10510779SCurtis.Dunham@arm.com avoid depending on the internal functions in the library. If the 10610779SCurtis.Dunham@arm.com end of file is reached, return (0, 0). 10710779SCurtis.Dunham@arm.com """ 10810779SCurtis.Dunham@arm.com result = 0 10910779SCurtis.Dunham@arm.com shift = 0 11010779SCurtis.Dunham@arm.com pos = 0 11110779SCurtis.Dunham@arm.com # Use a 32-bit mask 11210779SCurtis.Dunham@arm.com mask = 0xffffffff 11310779SCurtis.Dunham@arm.com while 1: 11410779SCurtis.Dunham@arm.com c = in_file.read(1) 11510779SCurtis.Dunham@arm.com if len(c) == 0: 11610779SCurtis.Dunham@arm.com return (0, 0) 11710779SCurtis.Dunham@arm.com b = struct.unpack('<B', c)[0] 11810779SCurtis.Dunham@arm.com result |= ((b & 0x7f) << shift) 11910779SCurtis.Dunham@arm.com pos += 1 12010779SCurtis.Dunham@arm.com if not (b & 0x80): 12110779SCurtis.Dunham@arm.com if result > 0x7fffffffffffffff: 12210779SCurtis.Dunham@arm.com result -= (1 << 64) 12310779SCurtis.Dunham@arm.com result |= ~mask 12410779SCurtis.Dunham@arm.com else: 12510779SCurtis.Dunham@arm.com result &= mask 12610779SCurtis.Dunham@arm.com return (result, pos) 12710779SCurtis.Dunham@arm.com shift += 7 12810779SCurtis.Dunham@arm.com if shift >= 64: 12910779SCurtis.Dunham@arm.com raise IOError('Too many bytes when decoding varint.') 13010779SCurtis.Dunham@arm.com 13110779SCurtis.Dunham@arm.comdef decodeMessage(in_file, message): 13210779SCurtis.Dunham@arm.com """ 13310779SCurtis.Dunham@arm.com Attempt to read a message from the file and decode it. Return 13410779SCurtis.Dunham@arm.com False if no message could be read. 13510779SCurtis.Dunham@arm.com """ 13610779SCurtis.Dunham@arm.com try: 13710779SCurtis.Dunham@arm.com size, pos = DecodeVarint(in_file) 13810779SCurtis.Dunham@arm.com if size == 0: 13910779SCurtis.Dunham@arm.com return False 14010779SCurtis.Dunham@arm.com buf = in_file.read(size) 14110779SCurtis.Dunham@arm.com message.ParseFromString(buf) 14210779SCurtis.Dunham@arm.com return True 14310779SCurtis.Dunham@arm.com except IOError: 14410779SCurtis.Dunham@arm.com return False 14510779SCurtis.Dunham@arm.com 14610779SCurtis.Dunham@arm.comdef EncodeVarint(out_file, value): 14710779SCurtis.Dunham@arm.com """ 14810779SCurtis.Dunham@arm.com The encoding of the Varint32 is copied from 14910779SCurtis.Dunham@arm.com google.protobuf.internal.encoder and is only repeated here to 15010779SCurtis.Dunham@arm.com avoid depending on the internal functions in the library. 15110779SCurtis.Dunham@arm.com """ 15210779SCurtis.Dunham@arm.com bits = value & 0x7f 15310779SCurtis.Dunham@arm.com value >>= 7 15410779SCurtis.Dunham@arm.com while value: 15510779SCurtis.Dunham@arm.com out_file.write(struct.pack('<B', 0x80|bits)) 15610779SCurtis.Dunham@arm.com bits = value & 0x7f 15710779SCurtis.Dunham@arm.com value >>= 7 15810779SCurtis.Dunham@arm.com out_file.write(struct.pack('<B', bits)) 15910779SCurtis.Dunham@arm.com 16010779SCurtis.Dunham@arm.comdef encodeMessage(out_file, message): 16110779SCurtis.Dunham@arm.com """ 16210779SCurtis.Dunham@arm.com Encoded a message with the length prepended as a 32-bit varint. 16310779SCurtis.Dunham@arm.com """ 16410779SCurtis.Dunham@arm.com out = message.SerializeToString() 16510779SCurtis.Dunham@arm.com EncodeVarint(out_file, len(out)) 16610779SCurtis.Dunham@arm.com out_file.write(out) 16710779SCurtis.Dunham@arm.com