# Qubit Binary Codec 用户指南
`qubit-codec-binary` 提供缓冲区级 binary codec,适合 parser、二进制格式和
已经自行管理 buffer 的 stream adapter。
## 层次
- 使用 `BinaryCodec<T, O>` 处理明确位宽的 primitive integer 和浮点数。
- 使用 `Leb128Codec<T, P>` 处理 unsigned / signed LEB128 值。
- 当有符号值通常接近零、包括负数也要保持紧凑时,使用 `ZigZagCodec<T, P>`。
- 使用 `Strict` 拒绝非 canonical LEB128 payload,使用 `NonStrict` 做宽松解码。
本库只重导出属于 binary codec 表面的必要 `qubit-codec` 原语:`Codec`、
`ByteOrder`、`ByteOrderSpec`、`BigEndian` 和 `LittleEndian`。同时暴露 sealed
`Leb128DecodePolicy` trait,用于内置 LEB128 policy marker。通用 adapter、
engine、hook 和 value trait 请直接从 `qubit-codec` 引入。
## Fixed-Width 值
`BinaryCodec` 支持 `u8`、`i8`、`u16`、`i16`、`u32`、`i32`、`u64`、`i64`、
`u128`、`i128`、`f32` 和 `f64`。它不实现 `usize` 或 `isize`,因为它们的
字节宽度依赖目标平台。
```rust
use qubit_codec_binary::{
BigEndian,
BinaryCodec,
};
let mut output = [0_u8; BinaryCodec::<u32, BigEndian>::MAX_UNITS_PER_VALUE];
unsafe {
BinaryCodec::<u32, BigEndian>::encode_unchecked(0x0102_0304, &mut output, 0);
}
assert_eq!([1, 2, 3, 4], output);
```
这些 unchecked API 面向调用方已经验证过 buffer 容量的热路径。
## LEB128 与 ZigZag
```rust
use qubit_codec_binary::{
Leb128Codec,
NonStrict,
ZigZagCodec,
};
let mut unsigned = [0_u8; Leb128Codec::<u64, NonStrict>::MAX_UNITS_PER_VALUE];
let written = unsafe { Leb128Codec::<u64, NonStrict>::encode_unchecked(300, &mut unsigned, 0) };
assert_eq!(2, written);
let mut signed = [0_u8; ZigZagCodec::<i64, NonStrict>::MAX_UNITS_PER_VALUE];
let written = unsafe { ZigZagCodec::<i64, NonStrict>::encode_unchecked(-42, &mut signed, 0) };
assert_eq!(1, written);
```
`MIN_UNITS_PER_VALUE` 适合用于判断是否可以开始解码。
`MAX_UNITS_PER_VALUE` 是容量上界,适合用于分配输出 buffer,或者在调用方无法
证明终止字节位置时保证最大可读范围。
## LEB128 解码错误
`Leb128DecodeError` 区分当前值的起点和错误被发现的位置:
- `start_index()` 返回当前尝试解码的值从哪个字节开始。
- `error_index()` 返回解码发现错误的位置。对于 incomplete input,它是当前可用
输入之后、下一字节应出现的边界。
- `required()`、`available()` 和 `additional()` 描述 incomplete input。
- `consumed()` 描述 malformed 或 non-canonical input 后调用方可以消费多少
无效字节。
## Unsafe 边界
这些 codec 是低层构件。unchecked 方法不负责发现 buffer 空间是否足够:
- Fixed-width `BinaryCodec` 的 decode 和 encode 调用要求从给定 index 开始有
`MIN_UNITS_PER_VALUE` 个可读字节或 `MAX_UNITS_PER_VALUE` 个可写字节。
对于 fixed-width 值,这两个边界相等。
- LEB128 和 ZigZag 的 encode 调用要求从给定 index 开始有
`MAX_UNITS_PER_VALUE` 个可写字节。
- LEB128 和 ZigZag 的 decode 调用要求从给定 index 开始至少有
`MIN_UNITS_PER_VALUE` 个可读字节。调用方通常应尽量提供到
`MAX_UNITS_PER_VALUE`,除非 EOF 已经无法继续读取。
- 如果 EOF 导致调用方无法提供足够字节来完成一个变长值,上层应把该值作为
`Leb128DecodeError` 中的不完整值处理。
对外暴露安全 API 时,应先验证这些条件,再跨过 unsafe 边界。
## 安全 Adapter 与 Stream
本 crate 刻意停留在 buffer-level binary codec 层。owned single-value adapter、
通用 buffered engine 或 conversion trait 请直接从 `qubit-codec` 引入,并把这些
binary codec 作为低层 codec 实现使用。
如果自行封装 `decode_unchecked`,调用 unsafe 方法前要先检查起始 index 后至少有
`MIN_UNITS_PER_VALUE` 个可读字节。对于 single-value decoder,还需要由你的格式决定
返回的 `consumed` 之后是否允许 trailing bytes。
如果需要围绕这些 codec 的 `std::io::Read` / `Write` adapter,请使用
`qubit-io-binary`。