ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
deflate.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_DEFLATE_H
5#define PROTOCORE_DEFLATE_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file deflate.h
13 * @brief Bounded RFC 1951 DEFLATE compressor (DEFLATE) - no heap.
14 *
15 * The outbound counterpart to inflate.* : a small, host-testable DEFLATE used by
16 * WebSocket permessage-deflate (RFC 7692) to compress server-to-client messages.
17 * It emits a single fixed-Huffman block (no dynamic tables to build) with LZ77
18 * back-references found over a bounded sliding window, then byte-aligns with an
19 * empty stored block and removes the trailing 0x00 0x00 0xff 0xff per
20 * RFC 7692 sec 7.2.1 - so the result is a ready-to-frame permessage-deflate
21 * payload. The peer's INFLATE re-appends that marker before decompressing (our
22 * own RX path does exactly that, see websocket.cpp).
23 *
24 * Matching reads from the source buffer itself - there is no kept window across
25 * messages, which is correct for `no_context_takeover` (the mode the handshake
26 * negotiates) and bounds memory: distances never exceed DEFLATE_WINDOW and the
27 * only working memory is a caller-supplied scratch (DEFLATE_SCRATCH_SIZE bytes,
28 * borrowed from the per-dispatch arena, like inflate).
29 *
30 * Fixed (not dynamic) Huffman keeps the encoder tiny and deterministic; it never
31 * builds an optimal tree, so the ratio is modest, but for the small JSON/text
32 * frames this serves it still shrinks the wire while costing no dedicated buffer.
33 * If the output would not be smaller than the input the caller simply sends the
34 * message uncompressed (the per-message RSV1 flag makes that legal).
35 *
36 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
37 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
38 * a caller drives every namespace the same way.
39 *
40 * @author Douglas Quigg (dstroy0)
41 * @date 2026
42 */
43
44// PROTOCORE_DEFLATE_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
45// it into its arena. Its size and its offset are each a static_assert, so a feature
46// combination that does not fit fails to compile rather than overrunning at run time.
47
48/**
49 * @brief Working-memory bytes deflate_raw() needs (hash chains + code tables).
50 *
51 * Pass a buffer at least this large as @p scratch. An internal static_assert
52 * keeps it honest against the table layout.
53 */
54#define DEFLATE_SCRATCH_SIZE 4096
55
56/** @brief deflate_raw() return codes (mirror ::InflateResult). */
58{
59 DEFLATE_OK = 0, ///< success; *out_len holds the compressed length
60 DEFLATE_ERR_OVERFLOW = -2, ///< output would exceed dst_cap (incompressible)
61 DEFLATE_ERR_SCRATCH = -3 ///< scratch_len < DEFLATE_SCRATCH_SIZE
63
64/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
65typedef struct
66{
67 DeflateResult (*raw)(uint8_t *, const uint8_t *, size_t, uint8_t *, size_t, size_t *, void *, size_t);
68} DeflateNs;
70
71/**
72 * @brief Compress src into a raw permessage-deflate payload (RFC 7692): a .
73 * @param work PROTOCORE_DEFLATE_BORROW bytes the caller took. Not held past the call.
74 * @param src Src
75 * @param src_len Src len
76 * @param dst Dst
77 * @param dst_cap Dst cap
78 * @param out_len Out len
79 * @param scratch Scratch
80 * @param scratch_len Scratch len
81 * @return The DeflateResult.
82 */
83DeflateResult protocore_deflate_raw(uint8_t *work, const uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_cap,
84 size_t *out_len, void *scratch, size_t scratch_len);
85
86/** @brief Module namespace. */
88
90
91#endif // PROTOCORE_DEFLATE_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
PROTOCORE_NS DeflateNs Deflate PROTOCORE_UNUSED
Module namespace.
Definition deflate.h:87
DeflateResult protocore_deflate_raw(uint8_t *work, const uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_cap, size_t *out_len, void *scratch, size_t scratch_len)
Compress src into a raw permessage-deflate payload (RFC 7692): a .
@ DEFLATE_ERR_SCRATCH
scratch_len < DEFLATE_SCRATCH_SIZE
Definition deflate.h:61
@ DEFLATE_OK
success; *out_len holds the compressed length
Definition deflate.h:59
@ DEFLATE_ERR_OVERFLOW
output would exceed dst_cap (incompressible)
Definition deflate.h:60
enum PROTO_ENUM_PACKED DeflateResult
deflate_raw() return codes (mirror ::InflateResult).
#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 deflate.h:66
DeflateResult(* raw)(uint8_t *, const uint8_t *, size_t, uint8_t *, size_t, size_t *, void *, size_t)
Definition deflate.h:67
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
#define PROTOCORE_END_DECLS
Definition types.h:97