def test_enum_invalid_deserialize(self): e = pycstruct.EnumDef() e.add('zero') buffer = bytearray(e.size() + 1) self.assertRaises(Exception, e.deserialize, buffer)
def test_enum_fixed_unsigned(self): e = pycstruct.EnumDef(size=4, signed=False) self.assertEqual(e.size(), 4) e.add("first") self.assertEqual(e.get_value("first"), 0) self.assertEqual(e.get_name(0), "first") self.assertEqual(e.size(), 4) e.add("largest", 0xFFFFFFFF) self.assertEqual(e.size(), 4) # Add a too large number self.assertRaises(Exception, e.add, "too_large", 0xFFFFFFFF + 1) # Add negative number to unsigned self.assertRaises(Exception, e.add, "negative", -1)
def test_enum_fixed_signed(self): e = pycstruct.EnumDef(size=4, signed=True) self.assertEqual(e.size(), 4) e.add("first") self.assertEqual(e.get_value("first"), 0) self.assertEqual(e.get_name(0), "first") self.assertEqual(e.size(), 4) e.add("negative", -1) self.assertEqual(e.size(), 4) e.add("largest_negative", 0x7FFFFFFF * -1 - 1) self.assertEqual(e.size(), 4) # Add too small value self.assertRaises(Exception, e.add, "too_small", 0x7FFFFFFF * -1 - 2) e.add("largest_positive", 0x7FFFFFFF) self.assertEqual(e.size(), 4) # Add too large value self.assertRaises(Exception, e.add, "too_large", 0x7FFFFFFF + 1)
def test_enum_add(self): e = pycstruct.EnumDef() self.assertEqual(e.size(), 1) e.add("first") self.assertEqual(e.get_value("first"), 0) self.assertEqual(e.get_name(0), "first") self.assertEqual(e.size(), 1) e.add("second", 1) self.assertEqual(e.get_value("second"), 1) self.assertEqual(e.get_name(1), "second") self.assertEqual(e.size(), 1) e.add("fitbyte", 127) self.assertEqual(e.get_value("fitbyte"), 127) self.assertEqual(e.get_name(127), "fitbyte") self.assertEqual(e.size(), 1) e.add("third") self.assertEqual(e.get_value("third"), 2) self.assertEqual(e.get_name(2), "third") self.assertEqual(e.size(), 1) # Duplicate self.assertRaises(Exception, e.add, "second") # > 64 bits self.assertRaises(Exception, e.add, "too_big", 12345678901234561234567) # Get invalid value self.assertRaises(Exception, e.get_value, 33) # Get invalid name self.assertRaises(Exception, e.get_name, "invalid")
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_enum_serialize_deserialize(self): e = pycstruct.EnumDef(size=1) e.add("zero", 0) e.add("one", 1) e.add("two", 2) e.add("three", 2) value = "two" buf = e.serialize(value) self.assertEqual(len(buf), 1) self.assertEqual(buf[0], 2) big = pycstruct.EnumDef('big', size=2) big.add("twofiftysix", 256) value = "twofiftysix" buf = big.serialize(value) self.assertEqual(len(buf), 2) self.assertEqual(buf[0], 1) self.assertEqual(buf[1], 0) outval = big.deserialize(buf) self.assertEqual(outval, "twofiftysix") little = pycstruct.EnumDef('little', size=2) value = "twofiftysix" little.add(value, 256) buf = little.serialize(value) self.assertEqual(len(buf), 2) self.assertEqual(buf[0], 0) self.assertEqual(buf[1], 1) outval = little.deserialize(buf) self.assertEqual(outval, value) value = "largest_uint16" little.add(value, 0xFFFF) buf = little.serialize(value) self.assertEqual(len(buf), 2) self.assertEqual(buf[0], 0xFF) self.assertEqual(buf[1], 0xFF) outval = little.deserialize(buf) self.assertEqual(outval, value) little_signed = pycstruct.EnumDef('little', size=2, signed=True) value = "largest_int16" little_signed.add(value, 32767) buf = little_signed.serialize(value) self.assertEqual(len(buf), 2) self.assertEqual(buf[0], 0xFF) self.assertEqual(buf[1], 0x7F) outval = little_signed.deserialize(buf) self.assertEqual(outval, value) value = "smallest_int16" little_signed.add(value, -32768) buf = little_signed.serialize(value) self.assertEqual(len(buf), 2) self.assertEqual(buf[0], 0x00) self.assertEqual(buf[1], 0x80) outval = little_signed.deserialize(buf) self.assertEqual(outval, value) # Unassigned values outval = little_signed.deserialize(bytes([0, 0])) self.assertEqual(outval, '__VALUE__0') outval = little_signed.deserialize(bytes([99, 0])) self.assertEqual(outval, '__VALUE__99') outval = little_signed.deserialize(bytes([0xFC, 0xFF])) self.assertEqual(outval, '__VALUE__-4') # Test to string method stringrep = str(e) self.assertTrue('zero' in stringrep) self.assertTrue('three' in stringrep)
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)