Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Vanderhell/microcbor

Repository files navigation

microcbor

CI License: MIT C99 Zero Allocation

Minimal CBOR encoder/decoder for embedded systems.

C99 | Zero dependencies | Zero allocations | RFC 8949 subset | Portable

Why microcbor?

IoT devices send sensor data over MQTT, CoAP, or BLE. JSON is the default choice, but on a microcontroller it is expensive: string escaping, float-to-text conversion, quotes around every key, and a parser that needs to handle arbitrary nesting.

CBOR (RFC 8949) is a binary format that is often 30-50% smaller than JSON, trivial to encode, and fast to decode. microcbor provides a compact C99 implementation for small firmware and constrained runtimes.

/* Encode a telemetry message */
uint8_t buf[64];
mcbor_enc_t enc;
mcbor_enc_init(&enc, buf, sizeof(buf));
mcbor_enc_map(&enc, 3);
mcbor_enc_str(&enc, "temp"); mcbor_enc_float(&enc, 23.4f);
mcbor_enc_str(&enc, "hum"); mcbor_enc_uint(&enc, 55);
mcbor_enc_str(&enc, "ok"); mcbor_enc_bool(&enc, true);
/* Send buf[0..mcbor_enc_size(&enc)] over MQTT */
mqtt_publish("sensor/data", buf, mcbor_enc_size(&enc));

The same message in JSON would be {"temp":23.4,"hum":55,"ok":true} (35 bytes). In CBOR it fits in 26 bytes. On a LoRa link with a 51-byte payload limit, that difference matters.

Features

  • Sequential encoder that writes into a caller-provided buffer.
  • Sequential decoder with typed convenience helpers.
  • Zero-copy byte and text references for decode paths.
  • Sticky overflow detection so encode chains can be checked once at the end.
  • Compact integer encoding with automatic width selection.
  • RFC 8949 subset focused on embedded telemetry workloads.
  • No heap allocation and no external dependencies.

Scope

Implemented:

  • Unsigned and signed 32-bit integers
  • Booleans and null
  • Float32
  • Text strings and byte strings
  • Definite-length arrays and maps
  • Recursive skip for unknown or forward-compatible fields

Not implemented:

  • 64-bit integers
  • Indefinite-length items
  • Tags
  • Dynamic allocation

Quick Start

Encode

uint8_t buf[128];
mcbor_enc_t enc;
mcbor_enc_init(&enc, buf, sizeof(buf));
mcbor_enc_map(&enc, 2);
mcbor_enc_str(&enc, "device"); mcbor_enc_str(&enc, "sensor-01");
mcbor_enc_str(&enc, "temp"); mcbor_enc_float(&enc, 22.5f);
uint32_t size = mcbor_enc_size(&enc);
/* buf[0..size] contains valid CBOR */

Decode

mcbor_dec_t dec;
mcbor_dec_init(&dec, buf, size);
uint32_t count;
mcbor_dec_map(&dec, &count);
for (uint32_t i = 0; i < count; i++) {
 char key[24];
 uint32_t klen;
 mcbor_dec_str(&dec, key, sizeof(key), &klen);
 if (strcmp(key, "temp") == 0) {
 float temp;
 mcbor_dec_float(&dec, &temp);
 } else {
 mcbor_dec_skip(&dec);
 }
}

Build And Test

Minimal GCC build:

gcc -std=c99 -Wall -Wextra -Wpedantic -Werror -Iinclude src/mcbor.c tests/test_all.c -lm -o test_all
./test_all

Using the bundled test makefile:

cd tests
make

On Windows, use MinGW, MSYS2, or WSL if gcc and make are not already installed.

API At A Glance

Encoder

Function Description
mcbor_enc_init Initialize encoder with buffer
mcbor_enc_uint Encode unsigned integer
mcbor_enc_int Encode signed integer
mcbor_enc_bool Encode boolean
mcbor_enc_null Encode null
mcbor_enc_float Encode float32
mcbor_enc_str Encode NUL-terminated string
mcbor_enc_text Encode string with explicit length
mcbor_enc_bytes Encode byte array
mcbor_enc_array Begin definite-length array
mcbor_enc_map Begin definite-length map
mcbor_enc_size Get bytes written
mcbor_enc_overflow Check overflow flag

Decoder

Function Description
mcbor_dec_init Initialize decoder with buffer
mcbor_dec_next Decode next item generically
mcbor_dec_uint Decode unsigned integer
mcbor_dec_int Decode signed integer
mcbor_dec_bool Decode boolean
mcbor_dec_float Decode float32
mcbor_dec_str Decode string with copy and NUL terminator
mcbor_dec_bytes_ref Decode bytes as zero-copy reference
mcbor_dec_array Decode array header
mcbor_dec_map Decode map header
mcbor_dec_skip Skip next item, including nested items
mcbor_dec_remaining Return unread bytes
mcbor_dec_done Check whether input is fully consumed

Repository Layout

  • include/mcbor.h public API
  • src/mcbor.c implementation
  • tests/test_all.c unit and round-trip tests
  • docs/API_REFERENCE.md API notes
  • docs/DESIGN.md design decisions
  • docs/PORTING_GUIDE.md integration notes

Ecosystem

Library Integration
iotspool CBOR encode -> spool -> MQTT publish
microconf Export config as CBOR for OTA
microlog Log CBOR encode and decode errors

Project Status

microcbor is suitable for publishing as a focused embedded utility library. The main remaining quality lever after publishing is automated CI execution on GitHub.

License

MIT License. Copyright (c) 2026 Vanderhell. See LICENSE.

About

Minimal CBOR encoder/decoder for embedded systems written in portable C99, focused on zero-allocation telemetry and small firmware targets.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

AltStyle によって変換されたページ (->オリジナル) /