ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
http_date.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 http_date.h
6 * @brief Render a Unix epoch as an RFC 7231 IMF-fixdate.
7 *
8 * One formatter serves every header that carries a timestamp (`Date`, `Last-Modified`, `Expires`),
9 * so the wire rendering is fixed in one place. The break-down is reentrant (`gmtime_r`, never the
10 * shared static `tm`), which is what makes it callable from any worker.
11 *
12 * Every rejection - no epoch, no buffer, a time that will not break down - returns 0 and leaves
13 * @p out an empty string, so a caller that ignores the length still emits a well-formed header
14 * value rather than whatever the buffer held.
15 *
16 * @author Douglas Quigg (dstroy0)
17 * @date 2026
18 */
19
20#ifndef PROTOCORE_HTTP_DATE_H
21#define PROTOCORE_HTTP_DATE_H
22
23#include "shared/time_compat/time_compat.h" // ::TimeCompat, time_t, and the entry point behind it
24
25/**
26 * @brief Smallest buffer that holds an RFC 7231 IMF-fixdate plus its NUL.
27 *
28 * `Sun, 06 Nov 1994 08:49:37 GMT` is 29 characters and the format is fixed-width, so this is a
29 * property of the protocol rather than a tuning choice. A smaller buffer truncates silently,
30 * because the builder writes nothing and reports 0 when the result does not fit.
31 */
32#define PROTOCORE_HTTP_DATE_MAX 30
33
34/** @brief The instant a format renders, and where it lands. */
35typedef struct
36{
37 time_t epoch; ///< seconds since the Unix epoch; 0 renders empty
38 char *out; ///< where the date lands
39 uint32_t out_cap; ///< how much room it has; ::PROTOCORE_HTTP_DATE_MAX holds the whole form
41
42/**
43 * @brief The IMF-fixdate an HTTP Date header carries.
44 *
45 * @var HttpDateNs::args the instant a format renders, and where it lands
46 * @var HttpDateNs::n characters written, excluding the NUL, or 0 on any rejection
47 * @var HttpDateNs::format render the instant in GMT
48 *
49 * A buffer smaller than ::PROTOCORE_HTTP_DATE_MAX truncates to empty rather than to a partial date,
50 * because the formatter writes nothing and reports 0 when the result does not fit.
51 *
52 * No storage member: the destination is the caller's and nothing is held between calls.
53 */
54typedef struct
55{
57 uint8_t n;
59
60/** @brief The operands and the outcome. */
62
63/** @brief The entries. */
64typedef struct
65{
66 void (*const format)(uint8_t *work);
68
69// What the table binds, defined once in the .c and taking one parameter each: everything
70// else an entry needs is an operand in HttpDateV or a region of the borrow at a fixed offset.
71void protocore_http_date_format(uint8_t *work);
72
73// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
74// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
75// `HttpDate.format(work)` resolves to a named function and becomes a DIRECT call. An extern table
76// leaves the call indirect and the symbol live at every level, -O2 -flto included.
77static const HttpDateNs HttpDate __attribute__((unused)) = {
79};
80
81#endif // PROTOCORE_HTTP_DATE_H
void protocore_http_date_format(uint8_t *work)
HttpDateVars HttpDateV
The operands and the outcome.
The instant a format renders, and where it lands.
Definition http_date.h:36
uint32_t out_cap
how much room it has; PROTOCORE_HTTP_DATE_MAX holds the whole form
Definition http_date.h:39
time_t epoch
seconds since the Unix epoch; 0 renders empty
Definition http_date.h:37
char * out
where the date lands
Definition http_date.h:38
The entries.
Definition http_date.h:65
void(*const format)(uint8_t *work)
Definition http_date.h:66
uint8_t n
Definition http_date.h:57
HttpDateArgs args
Definition http_date.h:56
Reentrant UTC broken-down time, portable across the host and target toolchains.