Skip to content

Commit 6cbc863

Browse files
authored
Add files via upload
1 parent 8bfdb2c commit 6cbc863

1 file changed

Lines changed: 98 additions & 44 deletions

File tree

pycatfile.py

Lines changed: 98 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,59 +1557,113 @@ def DetectTarBombCatFileArray(listarrayfiles,
15571557
}
15581558

15591559

1560-
def MkTempFile(data=None, inmem=__use_inmemfile__, isbytes=True, prefix=__project__,
1561-
delete=True, encoding="utf-8"):
1560+
def _normalize_initial_data(data, isbytes, encoding):
15621561
"""
1563-
Return a file-like handle.
1564-
- If inmem=True: returns StringIO (text) or BytesIO (bytes).
1565-
- If inmem=False: returns a NamedTemporaryFile opened in text or binary mode.
1566-
Args:
1567-
data: optional initial content; if provided, it's written and the handle is seek(0)
1568-
inmem: bool — return in-memory handle if True
1569-
isbytes: bool — choose bytes (True) or text (False)
1570-
prefix: str — tempfile prefix
1571-
delete: bool — whether the tempfile is deleted on close (NamedTemporaryFile)
1572-
encoding: str — used for text mode (and for conversions when needed)
1562+
Coerce `data` to the correct type for the chosen mode:
1563+
- bytes mode: return `bytes` (Py2: str; Py3: bytes)
1564+
- text mode : return unicode/str (Py2: unicode; Py3: str)
15731565
"""
1574-
init = _normalize_initial_data(data, isbytes, encoding)
1575-
1576-
if inmem:
1577-
buf = BytesIO() if isbytes else StringIO()
1578-
if init is not None:
1579-
buf.write(init)
1580-
buf.seek(0)
1581-
return buf
1582-
1583-
mode = "wb+" if isbytes else "w+"
1584-
kwargs = {"prefix": prefix or "", "delete": delete, "mode": mode}
1566+
if data is None:
1567+
return None
15851568

1586-
# Only Python 3's text-mode files accept encoding/newline explicitly
1587-
if not isbytes and sys.version_info[0] >= 3:
1588-
kwargs["encoding"] = encoding
1589-
kwargs["newline"] = ""
1569+
if isbytes:
1570+
# Need a byte sequence
1571+
if isinstance(data, bytes):
1572+
return data
1573+
if isinstance(data, bytearray):
1574+
return bytes(data)
1575+
# memoryview may not exist on very old Py2 builds; guard dynamically
1576+
mv_t = getattr(__builtins__, 'memoryview', type(None))
1577+
if isinstance(data, mv_t):
1578+
return bytes(data)
1579+
if isinstance(data, str):
1580+
# Py2 str is already bytes; Py3 str must be encoded
1581+
return data if PY2 else data.encode(encoding)
1582+
if PY2 and isinstance(data, unicode): # noqa: F821 (unicode only in Py2)
1583+
return data.encode(encoding)
1584+
raise TypeError("data must be bytes-like or text for isbytes=True (got %r)" % (type(data),))
1585+
else:
1586+
# Need text (unicode in Py2, str in Py3)
1587+
if PY2:
1588+
if isinstance(data, unicode): # noqa: F821
1589+
return data
1590+
if isinstance(data, str):
1591+
return data.decode(encoding)
1592+
if isinstance(data, bytearray):
1593+
return bytes(data).decode(encoding)
1594+
mv_t = getattr(__builtins__, 'memoryview', type(None))
1595+
if isinstance(data, mv_t):
1596+
return bytes(data).decode(encoding)
1597+
raise TypeError("data must be unicode or bytes-like for text mode (got %r)" % (type(data),))
1598+
else:
1599+
if isinstance(data, str):
1600+
return data
1601+
if isinstance(data, (bytes, bytearray, memoryview)):
1602+
return bytes(data).decode(encoding)
1603+
raise TypeError("data must be str or bytes-like for text mode (got %r)" % (type(data),))
1604+
1605+
def MkTempFile(data=None,
1606+
inmem=True,
1607+
isbytes=True,
1608+
prefix="",
1609+
delete=True,
1610+
encoding="utf-8",
1611+
newline=None, # Py3 text only; ignored by Py2 temp classes
1612+
dir=None,
1613+
suffix="",
1614+
# spooled option (RAM until threshold, then rolls to disk)
1615+
use_spool=False,
1616+
spool_max=8 * 1024 * 1024,
1617+
spool_dir=None):
1618+
"""
1619+
Return a file-like handle with consistent behavior on Py2.7 and Py3.x.
15901620

1591-
f = tempfile.NamedTemporaryFile(**kwargs)
1621+
- inmem=True -> BytesIO (bytes) or StringIO (text)
1622+
- inmem=False, use_spool=True -> SpooledTemporaryFile (RAM -> disk after spool_max)
1623+
- inmem=False, use_spool=False -> NamedTemporaryFile (on disk)
15921624

1593-
if init is not None:
1594-
f.write(init)
1595-
f.seek(0)
1596-
return f
1625+
If `data` is provided, it's written and the handle is rewound to position 0.
1626+
"""
1627+
init = _normalize_initial_data(data, isbytes, encoding)
15971628

1629+
# -------- In-memory --------
1630+
if inmem:
1631+
if isbytes:
1632+
return BytesIO(init if init is not None else b"")
1633+
else:
1634+
# Py2 needs unicode literal for empty default
1635+
return StringIO(init if init is not None else (u"" if PY2 else ""))
15981636

1599-
def MkTempFileSmart(data=None, isbytes=True, prefix=__project__, max_mem=1024*1024, encoding="utf-8"):
1600-
"""
1601-
Spooled temp file: starts in memory and spills to disk past max_mem.
1602-
Behaves like BytesIO/StringIO for small data, with the same preload+seek(0) behavior.
1603-
"""
1604-
mode = "wb+" if isbytes else "w+"
1605-
kwargs = {"mode": mode, "max_size": max_mem, "prefix": prefix or ""}
1606-
if not isbytes and sys.version_info[0] >= 3:
1607-
kwargs["encoding"] = encoding
1608-
kwargs["newline"] = ""
1637+
# -------- Spooled (RAM then disk) --------
1638+
if use_spool:
1639+
if isbytes:
1640+
f = tempfile.SpooledTemporaryFile(max_size=spool_max, mode="w+b", dir=spool_dir)
1641+
else:
1642+
if PY2:
1643+
# Py2 SpooledTemporaryFile doesn't accept encoding/newline
1644+
f = tempfile.SpooledTemporaryFile(max_size=spool_max, mode="w+", dir=spool_dir)
1645+
else:
1646+
f = tempfile.SpooledTemporaryFile(max_size=spool_max, mode="w+",
1647+
dir=spool_dir, encoding=encoding, newline=newline)
1648+
if init is not None:
1649+
f.write(init)
1650+
f.seek(0)
1651+
return f
16091652

1610-
f = tempfile.SpooledTemporaryFile(**kwargs)
1653+
# -------- On-disk temp --------
1654+
if isbytes:
1655+
f = tempfile.NamedTemporaryFile(mode="w+b", prefix=prefix or "", suffix=suffix,
1656+
dir=dir, delete=delete)
1657+
else:
1658+
if PY2:
1659+
# Py2 temp files don't accept encoding/newline; writes of unicode will be encoded
1660+
# using the default encoding. If you need strict control, wrap with codecs/io.open.
1661+
f = tempfile.NamedTemporaryFile(mode="w+", prefix=prefix or "", suffix=suffix,
1662+
dir=dir, delete=delete)
1663+
else:
1664+
f = tempfile.NamedTemporaryFile(mode="w+", prefix=prefix or "", suffix=suffix,
1665+
dir=dir, delete=delete, encoding=encoding, newline=newline)
16111666

1612-
init = _normalize_initial_data(data, isbytes, encoding)
16131667
if init is not None:
16141668
f.write(init)
16151669
f.seek(0)

0 commit comments

Comments
 (0)