DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
cbor.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file cbor.h
6 * @brief Layer 6 (Presentation) - zero-heap CBOR (RFC 8949) encoder.
7 *
8 * A streaming encoder that writes directly into a caller-provided buffer (no
9 * heap), the binary counterpart to the JSON writer. Emit definite-length arrays
10 * and maps by writing the header (cbor_array / cbor_map with the item count) then
11 * that many items (twice that for a map: key, value, key, value, ...).
12 *
13 * Overflow is tracked, not crashed on: writes past the buffer set the overflow
14 * flag and stop, while cbor_len() keeps counting the bytes the full payload would
15 * need, so a caller can size the buffer and check cbor_ok().
16 *
17 * @author Douglas Quigg (dstroy0)
18 * @date 2026
19 */
20
21#ifndef DETERMINISTICESPASYNCWEBSERVER_CBOR_H
22#define DETERMINISTICESPASYNCWEBSERVER_CBOR_H
23
24#include "ServerConfig.h"
25#include <stddef.h>
26#include <stdint.h>
27
28#if DETWS_ENABLE_CBOR
29
30/** @brief CBOR encoder state over a caller-provided buffer. */
31struct CborWriter
32{
33 uint8_t *buf; ///< destination buffer.
34 size_t cap; ///< buffer capacity in bytes.
35 size_t pos; ///< bytes the payload needs so far (may exceed cap on overflow).
36 bool overflow; ///< true once a write did not fit.
37};
38
39/** @brief Bind a writer to @p buf (capacity @p cap) and reset it. */
40void cbor_init(CborWriter *w, uint8_t *buf, size_t cap);
41
42/** @brief Encoded length in bytes (what the full payload needs; compare to cap). */
43size_t cbor_len(const CborWriter *w);
44
45/** @brief True if every value fit in the buffer. */
46bool cbor_ok(const CborWriter *w);
47
48void cbor_uint(CborWriter *w, uint64_t v); ///< unsigned integer
49void cbor_int(CborWriter *w, int64_t v); ///< signed integer
50void cbor_bytes(CborWriter *w, const uint8_t *data, size_t len); ///< byte string
51void cbor_text(CborWriter *w, const char *s); ///< text string (null-terminated)
52void cbor_text_n(CborWriter *w, const char *s, size_t len); ///< text string (explicit length)
53void cbor_bool(CborWriter *w, bool b); ///< true / false
54void cbor_null(CborWriter *w); ///< null
55void cbor_float(CborWriter *w, float f); ///< IEEE-754 single (major 7, 0xfa)
56void cbor_array(CborWriter *w, size_t count); ///< definite-length array header
57void cbor_map(CborWriter *w, size_t count); ///< definite-length map header
58
59// ---------------------------------------------------------------------------
60// Decoder (cursor over a CBOR byte buffer)
61// ---------------------------------------------------------------------------
62
63/** @brief Major type of the next item (returned by cbor_peek). */
64enum class CborType : uint8_t
65{
66 CBOR_TYPE_UINT = 0,
67 CBOR_TYPE_INT,
68 CBOR_TYPE_BYTES,
69 CBOR_TYPE_TEXT,
70 CBOR_TYPE_ARRAY,
71 CBOR_TYPE_MAP,
72 CBOR_TYPE_BOOL,
73 CBOR_TYPE_NULL,
74 CBOR_TYPE_FLOAT,
75 CBOR_TYPE_INVALID ///< end of buffer, a prior error, or an unsupported item
76};
77
78/** @brief CBOR decoder cursor over a read-only buffer. */
79struct CborReader
80{
81 const uint8_t *buf; ///< source bytes.
82 size_t len; ///< buffer length.
83 size_t pos; ///< current read offset.
84 bool err; ///< sticky: set on any malformed / out-of-bounds read.
85};
86
87/** @brief Bind a reader to @p buf (length @p len) at offset 0. */
88void cbor_reader_init(CborReader *r, const uint8_t *buf, size_t len);
89
90/** @brief Type of the next item without consuming it. */
91CborType cbor_peek(CborReader *r);
92
93/** @brief True while no malformed read has occurred. */
94bool cbor_reader_ok(const CborReader *r);
95
96bool cbor_read_uint(CborReader *r, uint64_t *out); ///< unsigned integer
97bool cbor_read_int(CborReader *r, int64_t *out); ///< signed integer (also accepts unsigned)
98bool cbor_read_bool(CborReader *r, bool *out); ///< true / false
99bool cbor_read_null(CborReader *r); ///< null
100bool cbor_read_float(CborReader *r, float *out); ///< float32 (0xfa) or double (0xfb)
101bool cbor_read_text(CborReader *r, const char **out, size_t *len); ///< text string (points into the buffer)
102bool cbor_read_bytes(CborReader *r, const uint8_t **out, size_t *len); ///< byte string (points into the buffer)
103bool cbor_read_array(CborReader *r, size_t *count); ///< definite-length array header
104bool cbor_read_map(CborReader *r, size_t *count); ///< definite-length map header
105
106#endif // DETWS_ENABLE_CBOR
107#endif // DETERMINISTICESPASYNCWEBSERVER_CBOR_H
User-facing configuration for DeterministicESPAsyncWebServer.