inflateSync
输入受损后,搜索可能的完全刷新边界。
完整章节与共同规则 ↗ecafc184cdf44b7f · 对应提交的原文 ↗先看本函数的前置条件和返回结果;可展开下方共同规则,查看整组接口的缓冲区与所有权要求。
int ZEXPORT inflateSync(z_streamp strm);
输入受损后,搜索可能的完全刷新边界。
定义域 受限定义域:数据错误后或恢复搜索期间的有效流,输入可读。
内存与状态效果 消费输入、修改状态,可能释放窗口。
前置条件 next_in 和 avail_in 描述可读范围。不使用输出。
返回与保证 先在缓冲的整字节、再在输入中搜索 00 00 ff ff,跨调用保留部分匹配。输入指针/计数和 total_in 按已搜索输入量推进。不产生输出,total_out 不变。
返回码 Z_OK 表示找到模式:重置历史和头部登记,保留总计数,可在后续块恢复解码。如果尚未读取头部,恢复使用 raw 模式;否则关闭尾部校验。仍未知的窗口大小变为 15。Z_DATA_ERROR 表示继续搜索;该搜索期间,普通 inflate 返回 Z_STREAM_ERROR。
边界情况 无输入且缓冲位少于八位时,返回 Z_BUF_ERROR,不发生变化。流检查失败不改变任何内容。找到的模式不一定是真正刷新点;即使是同步刷新边界,也可能需要此前历史。恢复不承诺有效后缀,也不承诺恢复校验和检查。不分配。
本组共同前提与范围
使用 inflate 流分批解码输入,同时控制输出空间。初始化时选择 zlib、gzip 或不带封装的 raw DEFLATE,随后提供更多输入或空间继续,直到完成、请求字典或发生错误。无论出现哪种结果,inflateEnd 都可释放解码器。整块缓冲区的 zlib 解码见 uncompress。
| 任务 | 条目 |
|---|---|
| 开始或复用 | 初始化、配置初始化、重置、新配置、保留历史 |
| 解码或提供元数据 | 解压、设置字典、读取历史、gzip 头 |
| 恢复或检查 | 同步搜索、同步点、位置标记、表使用量 |
| 调整或分支 | 预置位、校验、距离选项、复制 |
| 释放存储 | 结束 |
聚焦契约遵循固定版本的 inflate.c 和 zlib.h,采用默认 LP64 Linux 构建,启用 gzip,不启用可选的无效距离或严格距离模式。范围更广的已登记公开目标保持各自定义域。术语见契约约定,证明状态和剩余工作见进度。
公共条件
调用者与解码器各自保留不同的内容。调用者提供本轮输入和输出缓冲区;解码器保留当前解析阶段、尚未用完的位,以及可能供后续复制使用的历史。更换调用者的输出数组,并不会开始一个新解码任务。
next_in 是本轮未读输入的起点,avail_in 是可读字节数;next_out 是下一个输出位置,avail_out 是从这里开始的剩余可写字节数。例如一块 5 字节输出数组返回时剩余 2 字节空间,就说明本轮写入了 3 字节。先接走这些结果,再把指针和容量设置为下一块可写区域。
下列所有契约都有受限定义域。仅凭 C 指针类型,不能提供这里要求的存储、生命周期或调用历史。
- 有效流已成功初始化或复制,尚未结束,保留库拥有的状态,且不发生并发调用。使用默认分配器和释放函数。初始化调用接收可写、尚未有效初始化为流的对象,分配器字段为 NULL 或默认函数。
- 可读或可写范围在整个调用期间都具有所述容量。调用者范围与流及流拥有的存储分离。输入与输出范围不重叠。字典目标、已登记头部记录及其目标缓冲区彼此分离,也与流分离。使用已登记头部存储的调用还要求它与输入/输出范围分离。这些是聚焦定义域的显式限制。
- 调用者拥有流对象及缓冲区。库拥有状态和可选窗口。调用只改变自己的流、拥有的存储、所述输出范围和任何已登记头部目标。它绝不释放调用者缓冲区。
- 流检查拒绝时返回
Z_STREAM_ERROR,不发生变化,除非查询或复制契约另有说明。这覆盖 NULL 和可安全读取但未通过检查的记录,不覆盖悬空或任意指针。检查要求分配器、状态、状态的回指针和有效模式满足条件。 - 计数器使用 C 无符号位宽并回绕。没有契约假设分配成功。解码、字典或分配错误之后,仍可调用
inflateEnd。
flowchart LR
I["初始化"] --> F["inflate"]
F -->|"Z_NEED_DICT"| D["设置字典"] --> F
F -->|"更多空间或输入"| F
F -->|"结束或放弃"| E["结束"]
F -->|"数据错误"| R["重置或同步搜索"] --> F
形式化约定
ZlibF.Spec.Public.Goal.inflateSync
证明状态:未完成 · 证明记录与剩余工作
/-- `int inflateSync(z_streamp strm)`.
Search byte-aligned held bits before new input, retaining the partial marker match.
On success retain totals and restart at TYPE with validation disabled. -/
def Goal.inflateSync : Prop :=
∀ h r i z s input,
StreamReachable .inflate h r → Zlib.Inflate.Spec.Good h r i z s →
Zlib.Inflate.Spec.DefAlloc z → Bytes h z.next_in z.avail_in.toNat input →
∃ rc after z' s' used,
C.run (Zlib.Inflate.inflateSync (some r)) h = .ok (rc, after) ∧
Zlib.Inflate.Spec.Good after r i z' s' ∧ used ≤ input.length ∧
z'.next_in = advance z.next_in used ∧ z'.avail_in.toNat + used = z.avail_in.toNat ∧
z'.total_in = z.total_in + UInt64.ofNat used ∧ z'.total_out = z.total_out ∧
(if z.avail_in = 0 ∧ s.bits.toNat < 8 then rc = Z_BUF_ERROR ∧ z' = z ∧ s' = s
else let start := if s.mode = SYNC then s.have.toNat else
(Api.syncSearch 0 (heldSyncBytes s)).1
let found := Api.syncSearch start input
used = found.2 ∧
if found.1 = 4 then rc = Z_OK ∧ s'.mode = TYPE ∧ (s'.wrap &&& 4) = 0
else rc = Z_DATA_ERROR ∧ s'.mode = SYNC ∧ s'.have.toNat = found.1) ∧
Frame h after (fun b => StreamRoot r b ∨ InflateOwned i s b) ∧
LiveChange h after (fun _ => False)
(fun b => InflateOwned i s b ∧ ¬ InflateOwned i s' b)相关定义与源码 ↗