Skip to content

Commit 07c6660

Browse files
authored
Add files via upload
1 parent e661965 commit 07c6660

File tree

1 file changed

+71
-47
lines changed

1 file changed

+71
-47
lines changed

pyarchivefile.py

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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 $"
614614
if(__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

88958895
def 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

89628986
def UncompressFile(infile, formatspecs=__file_format_multi_dict__, mode="rb",
89638987
filestart=0, use_mmap=False):

0 commit comments

Comments
 (0)