将 zipfile 改为最简洁形式
This commit is contained in:
1 parent
4957ba5661
commit
9cef4d8b56
1 file changed
+26
-28
+26
-28
@@ -11,16 +11,14 @@
|
||||
# 成员名为原始 UTF-8 字节(写入时置 flag bit 11,读取时不自动解码)。
|
||||
#
|
||||
# 用法(对齐 Python 语义,只读模式自动把整个 zip 读入内存):
|
||||
# w: rawptr[zipfile.ZipFile] = zipfile.ZipFile("out.zip", "w")
|
||||
# w: zipfile.ZipFile* = zipfile.ZipFile("out.zip", "w")
|
||||
# w.write("a.txt", buf, buf_len) # 默认 ZIP_DEFLATED
|
||||
# w.close()
|
||||
#
|
||||
# r: rawptr[zipfile.ZipFile] = zipfile.ZipFile("out.zip", "r")
|
||||
# r: zipfile.ZipFile* = zipfile.ZipFile("out.zip", "r")
|
||||
# olen: sizet = 0
|
||||
# data: bytes = r.read("a.txt", &olen) # malloc 缓冲,用后 free
|
||||
# err = zipfile.error_code() / zipfile.error()
|
||||
|
||||
import t, c
|
||||
import stdlib
|
||||
import string
|
||||
import viperlib
|
||||
@@ -93,7 +91,7 @@ def error() -> str:
|
||||
# ============================================================
|
||||
def zf_strlen(s: bytes) -> sizet:
|
||||
n: sizet = 0
|
||||
while s is not None and c.Deref(s) != 0:
|
||||
while s is not None and *s != 0:
|
||||
n += 1
|
||||
s += 1
|
||||
return n
|
||||
@@ -159,7 +157,7 @@ def zf_read_all(h: wb.HANDLE, p: uint8*, n: sizet) -> int:
|
||||
if chunk > 0xFFFFFF00:
|
||||
chunk = 0xFFFFFF00
|
||||
bytes_read: ulong = 0
|
||||
ok: int = wf.ReadFile(h, p + done, ulong(chunk), c.Addr(bytes_read), None)
|
||||
ok: int = wf.ReadFile(h, p + done, ulong(chunk), &bytes_read, None)
|
||||
if ok == 0 or bytes_read == 0:
|
||||
global zipfile_error_code_val, zipfile_error_msg
|
||||
zipfile_error_code_val = ZIP_ERR_IO
|
||||
@@ -170,7 +168,7 @@ def zf_read_all(h: wb.HANDLE, p: uint8*, n: sizet) -> int:
|
||||
return ZIP_ERR_OK
|
||||
|
||||
|
||||
def zf_read_whole(path: str, out_len: rawptr[sizet]) -> uint8*:
|
||||
def zf_read_whole(path: str, out_len: sizet*) -> uint8*:
|
||||
if not out_len:
|
||||
zipfile_set_error(ZIP_ERR_OPEN, "out_len is None")
|
||||
return None
|
||||
@@ -181,7 +179,7 @@ def zf_read_whole(path: str, out_len: rawptr[sizet]) -> uint8*:
|
||||
zipfile_set_error_win(ZIP_ERR_OPEN, "cannot open file for reading", wb.GetLastError())
|
||||
return None
|
||||
li: wb.LARGE_INTEGER = wb.LARGE_INTEGER()
|
||||
ok_size: int = wf.GetFileSizeEx(h, t.CPtr(c.Addr(li)))
|
||||
ok_size: int = wf.GetFileSizeEx(h, &li)
|
||||
if ok_size == 0:
|
||||
wb.CloseHandle(h)
|
||||
zipfile_set_error(ZIP_ERR_IO, "cannot get file size")
|
||||
@@ -208,17 +206,17 @@ def zf_read_whole(path: str, out_len: rawptr[sizet]) -> uint8*:
|
||||
# ============================================================
|
||||
# 条目信息(目录项)
|
||||
# 注意: 节点为显式 calloc 分配
|
||||
# 由 ZipFile 负责释放——避免 GC 实例经 | t.CPtr 联合字段引用被回收。
|
||||
# 由 ZipFile 负责释放——避免 GC 实例经 Ptr 字段引用被回收。
|
||||
# ============================================================
|
||||
class ZipInfo:
|
||||
filename: bytes # 原始字节名(含 \0,zipfile 持有并负责释放)
|
||||
name_len: sizet
|
||||
compress_type: int # ZIP_STORED / ZIP_DEFLATED
|
||||
crc32: uint32
|
||||
filename: bytes # 原始字节名(含 \0,zipfile 持有并负责释放)
|
||||
name_len: sizet
|
||||
compress_type: int # ZIP_STORED / ZIP_DEFLATED
|
||||
crc32: uint32
|
||||
compress_size: sizet
|
||||
file_size: sizet
|
||||
file_size: sizet
|
||||
header_offset: sizet # 本地文件头偏移
|
||||
next: rawptr[ZipInfo] # 链表(保持写入/目录顺序)
|
||||
next: ZipInfo* # 链表(保持写入/目录顺序)
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -231,8 +229,8 @@ class ZipFile:
|
||||
fh: wb.HANDLE = None # 写模式句柄(裸 win32 CreateFileA)
|
||||
data: bytes = None # 读模式:整个归档的内存副本
|
||||
data_len: sizet = 0
|
||||
info_head: rawptr[ZipInfo] = None
|
||||
info_tail: rawptr[ZipInfo] = None
|
||||
info_head: ZipInfo* = None
|
||||
info_tail: ZipInfo* = None
|
||||
info_count: sizet = 0
|
||||
pos: sizet = 0 # 写模式当前偏移
|
||||
ok: int = 0 # 1 = 可正常使用
|
||||
@@ -273,12 +271,12 @@ class ZipFile:
|
||||
self.ok = 1
|
||||
|
||||
def _clear_infos(self):
|
||||
n: rawptr[ZipInfo] = self.info_head
|
||||
n: ZipInfo* = self.info_head
|
||||
while n is not None:
|
||||
if n.filename is not None:
|
||||
stdlib.free(n.filename)
|
||||
n.filename = None
|
||||
nxt: rawptr[ZipInfo] = n.next
|
||||
nxt: ZipInfo* = n.next
|
||||
n.next = None
|
||||
stdlib.free(n)
|
||||
n = nxt
|
||||
@@ -286,8 +284,8 @@ class ZipFile:
|
||||
self.info_tail = None
|
||||
self.info_count = 0
|
||||
|
||||
def _append_info(self) -> rawptr[ZipInfo]:
|
||||
node: rawptr[ZipInfo] = stdlib.calloc(1, ZipInfo.__sizeof__())
|
||||
def _append_info(self) -> ZipInfo*:
|
||||
node: ZipInfo* = stdlib.calloc(1, ZipInfo.__sizeof__())
|
||||
if not node:
|
||||
zipfile_set_error(ZIP_ERR_MEMORY, "out of memory")
|
||||
return None
|
||||
@@ -360,7 +358,7 @@ class ZipFile:
|
||||
if not dup:
|
||||
zipfile_set_error(ZIP_ERR_MEMORY, "out of memory")
|
||||
return ZIP_ERR_MEMORY
|
||||
node: rawptr[ZipInfo] = self._append_info()
|
||||
node: ZipInfo* = self._append_info()
|
||||
if node is None:
|
||||
stdlib.free(dup)
|
||||
return ZIP_ERR_MEMORY
|
||||
@@ -379,7 +377,7 @@ class ZipFile:
|
||||
def namelist_at(self, i: sizet) -> bytes:
|
||||
if self.ok == 0 or self.info_count == 0 or i >= self.info_count:
|
||||
return None
|
||||
n: rawptr[ZipInfo] = self.info_head
|
||||
n: ZipInfo* = self.info_head
|
||||
k: sizet = 0
|
||||
while n is not None:
|
||||
if k == i:
|
||||
@@ -388,10 +386,10 @@ class ZipFile:
|
||||
k += 1
|
||||
return None
|
||||
|
||||
def getinfo(self, name: str) -> rawptr[ZipInfo]:
|
||||
def getinfo(self, name: str) -> ZipInfo*:
|
||||
if self.ok == 0:
|
||||
return None
|
||||
n: rawptr[ZipInfo] = self.info_head
|
||||
n: ZipInfo* = self.info_head
|
||||
while n is not None:
|
||||
if n.filename is not None and string.strcmp(n.filename, name) == 0:
|
||||
return n
|
||||
@@ -410,7 +408,7 @@ class ZipFile:
|
||||
if self.mode != 0:
|
||||
zipfile_set_error(ZIP_ERR_MODE, "zip file is not open for reading")
|
||||
return None
|
||||
info: rawptr[ZipInfo] = self.getinfo(name)
|
||||
info: ZipInfo* = self.getinfo(name)
|
||||
if info is None:
|
||||
zipfile_set_error(ZIP_ERR_NOT_FOUND, "member not found")
|
||||
return None
|
||||
@@ -540,7 +538,7 @@ class ZipFile:
|
||||
if not dup:
|
||||
zipfile_set_error(ZIP_ERR_MEMORY, "out of memory")
|
||||
return ZIP_ERR_MEMORY
|
||||
node: rawptr[ZipInfo] = self._append_info()
|
||||
node: ZipInfo* = self._append_info()
|
||||
if node is None:
|
||||
stdlib.free(dup)
|
||||
return ZIP_ERR_MEMORY
|
||||
@@ -564,7 +562,7 @@ class ZipFile:
|
||||
zipfile_set_error(ZIP_ERR_MEMORY, "out of memory")
|
||||
return ZIP_ERR_MEMORY
|
||||
rc: int = ZIP_ERR_OK
|
||||
n: rawptr[ZipInfo] = self.info_head
|
||||
n: ZipInfo* = self.info_head
|
||||
while n is not None and rc == ZIP_ERR_OK:
|
||||
string.memset(hdr, 0, 46)
|
||||
zf_w32le(hdr, 0x02014B50)
|
||||
|
||||
Reference in new issue
Block a user