豫言 / 豫言操作系统压缩适配 @ 0.1.0
以云工原生 DecompressionStream 实现限量解压与 ZIP 条目校验。
说明.汉语.md
# 压缩云工适配
把公共[压缩接口](../../../豫言操作系统接口/压缩/规范.汉语.md)映射到云工宿主的原生 `DecompressionStream`,全部用豫言写在 `云工宿主`的句柄桥之上,不含宿主 JS。
- **数据进宿主一次**:条目数据经 `云工物字造字节` 变成宿主 Blob(越过值桥一次,至多 16 MiB),之后的切片、拼接和流都在宿主内完成。
- **解压路径**:`Blob.stream()` 经 `pipeThrough` 接入 `DecompressionStream`,豫言用 `云工读取流块安全` 逐块读取输出:先读块的 `byteLength`,累计超过最大输出就释放块句柄、取消读取器并返回状态 1,绝不把超限的块复制进 Wasm;流出错为状态 2;读完则把各块按“栈顶最新、邻近同量级则合并”的规则拼接(总复制量为 O(n log n)),只在结果处复制一次。块的大小由宿主决定(Node 为 16 KiB,本地 workerd 为 4 KiB)。
- **归档条目校验**:条目被包成 gzip 容器——10 字节头、条目的 deflate 流、8 字节尾(CRC-32 与 ISIZE,小端)——交给 `DecompressionStream('gzip')`,由平台校验。存储方法的数据先被包成 deflate 存储块:每块至多 65535 字节,块头是新建的 5 字节小 Blob,块体是原数据 Blob 的 `slice`,末块置 BFINAL;空数据产生一个空的末块。容器全部在宿主里用 Blob 拼接,不把大数据逐字节搬进豫言,也不在豫言里算 CRC-32。
- **区分状态 2 与 3**:存储方法先比较长度(大于最大输出为 1,不等于预期为 3);deflate 方法在 gzip 校验失败后用 raw deflate 复解一遍并按同一上限累计(超限 1、失败 2、成功则是 CRC-32 或大小不符 3)。真实 workerd 遇到 gzip 尾部校验失败时不先交出已解出的块,Node 则先交出,所以结论不依赖流先出块还是先报错。
- **句柄**:每个用到的宿主句柄(Blob、流、转换流、读取器、块、存储块头与切片)用毕即释放;测试在同一事件里反复解压不触及 4096 的句柄上限。
- **参数校验在豫言里做**:最大输出、输入长度、方法、CRC-32 范围、预期大小;违规抛出豫言异常(不是宿主 JS 错误)。
验证:Node 与 `wrangler 4.129.0` 的本地 workerd 都通过同一份测试(见 `一致性验证/`):与 `zlib.inflateRawSync`、`zlib.deflateRawSync`、`zlib.crc32` 对拍,覆盖存储块边界、压缩炸弹(200 MiB 输出取消于 1 MiB 上限,用时数毫秒至数十毫秒)与随机扰动对拍。
说明.文言.md
# 压缩云工适配
以云工宿主原生之 `DecompressionStream` 承公共[压缩公约](../../../豫言操作系统接口/压缩/规范.文言.md),悉以豫言书于 `云工宿主`句柄桥之上,不藏宿主 JS。
- **数据入宿主一次**:条目数据经 `云工物字造字节` 成宿主 Blob(越值桥一次,至多十六兆),此后之切、联、流皆于宿主内为之。
- **解压之径**:`Blob.stream()` 以 `pipeThrough` 接 `DecompressionStream`,豫言以 `云工读取流块安全` 逐块读出:先取块之 `byteLength`,累计逾出限则释块之柄、止读器而返状一,绝不复制逾限之块入 Wasm;流败为状二;读尽则依“顶者最新,邻者同量级则并”之法联诸块(总复制量为 n log n),惟于果处复制一次。块之大小由宿主定(Node 十六 KiB,本地 workerd 四 KiB)。
- **归档条目之验**:条目包为 gzip 容器——十字节首、条目之 deflate 流、八字节尾(CRC-32 与 ISIZE,小端)——授 `DecompressionStream('gzip')`,由平台验之。存之法之数据先包为 deflate 存储块:每块至多六万五千五百三十五字节,块首为新造之五字节小 Blob,块体为原数据 Blob 之 `slice`,末块置 BFINAL;数据空则造一空末块。容器皆于宿主以 Blob 联之,不逐字节搬大数据入豫言,亦不于豫言算 CRC-32。
- **别状二与三**:存之法先较其长(大于出限为一,不等所期为三);deflate 之法 gzip 验败后,以 raw deflate 复解一过而依同限累计(逾一、败二、成则为 CRC-32 或实数不合而三)。真 workerd 遇 gzip 尾验败,不先交已解之块,Node 则先交,故所断不依流先出块或先报错。
- **柄**:所用宿主柄(Blob、流、转换流、读器、块、存储块首与切片)用毕即释;试验于同一事内反复解压,不触四〇九六之柄限。
- **参数之校在豫言**:出限、入长、法、CRC-32 之界、所期实数;违者抛豫言之异(非宿主 JS 之错)。
验:Node 与 `wrangler 4.129.0` 本地 workerd 皆过同一试验(见 `一致性验证/`):与 `zlib.inflateRawSync`、`zlib.deflateRawSync`、`zlib.crc32` 对拍,覆存储块之边、压缩之炸(二百 MiB 之出,于一 MiB 之限取消,用时数毫秒至数十毫秒)及随机扰动之对拍。