protolib.py revision 11828
111828Sjason@lowepower.com#!/usr/bin/env python2 210107Sradhika.jagtap@ARM.com 310107Sradhika.jagtap@ARM.com# Copyright (c) 2013 ARM Limited 410107Sradhika.jagtap@ARM.com# All rights reserved 510107Sradhika.jagtap@ARM.com# 610107Sradhika.jagtap@ARM.com# The license below extends only to copyright in the software and shall 710107Sradhika.jagtap@ARM.com# not be construed as granting a license to any other intellectual 810107Sradhika.jagtap@ARM.com# property including but not limited to intellectual property relating 910107Sradhika.jagtap@ARM.com# to a hardware implementation of the functionality of the software 1010107Sradhika.jagtap@ARM.com# licensed hereunder. You may use the software subject to the license 1110107Sradhika.jagtap@ARM.com# terms below provided that you ensure that this notice is replicated 1210107Sradhika.jagtap@ARM.com# unmodified and in its entirety in all distributions of the software, 1310107Sradhika.jagtap@ARM.com# modified or unmodified, in source code or in binary form. 1410107Sradhika.jagtap@ARM.com# 1510107Sradhika.jagtap@ARM.com# Redistribution and use in source and binary forms, with or without 1610107Sradhika.jagtap@ARM.com# modification, are permitted provided that the following conditions are 1710107Sradhika.jagtap@ARM.com# met: redistributions of source code must retain the above copyright 1810107Sradhika.jagtap@ARM.com# notice, this list of conditions and the following disclaimer; 1910107Sradhika.jagtap@ARM.com# redistributions in binary form must reproduce the above copyright 2010107Sradhika.jagtap@ARM.com# notice, this list of conditions and the following disclaimer in the 2110107Sradhika.jagtap@ARM.com# documentation and/or other materials provided with the distribution; 2210107Sradhika.jagtap@ARM.com# neither the name of the copyright holders nor the names of its 2310107Sradhika.jagtap@ARM.com# contributors may be used to endorse or promote products derived from 2410107Sradhika.jagtap@ARM.com# this software without specific prior written permission. 2510107Sradhika.jagtap@ARM.com# 2610107Sradhika.jagtap@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2710107Sradhika.jagtap@ARM.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2810107Sradhika.jagtap@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2910107Sradhika.jagtap@ARM.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3010107Sradhika.jagtap@ARM.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3110107Sradhika.jagtap@ARM.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3210107Sradhika.jagtap@ARM.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3310107Sradhika.jagtap@ARM.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3410107Sradhika.jagtap@ARM.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3510107Sradhika.jagtap@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3610107Sradhika.jagtap@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3710107Sradhika.jagtap@ARM.com# 3810107Sradhika.jagtap@ARM.com# Copyright 2008 Google Inc. All rights reserved. 3910107Sradhika.jagtap@ARM.com# http://code.google.com/p/protobuf/ 4010107Sradhika.jagtap@ARM.com# 4110107Sradhika.jagtap@ARM.com# Redistribution and use in source and binary forms, with or without 4210107Sradhika.jagtap@ARM.com# modification, are permitted provided that the following conditions are 4310107Sradhika.jagtap@ARM.com# met: 4410107Sradhika.jagtap@ARM.com# 4510107Sradhika.jagtap@ARM.com# * Redistributions of source code must retain the above copyright 4610107Sradhika.jagtap@ARM.com# notice, this list of conditions and the following disclaimer. 4710107Sradhika.jagtap@ARM.com# * Redistributions in binary form must reproduce the above 4810107Sradhika.jagtap@ARM.com# copyright notice, this list of conditions and the following disclaimer 4910107Sradhika.jagtap@ARM.com# in the documentation and/or other materials provided with the 5010107Sradhika.jagtap@ARM.com# distribution. 5110107Sradhika.jagtap@ARM.com# * Neither the name of Google Inc. nor the names of its 5210107Sradhika.jagtap@ARM.com# contributors may be used to endorse or promote products derived from 5310107Sradhika.jagtap@ARM.com# this software without specific prior written permission. 5410107Sradhika.jagtap@ARM.com# 5510107Sradhika.jagtap@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 5610107Sradhika.jagtap@ARM.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5710107Sradhika.jagtap@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 5810107Sradhika.jagtap@ARM.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 5910107Sradhika.jagtap@ARM.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 6010107Sradhika.jagtap@ARM.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 6110107Sradhika.jagtap@ARM.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 6210107Sradhika.jagtap@ARM.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 6310107Sradhika.jagtap@ARM.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 6410107Sradhika.jagtap@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 6510107Sradhika.jagtap@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6610107Sradhika.jagtap@ARM.com# 6710107Sradhika.jagtap@ARM.com# Authors: Andreas Hansson 6810107Sradhika.jagtap@ARM.com# Radhika Jagtap 6910107Sradhika.jagtap@ARM.com 7010107Sradhika.jagtap@ARM.com# This file is a library of commonly used functions used when interfacing 7110107Sradhika.jagtap@ARM.com# with protobuf python messages. For eg, the decode scripts for different 7210107Sradhika.jagtap@ARM.com# types of proto objects can use the same function to decode a single message 7310107Sradhika.jagtap@ARM.com 7410269Sradhika.jagtap@ARM.comimport gzip 7510107Sradhika.jagtap@ARM.comimport struct 7610107Sradhika.jagtap@ARM.com 7710269Sradhika.jagtap@ARM.comdef openFileRd(in_file): 7810269Sradhika.jagtap@ARM.com """ 7910269Sradhika.jagtap@ARM.com This opens the file passed as argument for reading using an appropriate 8010269Sradhika.jagtap@ARM.com function depending on if it is gzipped or not. It returns the file 8110269Sradhika.jagtap@ARM.com handle. 8210269Sradhika.jagtap@ARM.com """ 8310269Sradhika.jagtap@ARM.com try: 8410269Sradhika.jagtap@ARM.com # First see if this file is gzipped 8510269Sradhika.jagtap@ARM.com try: 8610269Sradhika.jagtap@ARM.com # Opening the file works even if it is not a gzip file 8710269Sradhika.jagtap@ARM.com proto_in = gzip.open(in_file, 'rb') 8810269Sradhika.jagtap@ARM.com 8910269Sradhika.jagtap@ARM.com # Force a check of the magic number by seeking in the 9010269Sradhika.jagtap@ARM.com # file. If we do not do it here the error will occur when 9110269Sradhika.jagtap@ARM.com # reading the first message. 9210269Sradhika.jagtap@ARM.com proto_in.seek(1) 9310269Sradhika.jagtap@ARM.com proto_in.seek(0) 9410269Sradhika.jagtap@ARM.com except IOError: 9510269Sradhika.jagtap@ARM.com proto_in = open(in_file, 'rb') 9610269Sradhika.jagtap@ARM.com except IOError: 9710269Sradhika.jagtap@ARM.com print "Failed to open ", in_file, " for reading" 9810269Sradhika.jagtap@ARM.com exit(-1) 9910269Sradhika.jagtap@ARM.com return proto_in 10010269Sradhika.jagtap@ARM.com 10110107Sradhika.jagtap@ARM.comdef DecodeVarint(in_file): 10210107Sradhika.jagtap@ARM.com """ 10310107Sradhika.jagtap@ARM.com The decoding of the Varint32 is copied from 10410107Sradhika.jagtap@ARM.com google.protobuf.internal.decoder and is only repeated here to 10510107Sradhika.jagtap@ARM.com avoid depending on the internal functions in the library. If the 10610107Sradhika.jagtap@ARM.com end of file is reached, return (0, 0). 10710107Sradhika.jagtap@ARM.com """ 10810107Sradhika.jagtap@ARM.com result = 0 10910107Sradhika.jagtap@ARM.com shift = 0 11010107Sradhika.jagtap@ARM.com pos = 0 11110107Sradhika.jagtap@ARM.com # Use a 32-bit mask 11210107Sradhika.jagtap@ARM.com mask = 0xffffffff 11310107Sradhika.jagtap@ARM.com while 1: 11410107Sradhika.jagtap@ARM.com c = in_file.read(1) 11510107Sradhika.jagtap@ARM.com if len(c) == 0: 11610107Sradhika.jagtap@ARM.com return (0, 0) 11710107Sradhika.jagtap@ARM.com b = struct.unpack('<B', c)[0] 11810107Sradhika.jagtap@ARM.com result |= ((b & 0x7f) << shift) 11910107Sradhika.jagtap@ARM.com pos += 1 12010107Sradhika.jagtap@ARM.com if not (b & 0x80): 12110107Sradhika.jagtap@ARM.com if result > 0x7fffffffffffffff: 12210107Sradhika.jagtap@ARM.com result -= (1 << 64) 12310107Sradhika.jagtap@ARM.com result |= ~mask 12410107Sradhika.jagtap@ARM.com else: 12510107Sradhika.jagtap@ARM.com result &= mask 12610107Sradhika.jagtap@ARM.com return (result, pos) 12710107Sradhika.jagtap@ARM.com shift += 7 12810107Sradhika.jagtap@ARM.com if shift >= 64: 12910107Sradhika.jagtap@ARM.com raise IOError('Too many bytes when decoding varint.') 13010107Sradhika.jagtap@ARM.com 13110107Sradhika.jagtap@ARM.comdef decodeMessage(in_file, message): 13210107Sradhika.jagtap@ARM.com """ 13310107Sradhika.jagtap@ARM.com Attempt to read a message from the file and decode it. Return 13410107Sradhika.jagtap@ARM.com False if no message could be read. 13510107Sradhika.jagtap@ARM.com """ 13610107Sradhika.jagtap@ARM.com try: 13710107Sradhika.jagtap@ARM.com size, pos = DecodeVarint(in_file) 13810107Sradhika.jagtap@ARM.com if size == 0: 13910107Sradhika.jagtap@ARM.com return False 14010107Sradhika.jagtap@ARM.com buf = in_file.read(size) 14110107Sradhika.jagtap@ARM.com message.ParseFromString(buf) 14210107Sradhika.jagtap@ARM.com return True 14310107Sradhika.jagtap@ARM.com except IOError: 14410107Sradhika.jagtap@ARM.com return False 14510107Sradhika.jagtap@ARM.com 14610107Sradhika.jagtap@ARM.comdef EncodeVarint(out_file, value): 14710107Sradhika.jagtap@ARM.com """ 14810107Sradhika.jagtap@ARM.com The encoding of the Varint32 is copied from 14910107Sradhika.jagtap@ARM.com google.protobuf.internal.encoder and is only repeated here to 15010107Sradhika.jagtap@ARM.com avoid depending on the internal functions in the library. 15110107Sradhika.jagtap@ARM.com """ 15210107Sradhika.jagtap@ARM.com bits = value & 0x7f 15310107Sradhika.jagtap@ARM.com value >>= 7 15410107Sradhika.jagtap@ARM.com while value: 15510107Sradhika.jagtap@ARM.com out_file.write(struct.pack('<B', 0x80|bits)) 15610107Sradhika.jagtap@ARM.com bits = value & 0x7f 15710107Sradhika.jagtap@ARM.com value >>= 7 15810107Sradhika.jagtap@ARM.com out_file.write(struct.pack('<B', bits)) 15910107Sradhika.jagtap@ARM.com 16010107Sradhika.jagtap@ARM.comdef encodeMessage(out_file, message): 16110107Sradhika.jagtap@ARM.com """ 16210107Sradhika.jagtap@ARM.com Encoded a message with the length prepended as a 32-bit varint. 16310107Sradhika.jagtap@ARM.com """ 16410107Sradhika.jagtap@ARM.com out = message.SerializeToString() 16510107Sradhika.jagtap@ARM.com EncodeVarint(out_file, len(out)) 16610107Sradhika.jagtap@ARM.com out_file.write(out) 167