File syn_cbor_write.c¶
File List > src > syntropic > util > syn_cbor_write.c
Go to the documentation of this file
#if __has_include("syn_config.h")
#include "syn_config.h"
#endif
#if !defined(SYN_USE_CBOR) || SYN_USE_CBOR
#include "syn_cbor_write.h"
#include <string.h>
static void emit_byte(SYN_CborWriter *w, uint8_t b)
{
if (w->overflow)
return;
if (w->len >= w->cap) {
w->overflow = true;
return;
}
w->buf[w->len++] = b;
}
static void emit_raw(SYN_CborWriter *w, const void *data, size_t n)
{
const uint8_t *p = (const uint8_t *)data;
size_t i;
for (i = 0u; i < n; i++) {
emit_byte(w, p[i]);
}
}
static void emit_head(SYN_CborWriter *w, uint8_t major, uint64_t val)
{
uint8_t mt = (uint8_t)((major & 0x07u) << 5u);
if (val <= 23u) {
emit_byte(w, mt | (uint8_t)val);
} else if (val <= 0xFFu) {
emit_byte(w, mt | 24u);
emit_byte(w, (uint8_t)val);
} else if (val <= 0xFFFFu) {
emit_byte(w, mt | 25u);
emit_byte(w, (uint8_t)(val >> 8u));
emit_byte(w, (uint8_t)(val));
} else if (val <= 0xFFFFFFFFu) {
emit_byte(w, mt | 26u);
emit_byte(w, (uint8_t)(val >> 24u));
emit_byte(w, (uint8_t)(val >> 16u));
emit_byte(w, (uint8_t)(val >> 8u));
emit_byte(w, (uint8_t)(val));
} else {
emit_byte(w, mt | 27u);
emit_byte(w, (uint8_t)(val >> 56u));
emit_byte(w, (uint8_t)(val >> 48u));
emit_byte(w, (uint8_t)(val >> 40u));
emit_byte(w, (uint8_t)(val >> 32u));
emit_byte(w, (uint8_t)(val >> 24u));
emit_byte(w, (uint8_t)(val >> 16u));
emit_byte(w, (uint8_t)(val >> 8u));
emit_byte(w, (uint8_t)(val));
}
}
void syn_cbor_writer_init(SYN_CborWriter *w, uint8_t *buf, size_t cap)
{
w->buf = buf;
w->cap = cap;
w->len = 0u;
w->overflow = false;
}
/* ── Collections ─────────────────────────────────────────────────────────── */
void syn_cbor_write_map_begin(SYN_CborWriter *w, size_t count)
{
emit_head(w, 5u, (uint64_t)count);
}
void syn_cbor_write_array_begin(SYN_CborWriter *w, size_t count)
{
emit_head(w, 4u, (uint64_t)count);
}
/* ── Scalars ─────────────────────────────────────────────────────────────── */
void syn_cbor_write_uint(SYN_CborWriter *w, uint64_t v)
{
emit_head(w, 0u, v);
}
void syn_cbor_write_int(SYN_CborWriter *w, int64_t v)
{
if (v >= 0) {
emit_head(w, 0u, (uint64_t)v);
} else {
/* CBOR negative: major type 1, value = -1 - v */
emit_head(w, 1u, (uint64_t)(-1 - v));
}
}
void syn_cbor_write_float(SYN_CborWriter *w, float v)
{
/* 0xFA = major type 7, info=26 (float32) */
emit_byte(w, 0xFAu);
/* Reinterpret float bits as uint32 — no UB via memcpy */
uint32_t bits = 0u;
memcpy(&bits, &v, sizeof(bits));
/* Emit big-endian */
emit_byte(w, (uint8_t)(bits >> 24u));
emit_byte(w, (uint8_t)(bits >> 16u));
emit_byte(w, (uint8_t)(bits >> 8u));
emit_byte(w, (uint8_t)(bits));
}
void syn_cbor_write_bool(SYN_CborWriter *w, bool v)
{
emit_byte(w, v ? 0xF5u : 0xF4u);
}
void syn_cbor_write_null(SYN_CborWriter *w)
{
emit_byte(w, 0xF6u);
}
/* ── Strings ─────────────────────────────────────────────────────────────── */
void syn_cbor_write_text(SYN_CborWriter *w, const char *str, size_t len)
{
emit_head(w, 3u, (uint64_t)len);
emit_raw(w, str, len);
}
void syn_cbor_write_text_cstr(SYN_CborWriter *w, const char *str)
{
size_t len = strlen(str);
syn_cbor_write_text(w, str, len);
}
void syn_cbor_write_bytes(SYN_CborWriter *w, const uint8_t *data, size_t len)
{
emit_head(w, 2u, (uint64_t)len);
emit_raw(w, data, len);
}
#endif /* SYN_USE_CBOR */