diff options
author | Brett Cannon <brett@python.org> | 2022-04-11 22:02:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-11 22:02:41 (GMT) |
commit | 3869a839d5f14a91978c6158a03c68fac5e938dd (patch) | |
tree | 996dca116c16e84fb623aa04d66f3434c07f1a27 /Lib/wave.py | |
parent | 8be8949116e1812df5e329a18647ebdea7fb9c6c (diff) | |
download | cpython-3869a839d5f14a91978c6158a03c68fac5e938dd.zip cpython-3869a839d5f14a91978c6158a03c68fac5e938dd.tar.gz cpython-3869a839d5f14a91978c6158a03c68fac5e938dd.tar.bz2 |
gh-47061: Deprecate `chunk` (GH-91419)
Diffstat (limited to 'Lib/wave.py')
-rw-r--r-- | Lib/wave.py | 118 |
1 files changed, 115 insertions, 3 deletions
diff --git a/Lib/wave.py b/Lib/wave.py index 47a233d..9a45574 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -71,7 +71,6 @@ The close() method is called automatically when the class instance is destroyed. """ -from chunk import Chunk from collections import namedtuple import builtins import struct @@ -100,6 +99,119 @@ def _byteswap(data, width): return bytes(swapped_data) +class _Chunk: + def __init__(self, file, align=True, bigendian=True, inclheader=False): + import struct + self.closed = False + self.align = align # whether to align to word (2-byte) boundaries + if bigendian: + strflag = '>' + else: + strflag = '<' + self.file = file + self.chunkname = file.read(4) + if len(self.chunkname) < 4: + raise EOFError + try: + self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0] + except struct.error: + raise EOFError from None + if inclheader: + self.chunksize = self.chunksize - 8 # subtract header + self.size_read = 0 + try: + self.offset = self.file.tell() + except (AttributeError, OSError): + self.seekable = False + else: + self.seekable = True + + def getname(self): + """Return the name (ID) of the current chunk.""" + return self.chunkname + + def close(self): + if not self.closed: + try: + self.skip() + finally: + self.closed = True + + def seek(self, pos, whence=0): + """Seek to specified position into the chunk. + Default position is 0 (start of chunk). + If the file is not seekable, this will result in an error. + """ + + if self.closed: + raise ValueError("I/O operation on closed file") + if not self.seekable: + raise OSError("cannot seek") + if whence == 1: + pos = pos + self.size_read + elif whence == 2: + pos = pos + self.chunksize + if pos < 0 or pos > self.chunksize: + raise RuntimeError + self.file.seek(self.offset + pos, 0) + self.size_read = pos + + def tell(self): + if self.closed: + raise ValueError("I/O operation on closed file") + return self.size_read + + def read(self, size=-1): + """Read at most size bytes from the chunk. + If size is omitted or negative, read until the end + of the chunk. + """ + + if self.closed: + raise ValueError("I/O operation on closed file") + if self.size_read >= self.chunksize: + return b'' + if size < 0: + size = self.chunksize - self.size_read + if size > self.chunksize - self.size_read: + size = self.chunksize - self.size_read + data = self.file.read(size) + self.size_read = self.size_read + len(data) + if self.size_read == self.chunksize and \ + self.align and \ + (self.chunksize & 1): + dummy = self.file.read(1) + self.size_read = self.size_read + len(dummy) + return data + + def skip(self): + """Skip the rest of the chunk. + If you are not interested in the contents of the chunk, + this method should be called so that the file points to + the start of the next chunk. + """ + + if self.closed: + raise ValueError("I/O operation on closed file") + if self.seekable: + try: + n = self.chunksize - self.size_read + # maybe fix alignment + if self.align and (self.chunksize & 1): + n = n + 1 + self.file.seek(n, 1) + self.size_read = self.size_read + n + return + except OSError: + pass + while self.size_read < self.chunksize: + n = min(8192, self.chunksize - self.size_read) + dummy = self.read(n) + if not dummy: + raise EOFError + + + class Wave_read: """Variables used in this class: @@ -134,7 +246,7 @@ class Wave_read: def initfp(self, file): self._convert = None self._soundpos = 0 - self._file = Chunk(file, bigendian = 0) + self._file = _Chunk(file, bigendian = 0) if self._file.getname() != b'RIFF': raise Error('file does not start with RIFF id') if self._file.read(4) != b'WAVE': @@ -144,7 +256,7 @@ class Wave_read: while 1: self._data_seek_needed = 1 try: - chunk = Chunk(self._file, bigendian = 0) + chunk = _Chunk(self._file, bigendian = 0) except EOFError: break chunkname = chunk.getname() |