Пример #1
0
    def test_invalid_add(self):

        m = pycstruct.StructDef()

        # Invalid type
        self.assertRaises(Exception, m.add, 'invalid', 'aname')

        # Invalid length
        self.assertRaises(Exception, m.add, 'int8', 'aname', 0)

        # Invalid byteorder in member
        self.assertRaises(Exception, m.add, 'int8', 'aname', 1, 'invalid')

        # Duplicaded member
        m.add('int8', 'name1')
        self.assertRaises(Exception, m.add, 'uint8', 'name1')

        # same_level with length > 1
        self.assertRaises(Exception,
                          m.add,
                          pycstruct.StructDef(),
                          'same_level_err1',
                          length=2,
                          same_level=True)

        # same_level with non StructDef/BitfieldDef
        self.assertRaises(Exception,
                          m.add,
                          'int8',
                          'same_level_err1',
                          same_level=True)
Пример #2
0
    def test_invalid_deserialize(self):

        m = pycstruct.StructDef()
        m.add('int8', 'name1')

        buffer = bytearray(m.size() + 1)
        self.assertRaises(Exception, m.deserialize, buffer)
Пример #3
0
    def test_embedded_exception(self):
        unserializable = UnserializableDef()

        s = pycstruct.StructDef()
        s.add(unserializable, 'unserializable')

        self.assertRaises(Exception, s.deserialize, bytes([0]))
        self.assertRaises(Exception, s.serialize, {'unserializable': 'hello'})
Пример #4
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))
Пример #5
0
    def test_invalid_serialize(self):

        m = pycstruct.StructDef()
        m.add('utf-8', 'astring', length=5)

        data = {}
        data['astring'] = 5  # no valid string
        self.assertRaises(Exception, m.serialize, data)

        data['astring'] = 'too long string'
        self.assertRaises(Exception, m.serialize, data)

        m.add('int32', 'alist', length=5)
        data['astring'] = 'valid'
        data['alist'] = 3  # no valid list
        self.assertRaises(Exception, m.serialize, data)

        data['alist'] = [1, 2, 3, 4, 5, 6, 7]  # to long
        self.assertRaises(Exception, m.serialize, data)
Пример #6
0
    def create_struct(self, byteorder, alignment):
        m = pycstruct.StructDef(byteorder, alignment)

        m.add('int8', 'int8_low')
        m.add('int8', 'int8_high')
        m.add('uint8', 'uint8_low')
        m.add('uint8', 'uint8_high')
        m.add('bool8', 'bool8_false')
        m.add('bool8', 'bool8_true')

        m.add('int16', 'int16_low')
        m.add('int16', 'int16_high')
        m.add('uint16', 'uint16_low')
        m.add('uint16', 'uint16_high')
        m.add('bool16', 'bool16_false')
        m.add('bool16', 'bool16_true')

        m.add('int32', 'int32_low')
        m.add('int32', 'int32_high')
        m.add('uint32', 'uint32_low')
        m.add('uint32', 'uint32_high')
        m.add('bool32', 'bool32_false')
        m.add('bool32', 'bool32_true')
        m.add('float32', 'float32_low')
        m.add('float32', 'float32_high')

        m.add('int64', 'int64_low')
        m.add('int64', 'int64_high')
        m.add('uint64', 'uint64_low')
        m.add('uint64', 'uint64_high')
        m.add('bool64', 'bool64_false')
        m.add('bool64', 'bool64_true')
        m.add('float64', 'float64_low')
        m.add('float64', 'float64_high')

        m.add('int32', 'int32_array', length=5)

        m.add('utf-8', 'utf8_ascii', 100)
        m.add('utf-8', 'utf8_nonascii', 80)
        m.add('utf-8', 'utf8_no_term', 4)

        return m
Пример #7
0
    def test_struct_remove_to(self):

        m = pycstruct.StructDef()
        m.add('int8', 'e1')
        m.add('int8', 'e2')
        m.add('int16', 'e3')
        m.add('int16', 'e4')
        m.add('int32', 'e5')
        m.add('int32', 'e6')

        self.assertEqual(m.size(), 14)

        self.assertRaises(Exception, m.remove_to, 'invalid')

        m.remove_to('e4')
        self.assertEqual(m.size(), 8)

        d = m.create_empty_data()
        self.assertFalse('e1' in d)
        self.assertFalse('e4' in d)
        self.assertTrue('e5' in d)
        self.assertTrue('e6' in d)
Пример #8
0
    def test_union_no_pad(self):

        u = pycstruct.StructDef(union=True, default_byteorder='big')
        self.assertEqual(u._type_name(), 'union')
        u.add('uint8', 'small')
        self.assertEqual(u.size(), 1)
        u.add('uint16', 'large')
        self.assertEqual(u.size(), 2)
        u.add('uint32', 'larger')
        self.assertEqual(u.size(), 4)
        u.add('uint64', 'largest')
        self.assertEqual(u.size(), 8)

        input = {}
        input['largest'] = 0x1122334455667788

        buf = u.serialize(input)
        self.assertEqual(len(buf), 8)

        output = u.deserialize(buf)
        self.assertEqual(output['small'], 0x11)
        self.assertEqual(output['large'], 0x1122)
        self.assertEqual(output['larger'], 0x11223344)
        self.assertEqual(output['largest'], 0x1122334455667788)

        buf2 = u.serialize(output)
        output2 = u.deserialize(buf2)
        self.assertEqual(output2['largest'], 0x1122334455667788)

        del output2['largest']
        del output2['larger']

        buf3 = u.serialize(output2)
        output3 = u.deserialize(buf3)
        self.assertEqual(output3['largest'], 0x1122000000000000)
        self.assertEqual(output3['larger'], 0x11220000)
Пример #9
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
Пример #10
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)
Пример #11
0
import pycstruct

person = pycstruct.StructDef()
person.add('utf-8', 'name', length=50)
person.add('uint32', 'age')
person.add('float32', 'height')
person.add('bool8', 'is_male')
person.add('uint32', 'nbr_of_children')
person.add('uint32', 'child_ages', length=10)

f = open('simple_example.dat', 'rb')
inbytes = f.read()
result = person.deserialize(inbytes)
f.close()

print(str(result))