def __setitem__(self, name, value): ''' Sets the given *value* to the field identified by *name*. Note that *name* will contain the array index before the first FIELD_SEPARATOR (if any)nnn . If names[0] (i.e. the index) does not exists in the array, a new field will be automatically created (only if the index is consecutive to the length of the array). ''' names = name.split(FIELD_SEPARATOR, 1) length = self.__length.value() if int(names[0]) < length: # Normal access pass elif int(names[0]) == length: new_field = self.__fieldtype(self.root()) new_field._set_name("%d" % length) Structure.append(self, new_field) self.__length.set_value(length + 1) else: # int(names[0]) > length raise IndexError("Index %s must be <= %s" % (names[0], length)) Structure.__setitem__(self, name, value)
def __setitem__(self, name, value): ''' Sets the given *value* to the field identified by *name*. Note that *name* will contain the array index before the first FIELD_SEPARATOR (if any)nnn . If names[0] (i.e. the index) does not exists in the array, a new field will be automatically created (only if the index is consecutive to the length of the array). ''' names = name.split(FIELD_SEPARATOR, 1) length = self.__length.value() if int(names[0]) < length: # Normal access pass elif int(names[0]) == length: new_field = self.__fieldtype(self.root()) new_field._set_name("%d" % length) Structure.append(self, new_field) self.__length.set_value (length + 1) else: # int(names[0]) > length raise IndexError("Index %s must be <= %s" % (names[0], length)) Structure.__setitem__(self, name, value)
def append(self, field): ''' Appends a new *field* to the array. The given *field* must be of the same type specified when creating the array, otherwise a *TypeError* exception is raised. It is important to note that the given *field* name will be changed by its index in the array. ''' basefield = self.__fieldtype(self.root()) basefieldtype = type(basefield) # If we have a MetaField check the type of the field that it # will hold. if isinstance(basefield, MetaField): basefieldtype = basefield.type() if isinstance(field, basefieldtype): value = self.__length.value() field._set_name(str(value)) self.__length.set_value(value + 1) Structure.append(self, field) else: raise TypeError("Invalid field type for array '%s' " "(expected %s, got %s)" \ % (self.name(), basefieldtype, type(field)))
def _decode(self, stream): # Clear all fields in the array. self.reset() # Re-add length field and decode its value. Structure.append(self, self.__length) self.__length._decode(stream) # Append fields and parse them. for i in range(self.__length.value()): new_field = self.__fieldtype(self.root()) new_field._set_name("%d" % i) new_field._decode(stream) Structure.append(self, new_field)
def __init__(self, name, lengthfield, fieldtype): ''' Initialize the array with the given *name*, a *lengthfield* for the counter field and *fieldtype* for a single argument function that will return a new array member. The single argument is a reference to the top-level root :mod:`Container` field where the array belongs to. ''' Structure.__init__(self, name) self.__length = lengthfield self.__fieldtype = fieldtype Structure.append(self, self.__length)
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)