132 lines
4.5 KiB
Markdown
132 lines
4.5 KiB
Markdown
[](https://github.com/enarx/ciborium/actions?query=workflow%3A%22test%22)
|
|
[](https://isitmaintained.com/project/enarx/ciborium "Average time to resolve an issue")
|
|
[](https://isitmaintained.com/project/enarx/ciborium "Percentage of issues still open")
|
|

|
|
|
|
# ciborium-ll
|
|
|
|
Low level CBOR parsing tools
|
|
|
|
This crate contains low-level types for encoding and decoding items in
|
|
CBOR. This crate is usable in both `no_std` and `no_alloc` environments.
|
|
To understand how this crate works, first we will look at the structure
|
|
of a CBOR item on the wire.
|
|
|
|
## Anatomy of a CBOR Item
|
|
|
|
This is a brief anatomy of a CBOR item on the wire.
|
|
|
|
```
|
|
+------------+-----------+
|
|
| | |
|
|
| Major | Minor |
|
|
| (3bits) | (5bits) |
|
|
| | |
|
|
+------------+-----------+
|
|
^ ^
|
|
| |
|
|
+-----+ +-----+
|
|
| |
|
|
| |
|
|
+----------------------------+--------------+
|
|
| | | |
|
|
| Prefix | Affix | Suffix |
|
|
| (1 byte) | (0-8 bytes) | (0+ bytes) |
|
|
| | | |
|
|
+------------+---------------+--------------+
|
|
|
|
| | |
|
|
+------------+---------------+--------------+
|
|
| |
|
|
v v
|
|
|
|
Header Body
|
|
```
|
|
|
|
The `ciborium` crate works by providing the `Decoder` and `Encoder` types
|
|
which provide input and output for a CBOR header (see: `Header`). From
|
|
there, you can either handle the body yourself or use the provided utility
|
|
functions.
|
|
|
|
For more information on the CBOR format, see
|
|
[RFC 7049](https://tools.ietf.org/html/rfc7049).
|
|
|
|
## Decoding
|
|
|
|
In order to decode CBOR, you will create a `Decoder` from a reader. The
|
|
decoder instance will allow you to `Decoder::pull()` `Header` instances
|
|
from the input.
|
|
|
|
Most CBOR items are fully contained in their headers and therefore have no
|
|
body. These items can be evaluated directly from the `Header` instance.
|
|
|
|
Bytes and text items have a body but do not contain child items. Since
|
|
both bytes and text values may be segmented, parsing them can be a bit
|
|
tricky. Therefore, we provide helper functions to parse these types. See
|
|
`Decoder::bytes()` and `Decoder::text()` for more details.
|
|
|
|
Array and map items have a body which contains child items. These can be
|
|
parsed by simply doing `Decoder::pull()` to parse the child items.
|
|
|
|
### Example
|
|
|
|
```rust
|
|
use ciborium_ll::{Decoder, Header};
|
|
use ciborium_io::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);
|
|
```
|
|
|
|
## Encoding
|
|
|
|
To encode values to CBOR, create an `Encoder` from a writer. The encoder
|
|
instance provides the `Encoder::push()` method to write a `Header` value
|
|
to the wire. CBOR item bodies can be written directly.
|
|
|
|
For bytes and text, there are the `Encoder::bytes()` and `Encoder::text()`
|
|
utility functions, respectively, which will properly segment the output
|
|
on the wire for you.
|
|
|
|
### Example
|
|
|
|
```rust
|
|
use ciborium_ll::{Encoder, Header};
|
|
use ciborium_io::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[..]);
|
|
```
|
|
|
|
License: Apache-2.0
|