| 115 | |
| 116 | |
| 117 | class _Chunk: |
| 118 | def __init__(self, file, align=True, bigendian=True, inclheader=False): |
| 119 | self.closed = False |
| 120 | self.align = align # whether to align to word (2-byte) boundaries |
| 121 | if bigendian: |
| 122 | strflag = '>' |
| 123 | else: |
| 124 | strflag = '<' |
| 125 | self.file = file |
| 126 | self.chunkname = file.read(4) |
| 127 | if len(self.chunkname) < 4: |
| 128 | raise EOFError |
| 129 | try: |
| 130 | self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0] |
| 131 | except struct.error: |
| 132 | raise EOFError from None |
| 133 | if inclheader: |
| 134 | self.chunksize = self.chunksize - 8 # subtract header |
| 135 | self.size_read = 0 |
| 136 | try: |
| 137 | self.offset = self.file.tell() |
| 138 | except (AttributeError, OSError): |
| 139 | self.seekable = False |
| 140 | else: |
| 141 | self.seekable = True |
| 142 | |
| 143 | def getname(self): |
| 144 | """Return the name (ID) of the current chunk.""" |
| 145 | return self.chunkname |
| 146 | |
| 147 | def close(self): |
| 148 | if not self.closed: |
| 149 | try: |
| 150 | self.skip() |
| 151 | finally: |
| 152 | self.closed = True |
| 153 | |
| 154 | def seek(self, pos, whence=0): |
| 155 | """Seek to specified position into the chunk. |
| 156 | Default position is 0 (start of chunk). |
| 157 | If the file is not seekable, this will result in an error. |
| 158 | """ |
| 159 | |
| 160 | if self.closed: |
| 161 | raise ValueError("I/O operation on closed file") |
| 162 | if not self.seekable: |
| 163 | raise OSError("cannot seek") |
| 164 | if whence == 1: |
| 165 | pos = pos + self.size_read |
| 166 | elif whence == 2: |
| 167 | pos = pos + self.chunksize |
| 168 | if pos < 0 or pos > self.chunksize: |
| 169 | raise RuntimeError |
| 170 | self.file.seek(self.offset + pos, 0) |
| 171 | self.size_read = pos |
| 172 | |
| 173 | def tell(self): |
| 174 | if self.closed: |
no outgoing calls
no test coverage detected
searching dependent graphs…