@@ -622,7 +622,7 @@ def _get(section_dict, key, default=None):
622622__version_date__ = str(__version_date_info__[0]) + "." + str(
623623 __version_date_info__[1]).zfill(2) + "." + str(__version_date_info__[2]).zfill(2)
624624__revision__ = __version_info__[3]
625- __revision_id__ = "$Id$"
625+ __revision_id__ = "$Id: b49a691e7b814a957c65b7e6859ae0670540456f $"
626626if(__version_info__[4] is not None):
627627 __version_date_plusrc__ = __version_date__ + \
628628 "-" + str(__version_date_info__[4])
@@ -8905,71 +8905,95 @@ def CheckCompressionTypeFromBytes(instring, formatspecs=__file_format_multi_dict
89058905
89068906
89078907def UncompressFileAlt(fp, formatspecs=__file_format_multi_dict__, filestart=0,
8908- use_mmap=False):
8908+ use_mmap=False, reuse_adapter=True ):
89098909 """
8910- Accepts an already-open *bytes* file-like (fp). Detects compression and
8911- returns a FileLikeAdapter opened for 'rb'. If the stream is uncompressed
8912- and backed by a real file, you can enable mmap via use_mmap=True .
8910+ Detect compression at 'filestart' on fp and return a seekable, bytes-only stream.
8911+ - If fp is a FileLikeAdapter and reuse_adapter=True, reuse it by swapping its _fp.
8912+ - If passthrough (uncompressed), optionally mmap the raw file .
89138913 """
89148914 if not hasattr(fp, "read"):
89158915 return False
89168916
8917- # If caller already gave us a FileLikeAdapter => honor it and return it.
8918- if isinstance(fp, FileLikeAdapter):
8919- try:
8920- fp.write_through = True
8921- except Exception:
8922- pass
8923- return fp
8917+ # Always operate on the raw source for probe/wrap
8918+ src = getattr(fp, "_fp", fp)
89248919
8925- # Detect format on the fileobj at filestart
8926- compresscheck = CheckCompressionType(fp, formatspecs, filestart, False)
8927- if IsNestedDict(formatspecs) and compresscheck in formatspecs:
8928- formatspecs = formatspecs[compresscheck]
8920+ # Probe at filestart using RAW handle
8921+ try:
8922+ src.seek(filestart, 0)
8923+ except Exception:
8924+ pass
8925+
8926+ kind = CheckCompressionType(src, formatspecs, filestart, False)
8927+ # Optional canonicalization so names match your compressionsupport entries
8928+ if kind == "bz2":
8929+ kind = "bzip2"
89298930
8930- # Build the appropriate decompressor stream (or pass-through)
8931- if (compresscheck == "gzip" and compresscheck in compressionsupport):
8932- fp = gzip.GzipFile(filename=None, fileobj=fp, mode="rb")
8933- elif (compresscheck == "bzip2" and compresscheck in compressionsupport):
8934- fp = bz2.BZ2File(fp)
8935- elif (compresscheck == "zstd" and compresscheck in compressionsupport):
8931+ if IsNestedDict(formatspecs) and kind in formatspecs:
8932+ formatspecs = formatspecs[kind]
8933+
8934+ # Guard against detector side-effects: ensure we're back at filestart
8935+ try:
8936+ src.seek(filestart, 0)
8937+ except Exception:
8938+ pass
8939+
8940+ # Build logical stream (or passthrough)
8941+ if kind == "gzip" and "gzip" in compressionsupport:
8942+ wrapped = gzip.GzipFile(fileobj=src, mode="rb")
8943+ elif kind == "bzip2" and ("bzip2" in compressionsupport or "bz2" in compressionsupport):
8944+ wrapped = bz2.BZ2File(src)
8945+ elif kind in ("lzma","xz") and (("lzma" in compressionsupport) or ("xz" in compressionsupport)):
8946+ wrapped = lzma.LZMAFile(src)
8947+ elif kind == "zstd" and ("zstd" in compressionsupport or "zstandard" in compressionsupport):
89368948 if 'zstandard' in sys.modules:
8937- fp = ZstdFile(fileobj=fp , mode="rb")
8949+ wrapped = ZstdFile(fileobj=src , mode="rb")
89388950 elif 'pyzstd' in sys.modules:
8939- fp = pyzstd.zstdfile.ZstdFile(fileobj=fp , mode="rb")
8951+ wrapped = pyzstd.zstdfile.ZstdFile(fileobj=src , mode="rb")
89408952 else:
89418953 return False
8942- elif (compresscheck == "lz4" and compresscheck in compressionsupport):
8943- fp = lz4.frame.LZ4FrameFile(fp, mode='rb')
8944- elif ((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
8945- fp = LzopFile(fileobj=fp, mode="rb")
8946- elif ((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
8947- fp = lzma.LZMAFile(fp)
8948- elif (compresscheck == "zlib" and compresscheck in compressionsupport):
8949- fp = ZlibFile(fileobj=fp, mode="rb")
8954+ elif kind == "lz4" and "lz4" in compressionsupport:
8955+ wrapped = lz4.frame.LZ4FrameFile(src, mode="rb")
8956+ elif kind in ("lzo","lzop") and (("lzo" in compressionsupport) or ("lzop" in compressionsupport)):
8957+ wrapped = LzopFile(fileobj=src, mode="rb")
8958+ elif kind == "zlib" and "zlib" in compressionsupport:
8959+ wrapped = ZlibFile(fileobj=src, mode="rb")
89508960 else:
8951- # Either magic matched your format OR no compression detected:
8952- # pass-through original fp.
8953- fp.seek(filestart, 0)
8961+ # Passthrough
8962+ wrapped = src
8963+ try:
8964+ wrapped.seek(filestart, 0)
8965+ except Exception:
8966+ pass
8967+ kind = "" # treat as uncompressed for logic below
8968+
8969+ # Positioning: start-of-member for compressed; filestart for passthrough
8970+ try:
8971+ if kind in compressionsupport:
8972+ wrapped.seek(0, 0)
8973+ else:
8974+ wrapped.seek(filestart, 0)
8975+ except Exception:
8976+ pass
8977+
8978+ # Reuse existing adapter by swapping its underlying handle
8979+ if isinstance(fp, FileLikeAdapter) and reuse_adapter:
8980+ fp._mm = None
8981+ fp._fp = wrapped
8982+ fp._mode = "rb"
8983+ fp._pos = 0
8984+ return fp
89548985
8955- # Wrap in FileLikeAdapter; optionally mmap only if uncompressed + real file
8986+ # New adapter; mmap only for passthrough/raw file
89568987 mm = None
8957- if use_mmap and compresscheck in (None, formatspecs.get('format_magic', None)) :
8958- base = _extract_base_fp(fp )
8988+ if use_mmap and wrapped is src and kind == "" :
8989+ base = _extract_base_fp(src )
89598990 try:
89608991 if base is not None:
8961- # Map whole file for read-only; keep base open via adapter
89628992 mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
89638993 except Exception:
8964- mm = None # silently fall back to streaming
8965- if(compresscheck in compressionsupport):
8966- # Always position at start of logical stream
8967- try:
8968- fp.seek(0, 0)
8969- except Exception:
8970- pass
8994+ mm = None
89718995
8972- return FileLikeAdapter(fp , mode="rb", mm=mm)
8996+ return FileLikeAdapter(wrapped , mode="rb", mm=mm)
89738997
89748998def UncompressFile(infile, formatspecs=__file_format_multi_dict__, mode="rb",
89758999 filestart=0, use_mmap=False):
0 commit comments