File-like object for reading an archive member. Is returned by ZipFile.open().
| 814 | |
| 815 | |
| 816 | class ZipExtFile(io.BufferedIOBase): |
| 817 | """File-like object for reading an archive member. |
| 818 | Is returned by ZipFile.open(). |
| 819 | """ |
| 820 | |
| 821 | # Max size supported by decompressor. |
| 822 | MAX_N = 1 << 31 - 1 |
| 823 | |
| 824 | # Read from compressed files in 4k blocks. |
| 825 | MIN_READ_SIZE = 4096 |
| 826 | |
| 827 | # Chunk size to read during seek |
| 828 | MAX_SEEK_READ = 1 << 24 |
| 829 | |
| 830 | def __init__(self, fileobj, mode, zipinfo, pwd=None, |
| 831 | close_fileobj=False): |
| 832 | self._fileobj = fileobj |
| 833 | self._pwd = pwd |
| 834 | self._close_fileobj = close_fileobj |
| 835 | |
| 836 | self._compress_type = zipinfo.compress_type |
| 837 | self._compress_left = zipinfo.compress_size |
| 838 | self._left = zipinfo.file_size |
| 839 | |
| 840 | self._decompressor = _get_decompressor(self._compress_type) |
| 841 | |
| 842 | self._eof = False |
| 843 | self._readbuffer = b'' |
| 844 | self._offset = 0 |
| 845 | |
| 846 | self.newlines = None |
| 847 | |
| 848 | self.mode = mode |
| 849 | self.name = zipinfo.filename |
| 850 | |
| 851 | if hasattr(zipinfo, 'CRC'): |
| 852 | self._expected_crc = zipinfo.CRC |
| 853 | self._running_crc = crc32(b'') |
| 854 | else: |
| 855 | self._expected_crc = None |
| 856 | |
| 857 | self._seekable = False |
| 858 | try: |
| 859 | if fileobj.seekable(): |
| 860 | self._orig_compress_start = fileobj.tell() |
| 861 | self._orig_compress_size = zipinfo.compress_size |
| 862 | self._orig_file_size = zipinfo.file_size |
| 863 | self._orig_start_crc = self._running_crc |
| 864 | self._seekable = True |
| 865 | except AttributeError: |
| 866 | pass |
| 867 | |
| 868 | self._decrypter = None |
| 869 | if pwd: |
| 870 | if zipinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR: |
| 871 | # compare against the file type from extended local headers |
| 872 | check_byte = (zipinfo._raw_time >> 8) & 0xff |
| 873 | else: |