0.1.0 |
|
---|
#95 in #cbor
56KB
931 代码行
这是为了发布在#25中提出的更改而创建的一个临时分支。不要使用此分支,而应使用ciborium。
ciborium-ll
低级别CBOR解析工具
本库包含用于在CBOR中编码和解码项的低级别类型。此库可以在no_std
和no_alloc
环境中使用。要了解此库的工作原理,我们首先将查看网络中CBOR项的结构。
CBOR项的解剖
这是网络中CBOR项的简要解剖。
+------------+-----------+
| | |
| Major | Minor |
| (3bits) | (5bits) |
| | |
+------------+-----------+
^ ^
| |
+-----+ +-----+
| |
| |
+----------------------------+--------------+
| | | |
| Prefix | Affix | Suffix |
| (1 byte) | (0-8 bytes) | (0+ bytes) |
| | | |
+------------+---------------+--------------+
| | |
+------------+---------------+--------------+
| |
v v
Header Body
ciborium
库通过提供Decoder
和Encoder
类型来实现,这些类型提供CBOR头部(见:Header
)的输入和输出。从那里,您可以自己处理主体或使用提供的实用函数。
有关CBOR格式的更多信息,请参阅RFC 7049。
解码
为了解码CBOR,您需要从一个读取器创建一个Decoder
实例。解码器实例将允许您从输入中提取Header
实例。
大多数CBOR项完全包含在其头部中,因此没有主体。这些项可以直接从Header
实例中进行评估。
字节和文本项有主体但没有子项。由于字节和文本值可能分段,因此解析它们可能有些棘手。因此,我们提供了辅助函数来解析这些类型。有关更多详细信息,请参阅Decoder::bytes()
和Decoder::text()
。
数组映射项包含子项的主体。可以通过简单地执行 Decoder::pull()
来解析子项。
示例
use ciborium_llvalue::{Decoder, Header};
use ciborium_iovalue::Read as _;
let input = b"\x6dHello, World!";
let mut decoder = Decoder::from(&input[..]);
let mut chunks = 0;
match decoder.pull().unwrap() {
Header::Text(len) => {
let mut segments = decoder.text(len);
while let Some(mut segment) = segments.pull().unwrap() {
let mut buffer = [0u8; 7];
while let Some(chunk) = segment.pull(&mut buffer[..]).unwrap() {
match chunk {
"Hello, " if chunks == 0 => chunks = 1,
"World!" if chunks == 1 => chunks = 2,
_ => panic!("received unexpected chunk"),
}
}
}
}
_ => panic!("received unexpected value"),
}
assert_eq!(chunks, 2);
编码
要将值编码为CBOR,从一个写入器创建一个 Encoder
。编码器实例提供了一个 Encoder::push()
方法来将 Header
值写入线。CBOR项的主体可以直接写入。
对于字节和文本,有分别的 Encoder::bytes()
和 Encoder::text()
工具函数,它们将正确地将输出分段写入线。
示例
use ciborium_llvalue::{Encoder, Header};
use ciborium_iovalue::Write as _;
let mut buffer = [0u8; 19];
let mut encoder = Encoder::from(&mut buffer[..]);
// Write the structure
encoder.push(Header::Map(Some(1))).unwrap();
encoder.push(Header::Positive(7)).unwrap();
encoder.text("Hello, World!", 7).unwrap();
// Validate our output
encoder.flush().unwrap();
assert_eq!(b"\xa1\x07\x7f\x67Hello, \x66World!\xff", &buffer[..]);
许可证:Apache-2.0
依赖项
~250KB