ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
hpack_prim.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#ifndef PROTOCORE_HPACK_PRIM_H
5#define PROTOCORE_HPACK_PRIM_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file hpack_prim.h
13 * @brief Low-level field-coding primitives shared by HPACK and QPACK.
14 *
15 * RFC 7541 defines two primitives that RFC 9204 (QPACK) reuses verbatim: the prefix-integer
16 * coding (RFC 7541 sec 5.1) and the canonical Huffman code (RFC 7541 Appendix B, referenced by
17 * RFC 9204 sec 5). This module is the single copy of both, so HTTP/2's HPACK and HTTP/3's QPACK
18 * share one implementation and one Huffman table instead of duplicating ~1 KB of tables.
19 *
20 * Pure and host-tested (via the HPACK and QPACK codec tests). Zero heap.
21 *
22 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
23 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
24 * a caller drives every namespace the same way.
25 *
26 * @author Douglas Quigg (dstroy0)
27 * @date 2026
28 */
29
30// PROTOCORE_HPACK_PRIM_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
31// it into its arena. Its size and its offset are each a static_assert, so a feature
32// combination that does not fit fails to compile rather than overrunning at run time.
33
34/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
35typedef struct
36{
37 size_t (*encode_int)(uint8_t *, uint8_t *, size_t, uint8_t, uint8_t, uint32_t);
38 proto_bool (*decode_int)(uint8_t *, const uint8_t *, size_t, uint8_t, size_t *, uint32_t *);
39 size_t (*huff_encode)(uint8_t *, uint8_t *, size_t, const char *, size_t);
40 size_t (*huff_len)(uint8_t *, const char *, size_t);
41 proto_bool (*huff_decode)(uint8_t *, const uint8_t *, size_t, char *, size_t, size_t *);
42 proto_bool (*decode_str)(uint8_t *, const uint8_t *, size_t, size_t *, char *, size_t, size_t *);
43 size_t (*encode_str)(uint8_t *, uint8_t *, size_t, const char *, size_t);
45PROTOCORE_NS_LAYOUT(HpackPrimNs, encode_int, decode_int, huff_encode, huff_len, huff_decode, decode_str, encode_str);
46
47/**
48 * @brief A prefix-prefix_bits integer with the high flags bits set in byte 0.
49 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
50 * @param out Out
51 * @param cap Cap
52 * @param prefix_bits Prefix bits
53 * @param flags Flags
54 * @param value Value
55 * @return The size_t.
56 */
57size_t protocore_hpack_prim_encode_int(uint8_t *work, uint8_t *out, size_t cap, uint8_t prefix_bits, uint8_t flags,
58 uint32_t value);
59/**
60 * @brief The same integer back; sets consumed and value, false if malformed.
61 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
62 * @param in In
63 * @param len Len
64 * @param prefix_bits Prefix bits
65 * @param consumed Consumed
66 * @param value Value
67 * @return PROTO_TRUE on success.
68 */
69proto_bool protocore_hpack_prim_decode_int(uint8_t *work, const uint8_t *in, size_t len, uint8_t prefix_bits,
70 size_t *consumed, uint32_t *value);
71/**
72 * @brief Huffman-encode n bytes of s (RFC 7541 Appendix B); bytes written,.
73 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
74 * @param out Out
75 * @param cap Cap
76 * @param s S
77 * @param n N
78 * @return The size_t.
79 */
80size_t protocore_hpack_prim_huff_encode(uint8_t *work, uint8_t *out, size_t cap, const char *s, size_t n);
81/**
82 * @brief The Huffman byte length of s without encoding it, which is what.
83 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
84 * @param s S
85 * @param n N
86 * @return The size_t.
87 */
88size_t protocore_hpack_prim_huff_len(uint8_t *work, const char *s, size_t n);
89/**
90 * @brief Huffman-decode n bytes into out; sets out_len, false on a bad code.
91 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
92 * @param in In
93 * @param n N
94 * @param out Out
95 * @param cap Cap
96 * @param out_len Out len
97 * @return PROTO_TRUE on success.
98 */
99proto_bool protocore_hpack_prim_huff_decode(uint8_t *work, const uint8_t *in, size_t n, char *out, size_t cap,
100 size_t *out_len);
101/**
102 * @brief A length-prefixed string literal (H bit at 0x80 + a 7-bit length .
103 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
104 * @param block Block
105 * @param len Len
106 * @param pos Pos
107 * @param out Out
108 * @param cap Cap
109 * @param out_len Out len
110 * @return PROTO_TRUE on success.
111 */
112proto_bool protocore_hpack_prim_decode_str(uint8_t *work, const uint8_t *block, size_t len, size_t *pos, char *out,
113 size_t cap, size_t *out_len);
114/**
115 * @brief The same literal out, Huffman-coded when that is the shorter of the .
116 * @param work PROTOCORE_HPACK_PRIM_BORROW bytes the caller took. Not held past the call.
117 * @param out Out
118 * @param cap Cap
119 * @param s S
120 * @param n N
121 * @return The size_t.
122 */
123size_t protocore_hpack_prim_encode_str(uint8_t *work, uint8_t *out, size_t cap, const char *s, size_t n);
124
125/** @brief Module namespace. */
133
135
136#endif // PROTOCORE_HPACK_PRIM_H
proto_bool protocore_hpack_prim_decode_int(uint8_t *work, const uint8_t *in, size_t len, uint8_t prefix_bits, size_t *consumed, uint32_t *value)
The same integer back; sets consumed and value, false if malformed.
size_t protocore_hpack_prim_huff_len(uint8_t *work, const char *s, size_t n)
The Huffman byte length of s without encoding it, which is what.
proto_bool protocore_hpack_prim_decode_str(uint8_t *work, const uint8_t *block, size_t len, size_t *pos, char *out, size_t cap, size_t *out_len)
A length-prefixed string literal (H bit at 0x80 + a 7-bit length .
size_t protocore_hpack_prim_huff_encode(uint8_t *work, uint8_t *out, size_t cap, const char *s, size_t n)
Huffman-encode n bytes of s (RFC 7541 Appendix B); bytes written,.
size_t protocore_hpack_prim_encode_str(uint8_t *work, uint8_t *out, size_t cap, const char *s, size_t n)
The same literal out, Huffman-coded when that is the shorter of the .
size_t protocore_hpack_prim_encode_int(uint8_t *work, uint8_t *out, size_t cap, uint8_t prefix_bits, uint8_t flags, uint32_t value)
A prefix-prefix_bits integer with the high flags bits set in byte 0.
PROTOCORE_NS HpackPrimNs HpackPrim PROTOCORE_UNUSED
Module namespace.
Definition hpack_prim.h:126
proto_bool protocore_hpack_prim_huff_decode(uint8_t *work, const uint8_t *in, size_t n, char *out, size_t cap, size_t *out_len)
Huffman-decode n bytes into out; sets out_len, false on a bad code.
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition hpack_prim.h:36
size_t(* encode_int)(uint8_t *, uint8_t *, size_t, uint8_t, uint8_t, uint32_t)
Definition hpack_prim.h:37
#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