@@ -588,7 +588,7 @@ def _get(section_dict, key, default=None):
588588__version_date__ = str(__version_date_info__[0]) + "." + str(
589589 __version_date_info__[1]).zfill(2) + "." + str(__version_date_info__[2]).zfill(2)
590590__revision__ = __version_info__[3]
591- __revision_id__ = "$Id$"
591+ __revision_id__ = "$Id: a38e58d7eb4204ddfc3bb9a945fc416d6093c62a $"
592592if(__version_info__[4] is not None):
593593 __version_date_plusrc__ = __version_date__ + \
594594 "-" + str(__version_date_info__[4])
@@ -8919,71 +8919,95 @@ def CheckCompressionTypeFromBytes(instring, formatspecs=__file_format_multi_dict
89198919
89208920
89218921def UncompressFileAlt(fp, formatspecs=__file_format_multi_dict__, filestart=0,
8922- use_mmap=False):
8922+ use_mmap=False, reuse_adapter=True ):
89238923 """
8924- Accepts an already-open *bytes* file-like (fp). Detects compression and
8925- returns a FileLikeAdapter opened for 'rb'. If the stream is uncompressed
8926- and backed by a real file, you can enable mmap via use_mmap=True .
8924+ Detect compression at 'filestart' on fp and return a seekable, bytes-only stream.
8925+ - If fp is a FileLikeAdapter and reuse_adapter=True, reuse it by swapping its _fp.
8926+ - If passthrough (uncompressed), optionally mmap the raw file .
89278927 """
89288928 if not hasattr(fp, "read"):
89298929 return False
89308930
8931- # If caller already gave us a FileLikeAdapter => honor it and return it.
8932- if isinstance(fp, FileLikeAdapter):
8933- try:
8934- fp.write_through = True
8935- except Exception:
8936- pass
8937- return fp
8931+ # Always operate on the raw source for probe/wrap
8932+ src = getattr(fp, "_fp", fp)
89388933
8939- # Detect format on the fileobj at filestart
8940- compresscheck = CheckCompressionType(fp, formatspecs, filestart, False)
8941- if IsNestedDict(formatspecs) and compresscheck in formatspecs:
8942- formatspecs = formatspecs[compresscheck]
8934+ # Probe at filestart using RAW handle
8935+ try:
8936+ src.seek(filestart, 0)
8937+ except Exception:
8938+ pass
8939+
8940+ kind = CheckCompressionType(src, formatspecs, filestart, False)
8941+ # Optional canonicalization so names match your compressionsupport entries
8942+ if kind == "bz2":
8943+ kind = "bzip2"
8944+
8945+ if IsNestedDict(formatspecs) and kind in formatspecs:
8946+ formatspecs = formatspecs[kind]
8947+
8948+ # Guard against detector side-effects: ensure we're back at filestart
8949+ try:
8950+ src.seek(filestart, 0)
8951+ except Exception:
8952+ pass
89438953
8944- # Build the appropriate decompressor stream (or pass-through)
8945- if (compresscheck == "gzip" and compresscheck in compressionsupport):
8946- fp = gzip.GzipFile(filename=None, fileobj=fp, mode="rb")
8947- elif (compresscheck == "bzip2" and compresscheck in compressionsupport):
8948- fp = bz2.BZ2File(fp)
8949- elif (compresscheck == "zstd" and compresscheck in compressionsupport):
8954+ # Build logical stream (or passthrough)
8955+ if kind == "gzip" and "gzip" in compressionsupport:
8956+ wrapped = gzip.GzipFile(fileobj=src, mode="rb")
8957+ elif kind == "bzip2" and ("bzip2" in compressionsupport or "bz2" in compressionsupport):
8958+ wrapped = bz2.BZ2File(src)
8959+ elif kind in ("lzma","xz") and (("lzma" in compressionsupport) or ("xz" in compressionsupport)):
8960+ wrapped = lzma.LZMAFile(src)
8961+ elif kind == "zstd" and ("zstd" in compressionsupport or "zstandard" in compressionsupport):
89508962 if 'zstandard' in sys.modules:
8951- fp = ZstdFile(fileobj=fp , mode="rb")
8963+ wrapped = ZstdFile(fileobj=src , mode="rb")
89528964 elif 'pyzstd' in sys.modules:
8953- fp = pyzstd.zstdfile.ZstdFile(fileobj=fp , mode="rb")
8965+ wrapped = pyzstd.zstdfile.ZstdFile(fileobj=src , mode="rb")
89548966 else:
89558967 return False
8956- elif (compresscheck == "lz4" and compresscheck in compressionsupport):
8957- fp = lz4.frame.LZ4FrameFile(fp, mode='rb')
8958- elif ((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
8959- fp = LzopFile(fileobj=fp, mode="rb")
8960- elif ((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
8961- fp = lzma.LZMAFile(fp)
8962- elif (compresscheck == "zlib" and compresscheck in compressionsupport):
8963- fp = ZlibFile(fileobj=fp, mode="rb")
8968+ elif kind == "lz4" and "lz4" in compressionsupport:
8969+ wrapped = lz4.frame.LZ4FrameFile(src, mode="rb")
8970+ elif kind in ("lzo","lzop") and (("lzo" in compressionsupport) or ("lzop" in compressionsupport)):
8971+ wrapped = LzopFile(fileobj=src, mode="rb")
8972+ elif kind == "zlib" and "zlib" in compressionsupport:
8973+ wrapped = ZlibFile(fileobj=src, mode="rb")
89648974 else:
8965- # Either magic matched your format OR no compression detected:
8966- # pass-through original fp.
8967- fp.seek(filestart, 0)
8975+ # Passthrough
8976+ wrapped = src
8977+ try:
8978+ wrapped.seek(filestart, 0)
8979+ except Exception:
8980+ pass
8981+ kind = "" # treat as uncompressed for logic below
89688982
8969- # Wrap in FileLikeAdapter; optionally mmap only if uncompressed + real file
8983+ # Positioning: start-of-member for compressed; filestart for passthrough
8984+ try:
8985+ if kind in compressionsupport:
8986+ wrapped.seek(0, 0)
8987+ else:
8988+ wrapped.seek(filestart, 0)
8989+ except Exception:
8990+ pass
8991+
8992+ # Reuse existing adapter by swapping its underlying handle
8993+ if isinstance(fp, FileLikeAdapter) and reuse_adapter:
8994+ fp._mm = None
8995+ fp._fp = wrapped
8996+ fp._mode = "rb"
8997+ fp._pos = 0
8998+ return fp
8999+
9000+ # New adapter; mmap only for passthrough/raw file
89709001 mm = None
8971- if use_mmap and compresscheck in (None, formatspecs.get('format_magic', None)) :
8972- base = _extract_base_fp(fp )
9002+ if use_mmap and wrapped is src and kind == "" :
9003+ base = _extract_base_fp(src )
89739004 try:
89749005 if base is not None:
8975- # Map whole file for read-only; keep base open via adapter
89769006 mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
89779007 except Exception:
8978- mm = None # silently fall back to streaming
8979- if(compresscheck in compressionsupport):
8980- # Always position at start of logical stream
8981- try:
8982- fp.seek(0, 0)
8983- except Exception:
8984- pass
9008+ mm = None
89859009
8986- return FileLikeAdapter(fp , mode="rb", mm=mm)
9010+ return FileLikeAdapter(wrapped , mode="rb", mm=mm)
89879011
89889012def UncompressFile(infile, formatspecs=__file_format_multi_dict__, mode="rb",
89899013 filestart=0, use_mmap=False):
0 commit comments