import itertools from hachoir.field import MissingField class FakeArray: """ Simulate an array for GenericFieldSet.array(): fielset.array("item")[0] is equivalent to fielset.array("item[0]"). It's possible to iterate over the items using:: for element in fieldset.array("item"): ... And to get array size using len(fieldset.array("item")). """ def __init__(self, fieldset, name): pos = name.rfind("/") if pos != -1: self.fieldset = fieldset[name[:pos]] self.name = name[pos + 1:] else: self.fieldset = fieldset self.name = name self._format = "%s[%%u]" % self.name self._cache = {} self._known_size = False self._max_index = -1 def __bool__(self): "Is the array empty or not?" if self._cache: return True else: return (0 in self) def __len__(self): "Number of fields in the array" total = self._max_index + 1 if not self._known_size: for index in itertools.count(total): try: self[index] total += 1 except MissingField: break return total def __contains__(self, index): try: self[index] return True except MissingField: return False def __getitem__(self, index): """ Get a field of the array. Returns a field, or raise MissingField exception if the field doesn't exist. """ try: value = self._cache[index] except KeyError: try: value = self.fieldset[self._format % index] except MissingField: self._known_size = True raise self._cache[index] = value self._max_index = max(index, self._max_index) return value def __iter__(self): """ Iterate in the fields in their index order: field[0], field[1], ... """ for index in itertools.count(0): try: yield self[index] except MissingField: break