Skip to content

Commit b8a6b8d

Browse files
committed
Small update
1 parent 537eaf6 commit b8a6b8d

1 file changed

Lines changed: 0 additions & 115 deletions

File tree

pyneofile/pyneofile.py

Lines changed: 0 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,121 +2457,6 @@ def GetBinaryFileType(infile, filestart=0, closefp=True):
24572457
# -------------- FALLBACK --------------
24582458
return False
24592459

2460-
def _get_seek_consts():
2461-
"""Return (SEEK_DATA, SEEK_HOLE) if supported, else (None, None)."""
2462-
seek_data = getattr(os, "SEEK_DATA", None)
2463-
seek_hole = getattr(os, "SEEK_HOLE", None)
2464-
if seek_data is None or seek_hole is None:
2465-
return None, None
2466-
return seek_data, seek_hole
2467-
2468-
def pack_sparse_to_stream(path, out_fp, bufsize=1024*1024):
2469-
"""
2470-
Write ONLY data extents from sparse file `path` into `out_fp`.
2471-
Returns: (logical_size, extents, stored_bytes)
2472-
extents: list of (offset, length) in logical file
2473-
stored_bytes: total bytes written to out_fp
2474-
"""
2475-
st = os.stat(path, follow_symlinks=False)
2476-
logical_size = int(st.st_size)
2477-
extents = []
2478-
stored = 0
2479-
2480-
SEEK_DATA, SEEK_HOLE = _get_seek_consts()
2481-
2482-
with open(path, "rb", buffering=0) as f:
2483-
if SEEK_DATA is not None and SEEK_HOLE is not None:
2484-
# Kernel knows where holes are (best, fastest, exact).
2485-
pos = 0
2486-
while pos < logical_size:
2487-
try:
2488-
data_off = os.lseek(f.fileno(), pos, SEEK_DATA)
2489-
except OSError:
2490-
break # no more data
2491-
try:
2492-
hole_off = os.lseek(f.fileno(), data_off, SEEK_HOLE)
2493-
except OSError:
2494-
hole_off = logical_size
2495-
if hole_off > logical_size:
2496-
hole_off = logical_size
2497-
2498-
length = hole_off - data_off
2499-
if length <= 0:
2500-
pos = max(pos + 1, hole_off)
2501-
continue
2502-
2503-
extents.append((data_off, length))
2504-
# copy that extent’s bytes into out_fp
2505-
os.lseek(f.fileno(), data_off, os.SEEK_SET)
2506-
remaining = length
2507-
while remaining:
2508-
chunk = f.read(min(bufsize, remaining))
2509-
if not chunk:
2510-
break
2511-
out_fp.write(chunk)
2512-
stored += len(chunk)
2513-
remaining -= len(chunk)
2514-
2515-
pos = hole_off
2516-
else:
2517-
# Portable fallback (no SEEK_HOLE/DATA): scan for non-zero blocks.
2518-
# Not perfect (won't detect "real zeros" vs "holes"), but works as a fallback.
2519-
block = 4096
2520-
pos = 0
2521-
while pos < logical_size:
2522-
chunk = f.read(block)
2523-
if not chunk:
2524-
break
2525-
if any(b != 0 for b in chunk):
2526-
off = pos
2527-
# extend this run while blocks have any non-zero
2528-
run = bytearray(chunk)
2529-
while True:
2530-
nxt = f.read(block)
2531-
if not nxt or not any(b != 0 for b in nxt):
2532-
if nxt:
2533-
# rewind one block if it was all-zero (we read too far)
2534-
f.seek(-len(nxt), os.SEEK_CUR)
2535-
break
2536-
run.extend(nxt)
2537-
extents.append((off, len(run)))
2538-
out_fp.write(run)
2539-
stored += len(run)
2540-
pos = off + len(run)
2541-
else:
2542-
pos += len(chunk)
2543-
2544-
out_fp.seek(0, os.SEEK_SET)
2545-
return logical_size, extents, stored
2546-
2547-
def write_sparse_to_fileobj(out_fp, logical_size, extents, in_fp, bufsize=1024*1024):
2548-
"""
2549-
Recreate sparse file layout into an already-open writable file-like object.
2550-
"""
2551-
out_fp.seek(0)
2552-
out_fp.truncate(int(logical_size))
2553-
2554-
for off, length in extents:
2555-
out_fp.seek(int(off), os.SEEK_SET)
2556-
remaining = int(length)
2557-
while remaining:
2558-
chunk = in_fp.read(min(bufsize, remaining))
2559-
if not chunk:
2560-
raise EOFError("Archive ended while reading sparse extent data")
2561-
out_fp.write(chunk)
2562-
remaining -= len(chunk)
2563-
2564-
def unpack_sparse_to_path(in_fp, out_path, logical_size, extents, bufsize=1024*1024):
2565-
os.makedirs(os.path.dirname(out_path) or ".", exist_ok=True)
2566-
2567-
with open(out_path, "wb") as f:
2568-
write_sparse_to_fileobj(f, logical_size, extents, in_fp, bufsize)
2569-
2570-
try:
2571-
f.flush()
2572-
os.fsync(f.fileno())
2573-
except Exception:
2574-
pass
25752460

25762461
def _is_valid_zlib_header(cmf, flg):
25772462
"""

0 commit comments

Comments
 (0)