def test_bitfield_invalid_deserialize(self): b = pycstruct.BitfieldDef() b.add('afield') buffer = bytearray(b.size() + 1) self.assertRaises(Exception, b.deserialize, buffer)
def create_bitfield(self, byteorder): b = pycstruct.BitfieldDef(byteorder) b.add("onebit", 1, signed=False) b.add("twobits", 2, signed=False) b.add("threebits", 3, signed=False) b.add("fourbits", 4, signed=False) b.add("fivesignedbits", 5, signed=True) b.add("eightbits", 8, signed=False) b.add("eightsignedbits", 8, signed=True) b.add("onesignedbit", 1, signed=True) b.add("foursignedbits", 4, signed=True) b.add("sixteensignedbits", 16, signed=True) b.add("fivebits", 5, signed=False) return b
def test_embedded_same_level(self): substruct = pycstruct.StructDef() substruct.add('uint8', 'ss1') substruct.add('int16', 'ss2') substruct.add('uint32', 'ss3') bitfield = pycstruct.BitfieldDef() bitfield.add('bf1', 3) bitfield.add('bf2', 1) bitfield.add('bf3', 4) parentstruct = pycstruct.StructDef() parentstruct.add('uint16', 'ps1') parentstruct.add('uint32', 'ps2') parentstruct.add(substruct, 'ps3', same_level=True) parentstruct.add(bitfield, 'ps4', same_level=True) parentstruct.add('int8', 'ps5') mydict = { 'ss1': 1, 'ss2': -1234, 'ss3': 123456, 'bf1': 5, 'bf2': 0, 'bf3': 11, 'ps1': 789, 'ps2': 91011, 'ps3': 1213, # Should be ignored 'ps5': -100 } databin = parentstruct.serialize(mydict) mydict2 = parentstruct.deserialize(databin) # Check for key, value in mydict.items(): if key != 'ps3': self.assertEqual(value, mydict2[key], msg='Key {0}'.format(key))
def test_bitfield_add(self): bitfield = pycstruct.BitfieldDef() self.assertEqual(bitfield.assigned_bits(), 0) self.assertEqual(bitfield.size(), 0) bitfield.add("one_bit") self.assertEqual(bitfield.assigned_bits(), 1) bitfield.add("two_bits", 2) bitfield.add("three_bits", 3) bitfield.add("two_bits_signed", 2, signed=True) self.assertEqual(bitfield.assigned_bits(), 8) self.assertEqual(bitfield.size(), 1) bitfield.add("one_more_bit") self.assertEqual(bitfield.assigned_bits(), 9) self.assertEqual(bitfield.size(), 2) bitfield.add("seven_bits", 7) self.assertEqual(bitfield.assigned_bits(), 16) self.assertEqual(bitfield.size(), 2) bitfield.add("three_bits_signed", 3, signed=True) self.assertEqual(bitfield.assigned_bits(), 19) self.assertEqual(bitfield.size(), 3) bitfield.add("32_bits", 32) self.assertEqual(bitfield.assigned_bits(), 51) self.assertEqual(bitfield.size(), 7) bitfield.add("13_signed_bits", 13, signed=True) self.assertEqual(bitfield.assigned_bits(), 64) self.assertEqual(bitfield.size(), 8) # Should overflow self.assertRaises(Exception, bitfield.add, 'this_wont_fit_in_64_bits') # Same bit field name again - forbidden self.assertRaises(Exception, bitfield.add, 'three_bits')
def _to_instance(self, name): ''' Create a pycstruct instance of type with name. Will recursively create instances of referenced types. Returns the instance. ''' if name in self._instances: return self._instances[name] # Parsed before meta = self._type_meta[name] if meta['supported'] == False: return None # Not supported instance = None # Structs or union if meta['type'] == 'struct' or meta['type'] == 'union': is_union = meta['type'] == 'union' instance = pycstruct.StructDef(self._byteorder, meta['align'], union=is_union) for member in meta['members']: if 'reference' in member: other_instance = self._to_instance(member['reference']) if other_instance == None: raise Exception( 'Member {} is of type {} {} that is not supported'. format(member['name'], member['type'], member['reference'])) same_level = False if ('same_level' in member) and (member['same_level'] == True): same_level = True instance.add(other_instance, member['name'], member['length'], same_level=same_level) else: instance.add(member['type'], member['name'], member['length']) # Enum elif meta['type'] == 'enum': instance = pycstruct.EnumDef(self._byteorder, meta['size'], meta['signed']) for member in meta['members']: instance.add(member['name'], member['value']) # Bitfield elif meta['type'] == 'bitfield': instance = pycstruct.BitfieldDef(self._byteorder, meta['size']) for member in meta['members']: instance.add(member['name'], member['bits'], member['signed']) # Not supported else: logger.warning( 'Unable to create instance for {} (type {}). Not supported.'. format(meta['name'], meta['type'])) meta['supported'] = False return None # Sanity check size: if meta['size'] != instance.size(): logger.warning( '{0} size, {1}, does match indicated size {2}'.format( meta['name'], instance.size(), meta['size'])) self._instances[name] = instance return instance
def test_bitfield_setsubvalue(self): bitstruct = pycstruct.BitfieldDef() # Unsigned tests self.assertEqual( bin( bitstruct._set_subvalue(0, 1, nbr_of_bits=1, start_bit=0, signed=False)), '0b1') self.assertEqual( bin( bitstruct._set_subvalue(0, 1, nbr_of_bits=1, start_bit=2, signed=False)), '0b100') self.assertEqual( bin( bitstruct._set_subvalue(0, 5, nbr_of_bits=3, start_bit=5, signed=False)), '0b10100000') value = int('010100001111', 2) self.assertEqual( bin( bitstruct._set_subvalue(value, 15, nbr_of_bits=4, start_bit=4, signed=False)), '0b10111111111') # Signed tests value = 0 self.assertEqual( bin( bitstruct._set_subvalue(0, -1, nbr_of_bits=1, start_bit=0, signed=True)), '0b1') self.assertEqual( bin( bitstruct._set_subvalue(0, -1, nbr_of_bits=1, start_bit=2, signed=True)), '0b100') self.assertEqual( bin( bitstruct._set_subvalue(0, -5, nbr_of_bits=4, start_bit=5, signed=True)), '0b101100000') self.assertEqual( bin( bitstruct._set_subvalue(0, 5, nbr_of_bits=4, start_bit=5, signed=True)), '0b10100000') # Invalid values self.assertRaises(Exception, bitstruct._set_subvalue, 0, -1, 1, 0, False) self.assertRaises(Exception, bitstruct._set_subvalue, 0, 2, 1, 0, False) self.assertRaises(Exception, bitstruct._set_subvalue, 0, 8, 3, 0, False) self.assertRaises(Exception, bitstruct._set_subvalue, 0, -2, 1, 0, True) self.assertRaises(Exception, bitstruct._set_subvalue, 0, 2, 1, 0, True) self.assertRaises(Exception, bitstruct._set_subvalue, 0, 7, 3, 0, True)
def test_bitfield_getsubvalue(self): bitstruct = pycstruct.BitfieldDef() value = int('0101110001010011', 2) # Unsigned tests self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=1, start_bit=0, signed=False), 1) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=4, start_bit=0, signed=False), 3) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=16, start_bit=0, signed=False), 23635) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=15, start_bit=0, signed=False), 23635) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=14, start_bit=2, signed=False), 5908) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=3, start_bit=4, signed=False), 5) # Signed tests self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=1, start_bit=0, signed=True), -1) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=4, start_bit=0, signed=True), 3) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=16, start_bit=0, signed=True), 23635) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=15, start_bit=0, signed=True), -9133) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=14, start_bit=2, signed=True), 5908) self.assertEqual( bitstruct._get_subvalue(value, nbr_of_bits=3, start_bit=4, signed=True), -3)
def embedded_struct(self, filename, alignment=1): car_type = pycstruct.EnumDef(size=4) car_type.add('Sedan', 0) car_type.add('Station_Wagon', 5) car_type.add('Bus', 7) car_type.add('Pickup', 12) sedan_properties = pycstruct.StructDef(alignment=alignment) sedan_properties.add('uint16', 'sedan_code') station_wagon_properties = pycstruct.StructDef(alignment=alignment) station_wagon_properties.add('int32', 'trunk_volume') bus_properties = pycstruct.StructDef(alignment=alignment) bus_properties.add('int32', 'number_of_passangers') bus_properties.add('uint16', 'number_of_entries') bus_properties.add('bool8', 'is_accordion_bus') pickup_properties = pycstruct.StructDef(alignment=alignment) pickup_properties.add('int32', 'truck_bed_volume') type_specific_properties = pycstruct.StructDef(alignment=alignment, union=True) type_specific_properties.add(sedan_properties, 'sedan') type_specific_properties.add(station_wagon_properties, 'station_wagon') type_specific_properties.add(bus_properties, 'bus') type_specific_properties.add(pickup_properties, 'pickup') # gcc is setting the size of car_properties_s to # 4 bytes when no packing is added of some strange # reason. size = 1 if alignment > 1: size = 4 car_properties = pycstruct.BitfieldDef(size=size) car_properties.add('env_class', 3) car_properties.add('registered', 1) car_properties.add('over_3500_kg', 1) car = pycstruct.StructDef(alignment=alignment) car.add('uint16', 'year') car.add('utf-8', 'model', length=50) car.add('utf-8', 'registration_number', length=10) car.add(car_properties, 'properties') car.add(car_type, 'type') car.add(type_specific_properties, 'type_properties') garage = pycstruct.StructDef(alignment=alignment) garage.add(car, 'cars', length=20) garage.add('uint8', 'nbr_registered_parkings') house = pycstruct.StructDef(alignment=alignment) house.add('uint8', 'nbr_of_levels') house.add(garage, 'garage') ############################################# # Test to string method stringrep = str(car) self.assertTrue('model' in stringrep) stringrep = str(garage) self.assertTrue('nbr_registered_parkings' in stringrep) stringrep = str(house) self.assertTrue('nbr_of_levels' in stringrep) ############################################# # Load pre-stored binary data and deserialize and check check_embedded_struct(self, house, filename)