@@ -610,7 +610,7 @@ def _get(section_dict, key, default=None):
610610__version_date__ = str(__version_date_info__[0]) + "." + str(
611611 __version_date_info__[1]).zfill(2) + "." + str(__version_date_info__[2]).zfill(2)
612612__revision__ = __version_info__[3]
613- __revision_id__ = "$Id$"
613+ __revision_id__ = "$Id: df415740ccda16ca0395e86ac4d28cf73a3eb9bf $"
614614if(__version_info__[4] is not None):
615615 __version_date_plusrc__ = __version_date__ + \
616616 "-" + str(__version_date_info__[4])
@@ -8893,71 +8893,95 @@ def CheckCompressionTypeFromBytes(instring, formatspecs=__file_format_multi_dict
88938893
88948894
88958895def UncompressFileAlt(fp, formatspecs=__file_format_multi_dict__, filestart=0,
8896- use_mmap=False):
8896+ use_mmap=False, reuse_adapter=True ):
88978897 """
8898- Accepts an already-open *bytes* file-like (fp). Detects compression and
8899- returns a FileLikeAdapter opened for 'rb'. If the stream is uncompressed
8900- and backed by a real file, you can enable mmap via use_mmap=True .
8898+ Detect compression at 'filestart' on fp and return a seekable, bytes-only stream.
8899+ - If fp is a FileLikeAdapter and reuse_adapter=True, reuse it by swapping its _fp.
8900+ - If passthrough (uncompressed), optionally mmap the raw file .
89018901 """
89028902 if not hasattr(fp, "read"):
89038903 return False
89048904
8905- # If caller already gave us a FileLikeAdapter => honor it and return it.
8906- if isinstance(fp, FileLikeAdapter):
8907- try:
8908- fp.write_through = True
8909- except Exception:
8910- pass
8911- return fp
8905+ # Always operate on the raw source for probe/wrap
8906+ src = getattr(fp, "_fp", fp)
89128907
8913- # Detect format on the fileobj at filestart
8914- compresscheck = CheckCompressionType(fp, formatspecs, filestart, False)
8915- if IsNestedDict(formatspecs) and compresscheck in formatspecs:
8916- formatspecs = formatspecs[compresscheck]
8908+ # Probe at filestart using RAW handle
8909+ try:
8910+ src.seek(filestart, 0)
8911+ except Exception:
8912+ pass
8913+
8914+ kind = CheckCompressionType(src, formatspecs, filestart, False)
8915+ # Optional canonicalization so names match your compressionsupport entries
8916+ if kind == "bz2":
8917+ kind = "bzip2"
89178918
8918- # Build the appropriate decompressor stream (or pass-through)
8919- if (compresscheck == "gzip" and compresscheck in compressionsupport):
8920- fp = gzip.GzipFile(filename=None, fileobj=fp, mode="rb")
8921- elif (compresscheck == "bzip2" and compresscheck in compressionsupport):
8922- fp = bz2.BZ2File(fp)
8923- elif (compresscheck == "zstd" and compresscheck in compressionsupport):
8919+ if IsNestedDict(formatspecs) and kind in formatspecs:
8920+ formatspecs = formatspecs[kind]
8921+
8922+ # Guard against detector side-effects: ensure we're back at filestart
8923+ try:
8924+ src.seek(filestart, 0)
8925+ except Exception:
8926+ pass
8927+
8928+ # Build logical stream (or passthrough)
8929+ if kind == "gzip" and "gzip" in compressionsupport:
8930+ wrapped = gzip.GzipFile(fileobj=src, mode="rb")
8931+ elif kind == "bzip2" and ("bzip2" in compressionsupport or "bz2" in compressionsupport):
8932+ wrapped = bz2.BZ2File(src)
8933+ elif kind in ("lzma","xz") and (("lzma" in compressionsupport) or ("xz" in compressionsupport)):
8934+ wrapped = lzma.LZMAFile(src)
8935+ elif kind == "zstd" and ("zstd" in compressionsupport or "zstandard" in compressionsupport):
89248936 if 'zstandard' in sys.modules:
8925- fp = ZstdFile(fileobj=fp , mode="rb")
8937+ wrapped = ZstdFile(fileobj=src , mode="rb")
89268938 elif 'pyzstd' in sys.modules:
8927- fp = pyzstd.zstdfile.ZstdFile(fileobj=fp , mode="rb")
8939+ wrapped = pyzstd.zstdfile.ZstdFile(fileobj=src , mode="rb")
89288940 else:
89298941 return False
8930- elif (compresscheck == "lz4" and compresscheck in compressionsupport):
8931- fp = lz4.frame.LZ4FrameFile(fp, mode='rb')
8932- elif ((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
8933- fp = LzopFile(fileobj=fp, mode="rb")
8934- elif ((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
8935- fp = lzma.LZMAFile(fp)
8936- elif (compresscheck == "zlib" and compresscheck in compressionsupport):
8937- fp = ZlibFile(fileobj=fp, mode="rb")
8942+ elif kind == "lz4" and "lz4" in compressionsupport:
8943+ wrapped = lz4.frame.LZ4FrameFile(src, mode="rb")
8944+ elif kind in ("lzo","lzop") and (("lzo" in compressionsupport) or ("lzop" in compressionsupport)):
8945+ wrapped = LzopFile(fileobj=src, mode="rb")
8946+ elif kind == "zlib" and "zlib" in compressionsupport:
8947+ wrapped = ZlibFile(fileobj=src, mode="rb")
89388948 else:
8939- # Either magic matched your format OR no compression detected:
8940- # pass-through original fp.
8941- fp.seek(filestart, 0)
8949+ # Passthrough
8950+ wrapped = src
8951+ try:
8952+ wrapped.seek(filestart, 0)
8953+ except Exception:
8954+ pass
8955+ kind = "" # treat as uncompressed for logic below
8956+
8957+ # Positioning: start-of-member for compressed; filestart for passthrough
8958+ try:
8959+ if kind in compressionsupport:
8960+ wrapped.seek(0, 0)
8961+ else:
8962+ wrapped.seek(filestart, 0)
8963+ except Exception:
8964+ pass
8965+
8966+ # Reuse existing adapter by swapping its underlying handle
8967+ if isinstance(fp, FileLikeAdapter) and reuse_adapter:
8968+ fp._mm = None
8969+ fp._fp = wrapped
8970+ fp._mode = "rb"
8971+ fp._pos = 0
8972+ return fp
89428973
8943- # Wrap in FileLikeAdapter; optionally mmap only if uncompressed + real file
8974+ # New adapter; mmap only for passthrough/raw file
89448975 mm = None
8945- if use_mmap and compresscheck in (None, formatspecs.get('format_magic', None)) :
8946- base = _extract_base_fp(fp )
8976+ if use_mmap and wrapped is src and kind == "" :
8977+ base = _extract_base_fp(src )
89478978 try:
89488979 if base is not None:
8949- # Map whole file for read-only; keep base open via adapter
89508980 mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
89518981 except Exception:
8952- mm = None # silently fall back to streaming
8953- if(compresscheck in compressionsupport):
8954- # Always position at start of logical stream
8955- try:
8956- fp.seek(0, 0)
8957- except Exception:
8958- pass
8982+ mm = None
89598983
8960- return FileLikeAdapter(fp , mode="rb", mm=mm)
8984+ return FileLikeAdapter(wrapped , mode="rb", mm=mm)
89618985
89628986def UncompressFile(infile, formatspecs=__file_format_multi_dict__, mode="rb",
89638987 filestart=0, use_mmap=False):
0 commit comments