10static const char*
TAG =
"CBOR";
52 if (w->offset >= w->size) {
57 w->buffer[w->offset++] = b;
66static void write_bytes(cbor_writer_t *w,
const uint8_t *data,
size_t len) {
68 if (w->offset + len > w->size) {
70 LOG_E(
TAG,
"Write overflow (need %d, have %d)", len, w->size - w->offset);
73 memcpy(w->buffer + w->offset, data, len);
84 uint8_t major = type << 5;
88 }
else if (value <= 0xFF) {
91 }
else if (value <= 0xFFFF) {
95 }
else if (value <= 0xFFFFFFFF) {
144 if (len > 0 && data) {
155 size_t len = str ? strlen(str) : 0;
170 if (len > 0 && str) {
301 return !r->error && r->offset < r->size;
310 if (r->error || r->offset >= r->size)
return -1;
311 return r->data[r->offset] >> 5;
321 if (r->error)
return false;
322 if (r->offset >= r->size) {
327 *b = r->data[r->offset++];
340 if (!
read_byte(r, &initial))
return false;
342 *type = initial >> 5;
343 uint8_t info = initial & 0x1F;
347 }
else if (info == 24) {
351 }
else if (info == 25) {
354 *value = ((uint16_t)b[0] << 8) | b[1];
355 }
else if (info == 26) {
357 for (
int i = 0; i < 4; i++) {
360 *value = ((uint32_t)b[0] << 24) | ((uint32_t)b[1] << 16) |
361 ((uint32_t)b[2] << 8) | b[3];
362 }
else if (info == 27) {
364 for (
int i = 0; i < 8; i++) {
367 *value = ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) |
368 ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) |
369 ((uint64_t)b[4] << 24) | ((uint64_t)b[5] << 16) |
370 ((uint64_t)b[6] << 8) | b[7];
371 }
else if (info == 31) {
374 LOG_E(
TAG,
"Indefinite length not supported");
378 LOG_E(
TAG,
"Invalid additional info: %d", info);
404 if (r->offset + value > r->size) {
408 item->bytes = r->data + r->offset;
409 item->length = value;
444 *value = (int64_t)item.value;
446 *value = -1 - (int64_t)item.value;
462bool cbor_read_bytes(cbor_reader_t *r, uint8_t *out,
size_t max_len,
size_t *out_len) {
470 size_t copy_len = (item.length < max_len) ? item.length : max_len;
471 if (out && copy_len > 0) {
472 memcpy(out, item.bytes, copy_len);
474 if (out_len) *out_len = copy_len;
486bool cbor_read_text(cbor_reader_t *r,
char *out,
size_t max_len,
size_t *out_len) {
487 if (max_len == 0)
return false;
496 size_t copy_len = (item.length < max_len - 1) ? item.length : (max_len - 1);
497 if (out && copy_len > 0) {
498 memcpy(out, item.bytes, copy_len);
500 if (out && max_len > 0) {
501 out[copy_len] =
'\0';
503 if (out_len) *out_len = copy_len;
541 return (
int)item.value;
556 return (
int)item.value;
560#define CBOR_MAX_RECURSION_DEPTH 8
561#define CBOR_MAX_CONTAINER_SIZE 256
565 LOG_W(
TAG,
"Max recursion depth exceeded");
575 LOG_W(
TAG,
"Array too large: %llu", (
unsigned long long)item.value);
578 for (uint64_t i = 0; i < item.value; i++) {
583 LOG_W(
TAG,
"Map too large: %llu", (
unsigned long long)item.value);
586 for (uint64_t i = 0; i < item.value * 2; i++) {
614 uint8_t *x, uint8_t *y) {
616 if (count < 0)
return false;
621 for (
int i = 0; i < count; i++) {
void cbor_encode_text_len(cbor_writer_t *w, const char *str, size_t len)
Encodes CBOR text string with explicit length.
void cbor_encode_cose_key_p256(cbor_writer_t *w, const uint8_t *x, const uint8_t *y)
Encodes COSE P-256 public key map.
void cbor_encode_uint(cbor_writer_t *w, uint64_t value)
Encodes CBOR unsigned integer.
static void write_byte(cbor_writer_t *w, uint8_t b)
Writes one byte to CBOR output buffer.
void cbor_reader_init(cbor_reader_t *r, const uint8_t *data, size_t size)
CBOR reader implementation.
void cbor_encode_bool(cbor_writer_t *w, bool value)
Encodes CBOR boolean.
#define CBOR_MAX_CONTAINER_SIZE
void cbor_encode_cose_key_ed25519(cbor_writer_t *w, const uint8_t *pubkey)
Encodes COSE Ed25519 public key map.
void cbor_writer_init(cbor_writer_t *w, uint8_t *buffer, size_t size)
CBOR writer implementation.
void cbor_encode_null(cbor_writer_t *w)
Encodes CBOR null.
bool cbor_read_text(cbor_reader_t *r, char *out, size_t max_len, size_t *out_len)
Reads CBOR text string into output buffer.
int cbor_read_map(cbor_reader_t *r)
Reads CBOR map header and returns pair count.
static bool cbor_skip_item_impl(cbor_reader_t *r, uint8_t depth)
int cbor_read_array(cbor_reader_t *r)
Reads CBOR array header and returns element count.
void cbor_encode_text(cbor_writer_t *w, const char *str)
Encodes CBOR text string.
bool cbor_skip_item(cbor_reader_t *r)
Skips one complete CBOR item including nested container content.
size_t cbor_writer_length(const cbor_writer_t *w)
Returns number of bytes written by CBOR writer.
static bool read_type_value(cbor_reader_t *r, uint8_t *type, uint64_t *value)
Reads CBOR item header and decoded value.
bool cbor_reader_error(const cbor_reader_t *r)
Returns whether reader is in error state.
static void write_type_value(cbor_writer_t *w, uint8_t type, uint64_t value)
Encodes CBOR major type and value header.
int cbor_reader_peek_type(const cbor_reader_t *r)
Peeks major type of next CBOR item.
bool cbor_writer_error(const cbor_writer_t *w)
Returns whether writer encountered an error.
#define CBOR_MAX_RECURSION_DEPTH
Defensive limits for recursive container skipping.
static bool read_byte(cbor_reader_t *r, uint8_t *b)
Reads one byte from CBOR reader.
void cbor_encode_bytes(cbor_writer_t *w, const uint8_t *data, size_t len)
Encodes CBOR byte-string.
bool cbor_read_bool(cbor_reader_t *r, bool *value)
Reads CBOR boolean simple value.
bool cbor_read_item(cbor_reader_t *r, cbor_item_t *item)
Reads next CBOR item metadata and optional inline payload pointer.
static void write_bytes(cbor_writer_t *w, const uint8_t *data, size_t len)
Writes byte span to CBOR output buffer.
void cbor_encode_array(cbor_writer_t *w, size_t count)
Encodes CBOR array header.
bool cbor_parse_cose_key(cbor_reader_t *r, int *kty, int *alg, uint8_t *x, uint8_t *y)
Parses COSE key map and extracts key type, algorithm, and coordinates.
bool cbor_read_int(cbor_reader_t *r, int64_t *value)
Reads CBOR integer (positive or negative).
bool cbor_read_uint(cbor_reader_t *r, uint64_t *value)
Reads CBOR unsigned integer.
void cbor_encode_int(cbor_writer_t *w, int64_t value)
Encodes CBOR signed integer.
bool cbor_read_bytes(cbor_reader_t *r, uint8_t *out, size_t max_len, size_t *out_len)
Reads CBOR byte-string into optional output buffer.
bool cbor_reader_available(const cbor_reader_t *r)
Returns whether unread data remains.
void cbor_encode_map(cbor_writer_t *w, size_t count)
Encodes CBOR map header.
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_W(tag, fmt,...)
#define LOG_E(tag, fmt,...)