roo_io
API Documentation for roo_io
Loading...
Searching...
No Matches
cobs.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Unlicense OR 0BSD
2
3// nanocobs v0.1.0, Charles Nicholson (charles.nicholson@gmail.com)
4#pragma once
5
6#include <stdbool.h>
7#include <stddef.h>
8#include <stdint.h>
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
20
21enum {
22 // All COBS frames end with this value. If you're scanning a data source for
23 // frame delimiters, the presence of this zero byte indicates the completion
24 // of a frame.
26
27 // In-place encoding mandatory placeholder byte values.
29
30 // In-place encodings that fit in a buffer of this size will always succeed.
32};
33
34// COBS_ENCODE_MAX
35//
36// Returns the maximum possible size in bytes of the buffer required to encode a buffer of
37// length |dec_len|. Cannot fail. Defined as macro/constexpr to facilitate compile-time
38// sizing of buffers.
39#ifdef __cplusplus
40inline constexpr size_t COBS_ENCODE_MAX(size_t DECODED_LEN) {
41 return 1 + DECODED_LEN + ((DECODED_LEN + 253) / 254) + (DECODED_LEN == 0);
42}
43#else
44// In C, DECODED_LEN is evaluated multiple times; don't call with mutating expressions!
45// e.g. Don't do "COBS_ENCODE_MAX(i++)".
46#define COBS_ENCODE_MAX(DECODED_LEN) \
47 (1 + (DECODED_LEN) + (((DECODED_LEN) + 253) / 254) + ((DECODED_LEN) == 0))
48#endif
49
50// cobs_encode_tinyframe
51//
52// Encode in-place the contents of the provided buffer |buf| of length |len|. Returns
53// COBS_RET_SUCCESS on successful encoding.
54//
55// Because encoding adds leading and trailing bytes, your buffer must reserve bytes 0 and
56// len-1 for the encoding. If the first and last bytes of |buf| are not set to
57// COBS_INPLACE_SENTINEL_VALUE, the function will fail with COBS_RET_ERR_BAD_PAYLOAD.
58//
59// If a null pointer or invalid length are provided, the function will fail with
60// COBS_RET_ERR_BAD_ARG.
61//
62// If |len| is less than or equal to COBS_INPLACE_SAFE_BUFFER_SIZE, the contents of |buf|
63// will never cause encoding to fail. If |len| is larger than
64// COBS_INPLACE_SAFE_BUFFER_SIZE, encoding can possibly fail with COBS_RET_ERR_BAD_PAYLOAD
65// if there are more than 254 bytes between zeros.
66//
67// If the function returns COBS_RET_ERR_BAD_PAYLOAD, the contents of |buf| are left
68// indeterminate and must not be relied on to be fully encoded or decoded.
69cobs_ret_t cobs_encode_tinyframe(void *buf, size_t len);
70
71// cobs_decode_tinyframe
72//
73// Decode in-place the contents of the provided buffer |buf| of length |len|.
74// Returns COBS_RET_SUCCESS on successful decoding.
75//
76// Because decoding is in-place, the first and last bytes of |buf| will be set to the value
77// COBS_INPLACE_SENTINEL_VALUE if decoding succeeds. The decoded contents are stored in the
78// inclusive span defined by buf[1] and buf[len-2].
79//
80// If a null pointer or invalid length are provided, the function will fail with
81// COBS_RET_ERR_BAD_ARG.
82//
83// If the encoded buffer contains any code bytes that exceed |len|, the function will fail
84// with COBS_RET_ERR_BAD_PAYLOAD. If the buffer starts with a 0 byte, or ends in a nonzero
85// byte, the function will fail with COBS_RET_ERR_BAD_PAYLOAD.
86//
87// If the function returns COBS_RET_ERR_BAD_PAYLOAD, the contents of |buf| are left
88// indeterminate and must not be relied on to be fully encoded or decoded.
89cobs_ret_t cobs_decode_tinyframe(void *buf, size_t len);
90
91// cobs_decode
92//
93// Decode |enc_len| encoded bytes from |enc| into |out_dec|, storing the decoded length in
94// |out_dec_len|. Returns COBS_RET_SUCCESS on successful decoding.
95//
96// If any of the input pointers are null, or if any of the lengths are invalid, the
97// function will fail with COBS_RET_ERR_BAD_ARG.
98//
99// If |enc| starts with a 0 byte, or does not end with a 0 byte, the function will fail
100// with COBS_RET_ERR_BAD_PAYLOAD.
101//
102// If the decoding exceeds |dec_max| bytes, the function will fail with
103// COBS_RET_ERR_EXHAUSTED.
104cobs_ret_t cobs_decode(void const *enc,
105 size_t enc_len,
106 void *out_dec,
107 size_t dec_max,
108 size_t *out_dec_len);
109
110// cobs_encode
111//
112// Encode |dec_len| decoded bytes from |dec| into |out_enc|, storing the encoded length in
113// |out_enc_len|. Returns COBS_RET_SUCCESS on successful encoding.
114//
115// If any of the input pointers are null, or if any of the lengths are invalid, the
116// function will fail with COBS_RET_ERR_BAD_ARG.
117//
118// If the encoding exceeds |enc_max| bytes, the function will fail with
119// COBS_RET_ERR_EXHAUSTED.
120cobs_ret_t cobs_encode(void const *dec,
121 size_t dec_len,
122 void *out_enc,
123 size_t enc_max,
124 size_t *out_enc_len);
125
126// Incremental encoding API
127
128typedef struct cobs_enc_ctx {
129 void *dst;
130 size_t dst_max;
131 size_t cur;
132 size_t code_idx;
133 unsigned code;
136
137// cobs_encode_inc_begin
138//
139// Begin an incremental encoding of data into |out_enc|. The intermediate encoding state is
140// stored in |out_ctx|, which can then be passed into calls to cobs_encode_inc. Returns
141// COBS_RET_SUCCESS if |out_ctx| can be used in future calls to cobs_encode_inc.
142//
143// If |out_enc| or |out_ctx| are null, or if |enc_max| is not large enough to hold the
144// smallest possible encoding, the function will return COBS_RET_ERR_BAD_ARG.
145cobs_ret_t cobs_encode_inc_begin(void *out_enc, size_t enc_max, cobs_enc_ctx_t *out_ctx);
146
147// cobs_encode_inc
148//
149// Continue an encoding in progress with the new |dec| buffer of length |dec_len|. Encodes
150// |dec_len| decoded bytes from |dec| into the buffer that |ctx| was initialized with in
151// cobs_encode_inc_begin.
152//
153// If any of the input pointers are null, or |dec_len| is zero, the function will fail with
154// COBS_RET_ERR_BAD_ARG.
155//
156// If the contents pointed to by |dec| can not be encoded in the remaining available buffer
157// space, the function returns COBS_RET_ERR_EXHAUSTED. In this case, |ctx| remains
158// unchanged and incremental encoding can be attempted again with different data, or
159// finished with cobs_encode_inc_end.
160//
161// If the contents of |dec| are successfully encoded, the function returns
162// COBS_RET_SUCCESS.
163cobs_ret_t cobs_encode_inc(cobs_enc_ctx_t *ctx, void const *dec_src, size_t dec_len);
164
165// cobs_encode_inc_end
166//
167// Finish an incremental encoding by writing the final code and delimiter.
168// Returns COBS_RET_SUCCESS on success, and no further calls to cobs_encode_inc or
169// cobs_encode_inc_end can be safely made until |ctx| is re-initialized via a new call to
170// cobs_encode_inc_begin.
171//
172// The final encoded length is written to |out_enc_len|, and the buffer passed to
173// cobs_encode_inc_begin holds the full COBS-encoded frame.
174//
175// If null pointers are provided, the function returns COBS_RET_ERR_BAD_ARG.
176cobs_ret_t cobs_encode_inc_end(cobs_enc_ctx_t *ctx, size_t *out_enc_len);
177
178// Incremental decoding API
179
188
189typedef struct cobs_decode_inc_args {
190 void const *enc_src; // pointer to current position of encoded payload
191 void *dec_dst; // pointer to decoded output buffer.
192 size_t enc_src_max; // length of the |src| input buffer.
193 size_t dec_dst_max; // length of the |dst| output buffer.
195
198 cobs_decode_inc_args_t const *args,
199 size_t *out_enc_src_len, // how many bytes of src were read
200 size_t *out_dec_dst_len, // how many bytes written to dst
201 bool *out_decode_complete);
202
203#ifdef __cplusplus
204}
205#endif
@ COBS_FRAME_DELIMITER
Definition cobs.h:25
@ COBS_TINYFRAME_SAFE_BUFFER_SIZE
Definition cobs.h:31
@ COBS_TINYFRAME_SENTINEL_VALUE
Definition cobs.h:28
cobs_ret_t cobs_decode_inc_begin(cobs_decode_inc_ctx_t *ctx)
Definition cobs.c:208
#define COBS_ENCODE_MAX(DECODED_LEN)
Definition cobs.h:46
cobs_ret_t cobs_encode_tinyframe(void *buf, size_t len)
Definition cobs.c:8
cobs_ret_t cobs_decode(void const *enc, size_t enc_len, void *out_dec, size_t dec_max, size_t *out_dec_len)
Definition cobs.c:175
cobs_ret_t cobs_encode(void const *dec, size_t dec_len, void *out_enc, size_t enc_max, size_t *out_enc_len)
Definition cobs.c:64
cobs_ret_t
Definition cobs.h:14
@ COBS_RET_ERR_BAD_PAYLOAD
Definition cobs.h:17
@ COBS_RET_ERR_EXHAUSTED
Definition cobs.h:18
@ COBS_RET_SUCCESS
Definition cobs.h:15
@ COBS_RET_ERR_BAD_ARG
Definition cobs.h:16
cobs_ret_t cobs_encode_inc_begin(void *out_enc, size_t enc_max, cobs_enc_ctx_t *out_ctx)
Definition cobs.c:84
cobs_ret_t cobs_decode_tinyframe(void *buf, size_t len)
Definition cobs.c:39
cobs_ret_t cobs_encode_inc_end(cobs_enc_ctx_t *ctx, size_t *out_enc_len)
Definition cobs.c:162
struct cobs_decode_inc_args cobs_decode_inc_args_t
cobs_ret_t cobs_decode_inc(cobs_decode_inc_ctx_t *ctx, cobs_decode_inc_args_t const *args, size_t *out_enc_src_len, size_t *out_dec_dst_len, bool *out_decode_complete)
Definition cobs.c:216
struct cobs_decode_inc_ctx cobs_decode_inc_ctx_t
cobs_ret_t cobs_encode_inc(cobs_enc_ctx_t *ctx, void const *dec_src, size_t dec_len)
Definition cobs.c:101
struct cobs_enc_ctx cobs_enc_ctx_t
size_t dec_dst_max
Definition cobs.h:193
size_t enc_src_max
Definition cobs.h:192
void const * enc_src
Definition cobs.h:190
enum cobs_decode_inc_ctx::cobs_decode_inc_state state
uint8_t block
Definition cobs.h:186
size_t cur
Definition cobs.h:131
size_t dst_max
Definition cobs.h:130
unsigned code
Definition cobs.h:133
size_t code_idx
Definition cobs.h:132
void * dst
Definition cobs.h:129
int need_advance
Definition cobs.h:134