Skip to content

Commit 123d420

Browse files
author
Kazuki Suzuki Przyborowski
committed
Update pyfoxfile.py
1 parent 8eb6e02 commit 123d420

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

pyfoxfile.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6259,6 +6259,74 @@ def __setattr__(self, name, value):
62596259
object.__setattr__(self, name, value); return
62606260
object.__setattr__(self, name, value)
62616261

6262+
# ========= shared utilities =========
6263+
6264+
def _maybe_make_mmap(fp_like, mode, use_mmap=False, mmap_size=None):
6265+
"""
6266+
If use_mmap is True and fp_like ultimately has a real fileno(),
6267+
return (fp_like, mm) where mm is an mmap.mmap for the whole file (read)
6268+
or a pre-sized mapping (write). Otherwise return (fp_like, None).
6269+
"""
6270+
if not use_mmap:
6271+
return fp_like, None
6272+
6273+
base = _extract_base_fp(fp_like)
6274+
if base is None:
6275+
return fp_like, None # BytesIO / compressed stream etc.
6276+
6277+
import mmap
6278+
# READ mapping: map entire file (size 0 means "whole file")
6279+
if "r" in mode and "w" not in mode and "a" not in mode and "x" not in mode:
6280+
try:
6281+
mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
6282+
return fp_like, mm
6283+
except Exception:
6284+
return fp_like, None
6285+
6286+
# WRITE mapping: must pre-size
6287+
if any(ch in mode for ch in "wax+"):
6288+
if not mmap_size or mmap_size <= 0:
6289+
# caller must provide a mapping length for writes
6290+
return fp_like, None
6291+
try:
6292+
# Ensure the underlying file is opened read+write
6293+
# (re-open if needed)
6294+
try:
6295+
fd = base.fileno()
6296+
except Exception:
6297+
return fp_like, None
6298+
6299+
# Make sure file is large enough
6300+
try:
6301+
base.truncate(mmap_size)
6302+
except Exception:
6303+
return fp_like, None
6304+
6305+
mm = mmap.mmap(fd, mmap_size, access=mmap.ACCESS_WRITE)
6306+
return fp_like, mm
6307+
except Exception:
6308+
return fp_like, None
6309+
6310+
return fp_like, None
6311+
6312+
6313+
def open_adapter(obj_or_path, mode="rb", use_mmap=False, mmap_size=None):
6314+
"""
6315+
Universal opener:
6316+
- If given a path (str/bytes), open it with built-in open().
6317+
- If given a file-like, use it as-is.
6318+
Returns a FileLikeAdapter, optionally mmap-backed (only when possible).
6319+
"""
6320+
is_path = isinstance(obj_or_path, (str, bytes))
6321+
if is_path:
6322+
fp = open(obj_or_path, mode)
6323+
fp, mm = _maybe_make_mmap(fp, mode, use_mmap=use_mmap, mmap_size=mmap_size)
6324+
return FileLikeAdapter(fp, mode=mode, mm=mm)
6325+
6326+
# file-like object
6327+
fp_like = obj_or_path
6328+
fp_like, mm = _maybe_make_mmap(fp_like, mode, use_mmap=use_mmap, mmap_size=mmap_size)
6329+
return FileLikeAdapter(fp_like, mode=mode, mm=mm)
62626330

62636331
# Assumes you already have: compressionsupport, outextlistwd, MkTempFile, etc.
62646332

0 commit comments

Comments
 (0)