Skip to content

Commit 56b3df3

Browse files
author
Kazuki Suzuki Przyborowski
committed
Update pyarchivefile.py
1 parent 3a9ee7a commit 56b3df3

1 file changed

Lines changed: 98 additions & 55 deletions

File tree

pyarchivefile.py

Lines changed: 98 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5755,88 +5755,131 @@ def CheckCompressionTypeFromBytes(instring, formatspecs=__file_format_multi_dict
57555755
return CheckCompressionType(instringsfile, formatspecs, filestart, closefp)
57565756

57575757

5758-
def UncompressFileAlt(fp, formatspecs=__file_format_multi_dict__, filestart=0):
5759-
if(not hasattr(fp, "read")):
5758+
def UncompressFileAlt(fp, formatspecs=__file_format_multi_dict__, filestart=0,
5759+
use_mmap=False):
5760+
"""
5761+
Accepts an already-open *bytes* file-like (fp). Detects compression and
5762+
returns a FileLikeAdapter opened for 'rb'. If the stream is uncompressed
5763+
and backed by a real file, you can enable mmap via use_mmap=True.
5764+
"""
5765+
if not hasattr(fp, "read"):
57605766
return False
5767+
5768+
# Detect format on the fileobj at filestart
57615769
compresscheck = CheckCompressionType(fp, formatspecs, filestart, False)
5762-
if(IsNestedDict(formatspecs) and compresscheck in formatspecs):
5770+
if IsNestedDict(formatspecs) and compresscheck in formatspecs:
57635771
formatspecs = formatspecs[compresscheck]
5764-
if(compresscheck == "gzip" and compresscheck in compressionsupport):
5772+
5773+
# Build the appropriate decompressor stream (or pass-through)
5774+
if (compresscheck == "gzip" and compresscheck in compressionsupport):
57655775
fp = gzip.GzipFile(fileobj=fp, mode="rb")
5766-
elif(compresscheck == "bzip2" and compresscheck in compressionsupport):
5776+
elif (compresscheck == "bzip2" and compresscheck in compressionsupport):
57675777
fp = bz2.BZ2File(fp)
5768-
elif(compresscheck == "zstd" and compresscheck in compressionsupport):
5778+
elif (compresscheck == "zstd" and compresscheck in compressionsupport):
57695779
if 'zstandard' in sys.modules:
57705780
fp = ZstdFile(fileobj=fp, mode="rb")
57715781
elif 'pyzstd' in sys.modules:
57725782
fp = pyzstd.zstdfile.ZstdFile(fileobj=fp, mode="rb")
57735783
else:
5774-
return Flase
5775-
elif(compresscheck == "lz4" and compresscheck in compressionsupport):
5784+
return False
5785+
elif (compresscheck == "lz4" and compresscheck in compressionsupport):
57765786
fp = lz4.frame.LZ4FrameFile(fp, mode='rb')
5777-
elif((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
5787+
elif ((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
57785788
fp = LzopFile(fileobj=fp, mode="rb")
5779-
elif((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
5789+
elif ((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
57805790
fp = lzma.LZMAFile(fp)
5781-
elif(compresscheck == "zlib" and compresscheck in compressionsupport):
5791+
elif (compresscheck == "zlib" and compresscheck in compressionsupport):
57825792
fp = ZlibFile(fileobj=fp, mode="rb")
5783-
elif(compresscheck == formatspecs['format_magic']):
5784-
fp = fp
5785-
elif(not compresscheck):
5793+
else:
5794+
# Either magic matched your format OR no compression detected:
5795+
# pass-through original fp.
5796+
fp.seek(filestart, 0)
5797+
5798+
# Wrap in FileLikeAdapter; optionally mmap only if uncompressed + real file
5799+
mm = None
5800+
if use_mmap and compresscheck in (None, formatspecs.get('format_magic', None)):
5801+
base = _extract_base_fp(fp)
57865802
try:
5787-
fp = lz4.frame.LZ4FrameFile(fp, mode='rb')
5788-
except lzma.LZMAError:
5789-
return False
5790-
if(compresscheck != formatspecs['format_magic']):
5791-
fp.close()
5792-
return fp
5803+
if base is not None:
5804+
# Map whole file for read-only; keep base open via adapter
5805+
mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
5806+
except Exception:
5807+
mm = None # silently fall back to streaming
57935808

5809+
# Always position at start of logical stream
5810+
try:
5811+
fp.seek(0, 0)
5812+
except Exception:
5813+
pass
5814+
5815+
return FileLikeAdapter(fp, mode="rb", mm=mm)
57945816

5795-
def UncompressFile(infile, formatspecs=__file_format_multi_dict__, mode="rb", filestart=0):
5817+
def UncompressFile(infile, formatspecs=__file_format_multi_dict__, mode="rb",
5818+
filestart=0, use_mmap=False):
5819+
"""
5820+
Opens a path, detects compression by header, and returns a FileLikeAdapter.
5821+
If uncompressed and use_mmap=True, returns an mmap-backed reader.
5822+
"""
57965823
compresscheck = CheckCompressionType(infile, formatspecs, filestart, False)
5797-
if(IsNestedDict(formatspecs) and compresscheck in formatspecs):
5824+
if IsNestedDict(formatspecs) and compresscheck in formatspecs:
57985825
formatspecs = formatspecs[compresscheck]
5799-
if(sys.version_info[0] == 2 and compresscheck):
5800-
if(mode == "rt"):
5801-
mode = "r"
5802-
elif(mode == "wt"):
5803-
mode = "w"
5826+
5827+
# Python 2 text-mode fixups if needed (though you're bytes-only)
5828+
if sys.version_info[0] == 2 and compresscheck:
5829+
if mode == "rt": mode = "r"
5830+
elif mode == "wt": mode = "w"
5831+
58045832
try:
5805-
if(compresscheck == "gzip" and compresscheck in compressionsupport):
5806-
if sys.version_info[0] == 2:
5807-
filefp = GzipFile(infile, mode=mode)
5808-
else:
5809-
filefp = gzip.open(infile, mode)
5810-
elif(compresscheck == "bzip2" and compresscheck in compressionsupport):
5811-
filefp = bz2.open(infile, mode)
5812-
elif(compresscheck == "zstd" and compresscheck in compressionsupport):
5833+
# Compressed branches
5834+
if (compresscheck == "gzip" and "gzip" in compressionsupport):
5835+
fp = GzipFile(infile, mode=mode) if sys.version_info[0] == 2 else gzip.open(infile, mode)
5836+
elif (compresscheck == "bzip2" and "bzip2" in compressionsupport):
5837+
fp = bz2.open(infile, mode)
5838+
elif (compresscheck == "zstd" and "zstandard" in compressionsupport):
58135839
if 'zstandard' in sys.modules:
5814-
filefp = ZstdFile(infile, mode=mode)
5840+
fp = ZstdFile(infile, mode=mode)
58155841
elif 'pyzstd' in sys.modules:
5816-
filefp = pyzstd.zstdfile.ZstdFile(infile, mode=mode)
5842+
fp = pyzstd.zstdfile.ZstdFile(infile, mode=mode)
58175843
else:
5818-
return Flase
5819-
elif(compresscheck == "lz4" and compresscheck in compressionsupport):
5820-
filefp = lz4.frame.open(infile, mode)
5821-
elif((compresscheck == "lzo" or compresscheck == "lzop") and compresscheck in compressionsupport):
5822-
filefp = LzopFile(infile, mode=mode)
5823-
elif((compresscheck == "lzma" or compresscheck == "xz") and compresscheck in compressionsupport):
5824-
filefp = lzma.open(infile, mode)
5825-
elif(compresscheck == "zlib" and compresscheck in compressionsupport):
5826-
filefp = ZlibFile(infile, mode=mode)
5827-
elif(compresscheck == formatspecs['format_magic']):
5828-
filefp = open(infile, mode)
5829-
elif(not compresscheck):
5830-
filefp = open(infile, mode)
5831-
else:
5832-
filefp = open(infile, mode)
5844+
return False
5845+
elif (compresscheck == "lz4" and "lz4" in compressionsupport):
5846+
fp = lz4.frame.open(infile, mode)
5847+
elif ((compresscheck == "lzo" or compresscheck == "lzop") and "lzop" in compressionsupport):
5848+
fp = LzopFile(infile, mode=mode)
5849+
elif ((compresscheck == "lzma" or compresscheck == "xz") and "xz" in compressionsupport):
5850+
fp = lzma.open(infile, mode)
5851+
elif (compresscheck == "zlib" and "zlib" in compressionsupport):
5852+
fp = ZlibFile(infile, mode=mode)
5853+
5854+
# Uncompressed (or unknown): open plain file
5855+
else:
5856+
fp = open(infile, mode)
5857+
58335858
except FileNotFoundError:
58345859
return False
5860+
5861+
# For uncompressed: optional mmap
5862+
mm = None
5863+
if use_mmap and (compresscheck is None or compresscheck == formatspecs.get('format_magic', None)):
5864+
try:
5865+
base = _extract_base_fp(fp)
5866+
if base is not None:
5867+
mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ if "r" in mode else mmap.ACCESS_WRITE)
5868+
except Exception:
5869+
mm = None # fallback to normal file stream
5870+
5871+
# Position to filestart if caller requested it (mainly for fileobj-based headers)
58355872
try:
5836-
filefp.write_through = True
5837-
except AttributeError:
5873+
fp.seek(0 if compresscheck else filestart, 0)
5874+
except Exception:
58385875
pass
5839-
return filefp
5876+
5877+
out = FileLikeAdapter(fp, mode="rb" if "r" in mode else "wb", mm=mm)
5878+
try:
5879+
out.write_through = True
5880+
except Exception:
5881+
pass
5882+
return out
58405883

58415884

58425885
def UncompressString(infile, formatspecs=__file_format_multi_dict__, filestart=0):

0 commit comments

Comments
 (0)