ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
zlib.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_TRANSPORT_ZLIB_H
5#define PROTOCORE_TRANSPORT_ZLIB_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file zlib.h
13 * @brief RFC 1950 / 1951 deflate, as SSH negotiates it.
14 *
15 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
16 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
17 * a caller drives every namespace the same way.
18 */
19
20// PROTOCORE_ZLIB_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
21// it into its arena. Its size and its offset are each a static_assert, so a feature
22// combination that does not fit fails to compile rather than overrunning at run time.
23
24/** @brief Hash-table buckets for the LZ77 3-byte match search (2^bits). */
25#define SSH_ZLIB_HASH_BITS 13
26#define SSH_ZLIB_HASH_SIZE (1 << SSH_ZLIB_HASH_BITS)
27
28/** @brief Work buffer capacity the compressor needs: window history + one input payload. */
29#define SSH_ZLIB_WORK_SIZE ((size_t)PROTOCORE_SSH_ZLIB_WINDOW + (size_t)PROTOCORE_SSH_ZLIB_MAX_IN)
30
31/**
32 * @brief Streaming server-to-client DEFLATE compressor (one per SSH connection).
33 *
34 * The window (history) lives at the front of @ref work; @ref hist bytes are valid. Hash chains
35 * (@ref head / @ref prev) are rebuilt over the history each packet, so a slid buffer needs no chain
36 * fix-up. All pointers are caller-owned; ssh_deflate_init() wires them and seeds the fixed tables.
37 */
38typedef struct
39{
40 uint8_t *work; ///< history+input work buffer, capacity SSH_ZLIB_WORK_SIZE.
41 uint16_t *head; ///< hash bucket heads, SSH_ZLIB_HASH_SIZE entries.
42 uint16_t *prev; ///< hash chain (absolute-position indexed), SSH_ZLIB_WORK_SIZE entries.
43 uint16_t *ll_code; ///< fixed literal/length Huffman codes (bit-reversed), 288 entries.
44 uint8_t *ll_len; ///< their bit lengths, 288 entries.
45 uint16_t *d_code; ///< fixed distance Huffman codes (bit-reversed), 30 entries.
46 uint8_t *d_len; ///< their bit lengths, 30 entries.
47 size_t hist; ///< bytes of history currently at the front of @ref work.
48 proto_bool header_sent; ///< true once the leading 2-byte zlib header has been emitted.
50
51/**
52 * @brief Worst-case compressed size for @p src_len input (header + block overhead + sync marker).
53 *
54 * Callers size @p dst with this. Fixed-Huffman can expand incompressible data slightly; the bound
55 * covers the 2-byte header, per-byte worst case, end-of-block, and the 4-byte sync marker.
56 */
57static inline size_t ssh_deflate_bound(size_t src_len)
58{
59 return 2 + src_len + (src_len >> 3) + 32;
60}
61
62/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
63typedef struct
64{
65 void (*init)(uint8_t *, SshDeflate *, uint8_t *, uint16_t *, uint16_t *, uint16_t *, uint8_t *, uint16_t *,
66 uint8_t *);
67 int (*packet)(uint8_t *, SshDeflate *, const uint8_t *, size_t, uint8_t *, size_t, size_t *);
68} ZlibNs;
70
71/**
72 * @brief Bind caller memory to a compressor and reset it to stream start.
73 * @param work PROTOCORE_ZLIB_BORROW bytes the caller took. Not held past the call.
74 * @param z the compressor to initialize
75 * @param win history+input buffer, >= SSH_ZLIB_WORK_SIZE bytes
76 * @param head hash heads, SSH_ZLIB_HASH_SIZE uint16 entries
77 * @param prev hash chain, SSH_ZLIB_WORK_SIZE uint16 entries
78 * @param ll_code Ll code
79 * @param ll_len Ll len
80 * @param d_code D code
81 * @param d_len D len
82 */
83void protocore_zlib_init(uint8_t *work, SshDeflate *z, uint8_t *win, uint16_t *head, uint16_t *prev, uint16_t *ll_code,
84 uint8_t *ll_len, uint16_t *d_code, uint8_t *d_len);
85/**
86 * @brief Compress one packet payload, continuing the session's zlib stream. .
87 * @param work PROTOCORE_ZLIB_BORROW bytes the caller took. Not held past the call.
88 * @param z the compressor
89 * @param src Src
90 * @param src_len Src len
91 * @param dst Dst
92 * @param dst_cap Dst cap
93 * @param out_len set to the compressed length on success
94 * @return The int.
95 */
96int protocore_zlib_packet(uint8_t *work, SshDeflate *z, const uint8_t *src, size_t src_len, uint8_t *dst,
97 size_t dst_cap, size_t *out_len);
98
99/** @brief Module namespace. */
101
103
104#endif // PROTOCORE_TRANSPORT_ZLIB_H
#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.
Streaming server-to-client DEFLATE compressor (one per SSH connection).
Definition zlib.h:39
uint8_t * d_len
their bit lengths, 30 entries.
Definition zlib.h:46
uint16_t * prev
hash chain (absolute-position indexed), SSH_ZLIB_WORK_SIZE entries.
Definition zlib.h:42
proto_bool header_sent
true once the leading 2-byte zlib header has been emitted.
Definition zlib.h:48
size_t hist
bytes of history currently at the front of work.
Definition zlib.h:47
uint8_t * work
history+input work buffer, capacity SSH_ZLIB_WORK_SIZE.
Definition zlib.h:40
uint16_t * ll_code
fixed literal/length Huffman codes (bit-reversed), 288 entries.
Definition zlib.h:43
uint16_t * d_code
fixed distance Huffman codes (bit-reversed), 30 entries.
Definition zlib.h:45
uint8_t * ll_len
their bit lengths, 288 entries.
Definition zlib.h:44
uint16_t * head
hash bucket heads, SSH_ZLIB_HASH_SIZE entries.
Definition zlib.h:41
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition zlib.h:64
void(* init)(uint8_t *, SshDeflate *, uint8_t *, uint16_t *, uint16_t *, uint16_t *, uint8_t *, uint16_t *, uint8_t *)
Definition zlib.h:65
#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
void protocore_zlib_init(uint8_t *work, SshDeflate *z, uint8_t *win, uint16_t *head, uint16_t *prev, uint16_t *ll_code, uint8_t *ll_len, uint16_t *d_code, uint8_t *d_len)
Bind caller memory to a compressor and reset it to stream start.
int protocore_zlib_packet(uint8_t *work, SshDeflate *z, const uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_cap, size_t *out_len)
Compress one packet payload, continuing the session's zlib stream. .
PROTOCORE_NS ZlibNs Zlib PROTOCORE_UNUSED
Module namespace.
Definition zlib.h:100