#cbor #low-level #codec #header #parser #decoder #ciborium

已撤回 ciborium-llvalue

低级别CBOR编解码器原语

0.1.0 2021年11月20日

#95 in #cbor


用于 ciboriumvalue

Apache-2.0

56KB
931 代码行

这是为了发布在#25中提出的更改而创建的一个临时分支。不要使用此分支,而应使用ciborium

Workflow Status Average time to resolve an issue Percentage of issues still open Maintenance

ciborium-ll

低级别CBOR解析工具

本库包含用于在CBOR中编码和解码项的低级别类型。此库可以在no_stdno_alloc环境中使用。要了解此库的工作原理,我们首先将查看网络中CBOR项的结构。

CBOR项的解剖

这是网络中CBOR项的简要解剖。

+------------+-----------+
|            |           |
|   Major    |   Minor   |
|  (3bits)   |  (5bits)  |
|            |           |
+------------+-----------+
^                        ^
|                        |
+-----+            +-----+
      |            |
      |            |
      +----------------------------+--------------+
      |            |               |              |
      |   Prefix   |     Affix     |    Suffix    |
      |  (1 byte)  |  (0-8 bytes)  |  (0+ bytes)  |
      |            |               |              |
      +------------+---------------+--------------+

      |                            |              |
      +------------+---------------+--------------+
                   |                       |
                   v                       v

                 Header                   Body

ciborium库通过提供DecoderEncoder类型来实现,这些类型提供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