| 69 | self.file.close() |
| 70 | |
| 71 | class IsoRecord(object): |
| 72 | label_part_names = ('rec_len rec_status impl_codes indicator_len identifier_len' |
| 73 | ' base_addr user_defined' |
| 74 | # directory map: |
| 75 | ' fld_len_len start_len impl_len reserved').split() |
| 76 | rec_len = 0 |
| 77 | |
| 78 | def __init__(self, iso_file=None): |
| 79 | self.iso_file = iso_file |
| 80 | self.load_label() |
| 81 | self.load_directory() |
| 82 | self.load_fields() |
| 83 | |
| 84 | def __len__(self): |
| 85 | return self.rec_len |
| 86 | |
| 87 | def load_label(self): |
| 88 | label = self.iso_file.read(LABEL_LEN) |
| 89 | if len(label) == 0: |
| 90 | raise StopIteration |
| 91 | elif len(label) != 24: |
| 92 | raise ValueError('Invalid record label: "%s"' % label) |
| 93 | parts = unpack(LABEL_FORMAT, label) |
| 94 | for name, part in zip(self.label_part_names, parts): |
| 95 | if name.endswith('_len') or name.endswith('_addr'): |
| 96 | part = int(part) |
| 97 | setattr(self, name, part) |
| 98 | |
| 99 | def show_label(self): |
| 100 | for name in self.label_part_names: |
| 101 | print('%15s : %r' % (name, getattr(self, name))) |
| 102 | |
| 103 | def load_directory(self): |
| 104 | fmt_dir = '3s %ss %ss %ss' % (self.fld_len_len, self.start_len, self.impl_len) |
| 105 | entry_len = TAG_LEN + self.fld_len_len + self.start_len + self.impl_len |
| 106 | self.directory = [] |
| 107 | while True: |
| 108 | char = self.iso_file.read(1) |
| 109 | if char.isdigit(): |
| 110 | entry = char + self.iso_file.read(entry_len-1) |
| 111 | entry = Field(* unpack(fmt_dir, entry)) |
| 112 | self.directory.append(entry) |
| 113 | else: |
| 114 | break |
| 115 | |
| 116 | def load_fields(self): |
| 117 | for field in self.directory: |
| 118 | if self.indicator_len > 0: |
| 119 | field.indicator = self.iso_file.read(self.indicator_len) |
| 120 | # XXX: lilacs30.iso has an identifier_len == 2, |
| 121 | # but we need to ignore it to succesfully read the field contents |
| 122 | # TODO: find out when to ignore the idenfier_len, |
| 123 | # or fix the lilacs30.iso fixture |
| 124 | # |
| 125 | ##if self.identifier_len > 0: # |
| 126 | ## field.identifier = self.iso_file.read(self.identifier_len) |
| 127 | value = self.iso_file.read(len(field)) |
| 128 | assert len(value) == len(field) |