示例#1
0
    def __init__(self, name, lengthfield, wordsize = 1):
        '''
        Initialize the field with the given *name* and a
        *lengthfield*. The *lengthfield* must be a numeric field
        instance. *wordsize* specifies how many bytes a word contains
        and it can be a numeric value or a unary function that knows
        where to get the word size, it has a default value of 1. So, the
        total length in bytes of a :mod:`Data` field is the length field
        multiplied by the word size. If *wordsize* is a function, it
        takes the top-level root :mod:`Container` field as a single
        argument. This way, it is possible to provide a word size that
        depends on the value of another field.
        '''
        Structure.__init__(self, name)
        self.__wordsize = wordsize

        wsizefunc = lambda root: \
            lengthfield.value() * param_call(wordsize, root)

        self.__length = lengthfield
        self.__data = String("Data", wsizefunc)

        Structure.append(self, self.__length)
        Structure.append(self, self.__data)
示例#2
0
class Data(Structure):
    '''
    This class lets you store strings of characters (divided by words)
    and also provides a field to hold its length. It is a
    :mod:`Structure` with two fields: length and data (internally
    created with name *Data*). The length is a numeric field and
    specifies how many words the *Data* field contains. The *Data* field
    is internally a :class:`String`.
    '''

    def __init__(self, name, lengthfield, wordsize = 1):
        '''
        Initialize the field with the given *name* and a
        *lengthfield*. The *lengthfield* must be a numeric field
        instance. *wordsize* specifies how many bytes a word contains
        and it can be a numeric value or a unary function that knows
        where to get the word size, it has a default value of 1. So, the
        total length in bytes of a :mod:`Data` field is the length field
        multiplied by the word size. If *wordsize* is a function, it
        takes the top-level root :mod:`Container` field as a single
        argument. This way, it is possible to provide a word size that
        depends on the value of another field.
        '''
        Structure.__init__(self, name)
        self.__wordsize = wordsize

        wsizefunc = lambda root: \
            lengthfield.value() * param_call(wordsize, root)

        self.__length = lengthfield
        self.__data = String("Data", wsizefunc)

        Structure.append(self, self.__length)
        Structure.append(self, self.__data)

    def value(self):
        '''
        Returns the value of the *Data* field as a string.
        '''
        return self.__data.value()

    def set_value(self, value):
        '''
        Sets a new string to the *Data* field. The given string length
        must be a mutliple of the word size and must fit in the length
        field (i.e. 300 characters are too long if the length field is
        :class:`UInt8`, as only 255 characters fit), otherwise a
        *ValueError* exception will be raised.
        '''
        length = len(value)
        wordsize = param_call(self.__wordsize, self.root())
        if (length % wordsize) == 0:
            try:
                self.__length.set_value(length / wordsize)
            except:
                raise ValueError("Data length must be lower than length "
                                 "field maximum size (%d given)" % length)

            self.__data.set_value(value)
        else:
            raise ValueError("Data length must be a multiple of %d (%d given)" \
                                 % (wordsize, length))