- vqt6: 包装类统一补 __new__ 堆分配, 修"创建函数栈帧 alloca"被存进字段/跨帧返回后 _ptr 悬垂(传给 QLayout::addWidget 等即崩溃); 菜单类按依赖顺序前移, menuBar()/statusBar() 改返回裸指针; 接入 Qt6 Charts 并新增 _bridge_canvas(Canvas 手绘板 / Graph3D 软件 3D 网络图 / ChartView 折线图); 新增自绘 QRadioButton(圆环+内点, 过渡动画)、剪贴板、应用级字体族 API - 新增模块: gzip.vp(RFC1952/1951 解码器)、torch/(torch-lite 稠密张量 + conv/pool 前反向) - vipersimd: 新增 scalar_fma/add/mul/sqrt_array 未向量化对照内核(与对应 SIMD 版逐位一致) - w32: 新增 UTF-8/UTF-16 路径转换, CreateFile/CreateDirectory 走 W 系列, 修中文路径被按 GBK 误读; read_all 参数 max_count -> buf_size 并文档化"容量含终止符"契约 - requests: https 响应缓冲按需翻倍扩容(上限 256MB), 修 MB 级正文(如 MNIST .gz)被 4KB 静默截断 - vipermath: 重写 exp 为范围归约 + 短泰勒, 修负值发散(x=-30 得 3.7e10)与 NaN 触发 2^31 次缩放导致的卡死 - builtins: 新增 sizet/uzt 别名; stdarg: va_arg 参数 CType -> CPtr - chore: 删除 vendored jpeg change.log
427 lines
16 KiB
Plaintext
427 lines
16 KiB
Plaintext
import t, c
|
|
from stdint import *
|
|
import stdio
|
|
import stdlib
|
|
import w32.win32base
|
|
import w32.win32file
|
|
|
|
|
|
class MODE(t.CEnum):
|
|
R = 0
|
|
W = 1
|
|
A = 2
|
|
RP = 3
|
|
WP = 4
|
|
AP = 5
|
|
X = 6
|
|
XP = 7
|
|
|
|
|
|
class FRESULT(t.CEnum):
|
|
OK = 0
|
|
ERR = -1
|
|
ERR_CLOSED = -2
|
|
ERR_PERM = -3
|
|
ERR_IO = -4
|
|
ERR_NOTFOUND = -5
|
|
|
|
|
|
SEEK_SET: t.CDefine = 0
|
|
SEEK_CUR: t.CDefine = 1
|
|
SEEK_END: t.CDefine = 2
|
|
|
|
INVALID_SET_FILE_POINTER: t.CDefine = -1
|
|
|
|
SHARE_READ: t.CDefine = 0x00000001
|
|
SHARE_WRITE: t.CDefine = 0x00000002
|
|
SHARE_DELETE: t.CDefine = 0x00000004
|
|
|
|
|
|
def create_file_utf8(path: str, access: ULONG, share: ULONG, disposition: ULONG,
|
|
flags: ULONG) -> w32.win32base.HANDLE:
|
|
"""按路径编码打开/创建文件。
|
|
合法 UTF-8(源码字面量、Qt 返回的中文目录) → 转 UTF-16 走 CreateFileW;
|
|
非法 UTF-8(如命令行 argv 的 ANSI 串) → 退回 CreateFileA。详见 win32base"""
|
|
if w32.win32base.utf8_is_valid(path) == 0:
|
|
return w32.win32file.CreateFileA(path, access, share, None, disposition,
|
|
flags, None)
|
|
wp: w32.win32base.WCHARPTR = w32.win32base.utf8_to_utf16_dup(path)
|
|
if wp is None:
|
|
# 宽字符缓冲分配失败: 走 A 路径, 非 ASCII 路径在此自然失败并返回
|
|
# INVALID_HANDLE_VALUE(不掩盖错误, 只是复用同一失败出口)
|
|
return w32.win32file.CreateFileA(path, access, share, None, disposition,
|
|
flags, None)
|
|
h: w32.win32base.HANDLE = w32.win32file.CreateFileW(
|
|
t.CPtr(wp), access, share, None, disposition, flags, None)
|
|
stdlib.free(wp)
|
|
return h
|
|
|
|
|
|
class File:
|
|
handle: w32.win32base.HANDLE
|
|
closed: bool
|
|
can_read: bool
|
|
can_write: bool
|
|
is_append: bool
|
|
_share_mode: ULONG
|
|
|
|
def __init__(self, filename: str, mode: ULONG, share: ULONG = SHARE_READ):
|
|
self.closed = True
|
|
self.can_read = False
|
|
self.can_write = False
|
|
self.is_append = False
|
|
self._share_mode = share
|
|
|
|
access: ULONG = 0
|
|
disposition: ULONG = w32.win32file.OPEN_EXISTING
|
|
|
|
if mode == MODE.R:
|
|
access = w32.win32file.GENERIC_READ
|
|
disposition = w32.win32file.OPEN_EXISTING
|
|
self.can_read = True
|
|
elif mode == MODE.W:
|
|
access = w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_ALWAYS
|
|
self.can_write = True
|
|
elif mode == MODE.A:
|
|
access = w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.OPEN_ALWAYS
|
|
self.can_write = True
|
|
self.is_append = True
|
|
elif mode == MODE.RP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.OPEN_EXISTING
|
|
self.can_read = True
|
|
self.can_write = True
|
|
elif mode == MODE.WP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_ALWAYS
|
|
self.can_read = True
|
|
self.can_write = True
|
|
elif mode == MODE.AP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.OPEN_ALWAYS
|
|
self.can_read = True
|
|
self.can_write = True
|
|
self.is_append = True
|
|
elif mode == MODE.X:
|
|
access = w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_NEW
|
|
self.can_write = True
|
|
elif mode == MODE.XP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_NEW
|
|
self.can_read = True
|
|
self.can_write = True
|
|
else:
|
|
access = w32.win32file.GENERIC_READ
|
|
disposition = w32.win32file.OPEN_EXISTING
|
|
self.can_read = True
|
|
|
|
self.handle = create_file_utf8(
|
|
filename, access, self._share_mode, disposition,
|
|
w32.win32file.FILE_ATTRIBUTE_NORMAL
|
|
)
|
|
|
|
if self.handle == w32.win32base.INVALID_HANDLE_VALUE:
|
|
self.closed = True
|
|
return
|
|
|
|
self.closed = False
|
|
|
|
if self.is_append:
|
|
self.seek(0, SEEK_END)
|
|
|
|
def __enter__(self) -> 'File' | t.CPtr:
|
|
return self
|
|
|
|
def __exit__(self):
|
|
self.close()
|
|
|
|
def read(self, buf: bytes, count: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_read: return FRESULT.ERR_PERM
|
|
bytes_read: ULONG = 0
|
|
result: BOOL = w32.win32file.ReadFile(self.handle, buf, count, t.CPtr(c.Addr(bytes_read)), None)
|
|
if result == 0: return FRESULT.ERR_IO
|
|
return LONG(bytes_read)
|
|
|
|
def write(self, buf: bytes, count: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_write: return FRESULT.ERR_PERM
|
|
bytes_written: ULONG = 0
|
|
result: BOOL = w32.win32file.WriteFile(self.handle, buf, count, c.Addr(bytes_written), None)
|
|
if result == 0: return FRESULT.ERR_IO
|
|
return LONG(bytes_written)
|
|
|
|
def write_str(self, s: str) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_write: return FRESULT.ERR_PERM
|
|
length: ULONG = 0
|
|
p: bytes = s
|
|
while c.Deref(p) != 0:
|
|
length += 1
|
|
p += 1
|
|
return self.write(s, length)
|
|
|
|
def seek(self, offset: LONG, origin: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
result: LONG = w32.win32file.SetFilePointer(self.handle, offset, None, origin)
|
|
if result == -1: return FRESULT.ERR_IO
|
|
return result
|
|
|
|
def tell(self) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
return self.seek(0, SEEK_CUR)
|
|
|
|
def close(self) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
w32.win32base.CloseHandle(self.handle)
|
|
self.closed = True
|
|
return FRESULT.OK
|
|
|
|
def flush(self) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
w32.win32file.FlushFileBuffers(self.handle)
|
|
return FRESULT.OK
|
|
|
|
def size(self) -> LONGLONG:
|
|
if self.closed: return -1
|
|
li: w32.win32base.LARGE_INTEGER = w32.win32base.LARGE_INTEGER()
|
|
result: BOOL = w32.win32file.GetFileSizeEx(self.handle, t.CPtr(c.Addr(li)))
|
|
if result == 0: return -1
|
|
return li.QuadPart
|
|
|
|
def readline(self, buf: bytes, max_count: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_read: return FRESULT.ERR_PERM
|
|
if max_count < 2: return FRESULT.ERR
|
|
total: ULONG = 0
|
|
bytes_read: ULONG = 0
|
|
ch: t.CInt = 0
|
|
while total < max_count - 1:
|
|
bytes_read = 0
|
|
result: BOOL = w32.win32file.ReadFile(self.handle, buf + total, 1, t.CPtr(c.Addr(bytes_read)), None)
|
|
if result == 0 or bytes_read == 0: break
|
|
ch = c.Deref(buf + total)
|
|
total += 1
|
|
if ch == 10: break
|
|
if total < max_count:
|
|
buf[total] = 0
|
|
return LONG(total)
|
|
|
|
def read_all(self, buf: bytes, buf_size: ULONG) -> LONG:
|
|
"""把整个文件读进 buf 并写成 C 字符串(内部先 seek 到 0)
|
|
|
|
契约(注意与 write 的 count 口径不同):
|
|
buf_size 是缓冲区**容量, 含终止符** —— 最多读 buf_size-1 字节,
|
|
再在 buf[返回值] 写一个 NUL 字节, 故返回值 <= buf_size-1。
|
|
文件比 buf_size-1 更长时**静默截断**, 不报错; 要区分"读完了"还是
|
|
"被截断了", 请在调用前自己比一次 f.size()。
|
|
返回实际读到的字节数, 负数为错误码。"""
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_read: return FRESULT.ERR_PERM
|
|
if buf_size < 2: return FRESULT.ERR
|
|
file_size: LONGLONG = self.size()
|
|
if file_size < 0: return FRESULT.ERR_IO
|
|
to_read: ULONG = 0
|
|
if file_size < buf_size - 1:
|
|
to_read = ULONG(file_size)
|
|
else:
|
|
to_read = buf_size - 1
|
|
self.seek(0, SEEK_SET)
|
|
bytes_read: ULONG = 0
|
|
result: BOOL = w32.win32file.ReadFile(self.handle, buf, to_read, t.CPtr(c.Addr(bytes_read)), None)
|
|
if result == 0: return FRESULT.ERR_IO
|
|
if bytes_read < buf_size:
|
|
buf[bytes_read] = 0
|
|
return LONG(bytes_read)
|
|
|
|
|
|
class FileW:
|
|
handle: w32.win32base.HANDLE
|
|
closed: bool
|
|
can_read: bool
|
|
can_write: bool
|
|
is_append: bool
|
|
_share_mode: ULONG
|
|
|
|
def __init__(self, filename: w32.win32base.LPCWSTR, mode: ULONG, share: ULONG = SHARE_READ):
|
|
self.closed = True
|
|
self.can_read = False
|
|
self.can_write = False
|
|
self.is_append = False
|
|
self._share_mode = share
|
|
|
|
access: ULONG = 0
|
|
disposition: ULONG = w32.win32file.OPEN_EXISTING
|
|
|
|
if mode == MODE.R:
|
|
access = w32.win32file.GENERIC_READ
|
|
disposition = w32.win32file.OPEN_EXISTING
|
|
self.can_read = True
|
|
elif mode == MODE.W:
|
|
access = w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_ALWAYS
|
|
self.can_write = True
|
|
elif mode == MODE.A:
|
|
access = w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.OPEN_ALWAYS
|
|
self.can_write = True
|
|
self.is_append = True
|
|
elif mode == MODE.RP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.OPEN_EXISTING
|
|
self.can_read = True
|
|
self.can_write = True
|
|
elif mode == MODE.WP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_ALWAYS
|
|
self.can_read = True
|
|
self.can_write = True
|
|
elif mode == MODE.AP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.OPEN_ALWAYS
|
|
self.can_read = True
|
|
self.can_write = True
|
|
self.is_append = True
|
|
elif mode == MODE.X:
|
|
access = w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_NEW
|
|
self.can_write = True
|
|
elif mode == MODE.XP:
|
|
access = w32.win32file.GENERIC_READ | w32.win32file.GENERIC_WRITE
|
|
disposition = w32.win32file.CREATE_NEW
|
|
self.can_read = True
|
|
self.can_write = True
|
|
else:
|
|
access = w32.win32file.GENERIC_READ
|
|
disposition = w32.win32file.OPEN_EXISTING
|
|
self.can_read = True
|
|
|
|
self.handle = w32.win32file.CreateFileW(
|
|
filename, access, self._share_mode,
|
|
None, disposition, w32.win32file.FILE_ATTRIBUTE_NORMAL, None
|
|
)
|
|
|
|
if self.handle == w32.win32base.INVALID_HANDLE_VALUE:
|
|
self.closed = True
|
|
return
|
|
|
|
self.closed = False
|
|
|
|
if self.is_append:
|
|
self.seek(0, SEEK_END)
|
|
|
|
def __enter__(self) -> 'FileW' | t.CPtr:
|
|
return self
|
|
|
|
def __exit__(self):
|
|
self.close()
|
|
|
|
def read(self, buf: bytes, count: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_read: return FRESULT.ERR_PERM
|
|
bytes_read: ULONG = 0
|
|
result: BOOL = w32.win32file.ReadFile(self.handle, buf, count, t.CPtr(c.Addr(bytes_read)), None)
|
|
if result == 0: return FRESULT.ERR_IO
|
|
return LONG(bytes_read)
|
|
|
|
def write(self, buf: bytes, count: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_write: return FRESULT.ERR_PERM
|
|
bytes_written: ULONG = 0
|
|
result: BOOL = w32.win32file.WriteFile(self.handle, buf, count, t.CPtr(c.Addr(bytes_written)), None)
|
|
if result == 0: return FRESULT.ERR_IO
|
|
return LONG(bytes_written)
|
|
|
|
def write_str(self, s: str) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_write: return FRESULT.ERR_PERM
|
|
length: ULONG = 0
|
|
p: bytes = s
|
|
while c.Deref(p) != 0:
|
|
length += 1
|
|
p += 1
|
|
return self.write(s, length)
|
|
|
|
def seek(self, offset: LONG, origin: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
result: LONG = w32.win32file.SetFilePointer(self.handle, offset, None, origin)
|
|
if result == -1: return FRESULT.ERR_IO
|
|
return result
|
|
|
|
def tell(self) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
return self.seek(0, SEEK_CUR)
|
|
|
|
def close(self) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
w32.win32base.CloseHandle(self.handle)
|
|
self.closed = True
|
|
return FRESULT.OK
|
|
|
|
def flush(self) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
w32.win32file.FlushFileBuffers(self.handle)
|
|
return FRESULT.OK
|
|
|
|
def size(self) -> LONGLONG:
|
|
if self.closed: return -1
|
|
li: w32.win32base.LARGE_INTEGER = w32.win32base.LARGE_INTEGER()
|
|
result: BOOL = w32.win32file.GetFileSizeEx(self.handle, t.CPtr(c.Addr(li)))
|
|
if result == 0: return -1
|
|
return li.QuadPart
|
|
|
|
def readline(self, buf: bytes, max_count: ULONG) -> LONG:
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_read: return FRESULT.ERR_PERM
|
|
if max_count < 2: return FRESULT.ERR
|
|
total: ULONG = 0
|
|
bytes_read: ULONG = 0
|
|
ch: t.CInt = 0
|
|
while total < max_count - 1:
|
|
bytes_read = 0
|
|
result: BOOL = w32.win32file.ReadFile(self.handle, buf + total, 1, t.CPtr(c.Addr(bytes_read)), None)
|
|
if result == 0 or bytes_read == 0: break
|
|
ch = c.Deref(buf + total)
|
|
total += 1
|
|
if ch == 10: break
|
|
if total < max_count:
|
|
buf[total] = 0
|
|
return LONG(total)
|
|
|
|
def read_all(self, buf: bytes, buf_size: ULONG) -> LONG:
|
|
"""把整个文件读进 buf 并写成 C 字符串(内部先 seek 到 0)
|
|
|
|
契约(注意与 write 的 count 口径不同):
|
|
buf_size 是缓冲区**容量, 含终止符** —— 最多读 buf_size-1 字节,
|
|
再在 buf[返回值] 写一个 NUL 字节, 故返回值 <= buf_size-1。
|
|
文件比 buf_size-1 更长时**静默截断**, 不报错; 要区分"读完了"还是
|
|
"被截断了", 请在调用前自己比一次 f.size()。
|
|
返回实际读到的字节数, 负数为错误码。"""
|
|
if self.closed: return FRESULT.ERR_CLOSED
|
|
if not self.can_read: return FRESULT.ERR_PERM
|
|
if buf_size < 2: return FRESULT.ERR
|
|
file_size: LONGLONG = self.size()
|
|
if file_size < 0: return FRESULT.ERR_IO
|
|
to_read: ULONG = 0
|
|
if file_size < buf_size - 1:
|
|
to_read = ULONG(file_size)
|
|
else:
|
|
to_read = buf_size - 1
|
|
self.seek(0, SEEK_SET)
|
|
bytes_read: ULONG = 0
|
|
result: BOOL = w32.win32file.ReadFile(self.handle, buf, to_read, t.CPtr(c.Addr(bytes_read)), None)
|
|
if result == 0: return FRESULT.ERR_IO
|
|
if bytes_read < buf_size:
|
|
buf[bytes_read] = 0
|
|
return LONG(bytes_read)
|
|
|
|
|
|
def open(filename: str, mode: ULONG, share: ULONG = SHARE_READ) -> File | t.CPtr:
|
|
return File(filename, mode, share)
|
|
|
|
def openw(filename: w32.win32base.LPCWSTR, mode: ULONG, share: ULONG = SHARE_READ) -> FileW | t.CPtr:
|
|
return FileW(filename, mode, share)
|