Android Mainline Module Release 9560301,
Update TEST_MAPPING am: c0ee65054b am: c1c6232a79 am: 5c8531092c am: 39e6bd9c81

Original change:

Change-Id: I912d020fb94d39583f2cea4aa7818a87126e850f
tree: 56d8252eb446a9eeafd3be964bcba4265e8ecccc
  1. src/
  2. Android.bp
  3. Cargo.toml
  4. Cargo.toml.orig

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


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.


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.


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);


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.


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.text("Hello, World!", 7).unwrap();

// Validate our output
assert_eq!(b"\xa1\x07\x7f\x67Hello, \x66World!\xff", &buffer[..]);

License: Apache-2.0