ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
codec.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file codec.h
6 * @brief One binary codec interface; a wire encoding is an instance of it.
7 *
8 * The interface fixes the operations, their order, and their signatures; a format supplies the
9 * function pointers. The order is the field order of the table, so a format whose operations drift
10 * out of order fails to compile.
11 *
12 * Dispatch is a `static const` table of function pointers in rodata.
13 *
14 * The region types come from spatium.h and the byte verbs from octetus_introitus_exitus.h. A codec
15 * allocates nothing and owns no buffer: it writes into a mmgr_span the caller bound and reads from a
16 * mmgr_cspan.
17 *
18 * @author Douglas Quigg (dstroy0)
19 * @date 2026
20 */
21
22#ifndef PROTOCORE_CODEC_H
23#define PROTOCORE_CODEC_H
24
25#include "spatium/spatium.h"
26
27#include "protocore_config.h" // PROTOCORE_ENABLE_CBOR / PROTOCORE_ENABLE_MSGPACK gate the instances below
28
30
31/**
32 * @brief The next item's type, reported by protocore_codec::peek without consuming it.
33 *
34 * One set of names across every format: CBOR calls a byte string "bytes" and MessagePack calls it
35 * "bin"; CBOR has "null" and MessagePack "nil". They are the same item, so they get one name here
36 * and the format maps its own tag onto it.
37 */
51
52/**
53 * @brief A wire encoding: the ten writes, the peek, and the nine reads.
54 *
55 * Field order is the operation order every format declares and implements in. `int`, `bool` and
56 * `float` are keywords, so the members carry the put_ / get_ prefix that says which direction they
57 * run in.
58 */
59typedef struct
60{
61 // --- encode into a caller-bound mmgr_span ---
62 void (*put_uint)(mmgr_span *w, uint64_t v);
63 void (*put_int)(mmgr_span *w, int64_t v);
64 void (*put_bytes)(mmgr_span *w, const uint8_t *data, size_t len);
65 void (*put_str)(mmgr_span *w, const char *s);
66 void (*put_str_n)(mmgr_span *w, const char *s, size_t len);
67 void (*put_bool)(mmgr_span *w, proto_bool b);
68 void (*put_null)(mmgr_span *w);
69 void (*put_float)(mmgr_span *w, float f);
70 void (*put_array)(mmgr_span *w, size_t count);
71 void (*put_map)(mmgr_span *w, size_t count);
72
73 /**
74 * @brief Emit a map key, given both spellings of it.
75 *
76 * A spec often names the same field differently per encoding: RFC 8428 labels a SenML base name
77 * `"bn"` in JSON and `-2` in CBOR. That is the encoding's business, not the caller's, so the
78 * caller hands over both and the format picks the one it is specified to write. Without this the
79 * difference leaks upward and every producer keeps one walk per encoding.
80 */
81 void (*put_label)(mmgr_span *w, const char *name, int64_t num);
82
83 // --- decode from a caller-bound mmgr_cspan ---
84 protocore_codec_type (*peek)(mmgr_cspan *r);
85 proto_bool (*get_uint)(mmgr_cspan *r, uint64_t *out);
86 proto_bool (*get_int)(mmgr_cspan *r, int64_t *out);
87 proto_bool (*get_bytes)(mmgr_cspan *r, const uint8_t **out, size_t *len);
88 proto_bool (*get_str)(mmgr_cspan *r, const char **out, size_t *len);
89 proto_bool (*get_array)(mmgr_cspan *r, size_t *count);
90 proto_bool (*get_map)(mmgr_cspan *r, size_t *count);
91 proto_bool (*get_bool)(mmgr_cspan *r, proto_bool *out);
92 proto_bool (*get_null)(mmgr_cspan *r);
93 proto_bool (*get_float)(mmgr_cspan *r, float *out);
95
96// Each format declares its own instance in its own header: cbor.h has Cbor, msgpack.h has
97// MsgPack. The instance is the storage, so the format that owns the operations owns the
98// table built from them, and a build that compiles a format out has neither.
99
101
102#endif // PROTOCORE_CODEC_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
PROTOCORE_BEGIN_DECLS enum PROTO_ENUM_PACKED protocore_codec_type
The next item's type, reported by protocore_codec::peek without consuming it.
@ PROTOCORE_CODEC_STR
Definition codec.h:43
@ PROTOCORE_CODEC_FLOAT
Definition codec.h:48
@ PROTOCORE_CODEC_NULL
Definition codec.h:47
@ PROTOCORE_CODEC_BOOL
Definition codec.h:46
@ PROTOCORE_CODEC_BYTES
Definition codec.h:42
@ PROTOCORE_CODEC_ARRAY
Definition codec.h:44
@ PROTOCORE_CODEC_INVALID
end of buffer, a prior error, or an item this format does not carry
Definition codec.h:49
@ PROTOCORE_CODEC_MAP
Definition codec.h:45
@ PROTOCORE_CODEC_UINT
Definition codec.h:40
@ PROTOCORE_CODEC_INT
Definition codec.h:41
A wire encoding: the ten writes, the peek, and the nine reads.
Definition codec.h:60
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97