Exemple #1
0
    def test_bitfield_invalid_deserialize(self):

        b = pycstruct.BitfieldDef()
        b.add('afield')

        buffer = bytearray(b.size() + 1)
        self.assertRaises(Exception, b.deserialize, buffer)
Exemple #2
0
    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
Exemple #3
0
    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))
Exemple #4
0
    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')
Exemple #5
0
    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
Exemple #6
0
    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)
Exemple #7
0
    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)
Exemple #8
0
    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)