ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
sse_chunk.cpp
Go to the documentation of this file.
1#include "sse_chunk.h"
2
3#include <cinttypes>
4#include <cstring>
5
7
9
10void for_each_chunk_piece(const char *message, size_t message_len, ChunkPieceSink sink, void *ctx) {
11 if (message == nullptr) {
12 sink(ctx, CHUNK_END, CHUNK_END_LEN);
13 return;
14 }
15 const char *pos = message;
16 const char *end = message + message_len;
17 for (;;) {
18 const size_t remaining = end - pos;
19 const auto *n = static_cast<const char *>(memchr(pos, '\n', remaining));
20 // Only a \r before the next \n can end this line, so the search stops there instead of
21 // rescanning the rest of the message for every line
22 const auto *r = static_cast<const char *>(memchr(pos, '\r', n != nullptr ? n - pos : remaining));
23 if (n == nullptr && r == nullptr) {
24 sink(ctx, pos, remaining);
25 break;
26 }
27 const char *brk = (r != nullptr && (n == nullptr || r < n)) ? r : n;
28 sink(ctx, pos, brk - pos);
29 pos = brk + ((brk == r && brk + 1 == n) ? 2 : 1);
30 if (pos >= end) {
31 break;
32 }
33 sink(ctx, SSE_SEP, SSE_SEP_LEN);
34 }
35 sink(ctx, SSE_SUFFIX, SSE_SUFFIX_LEN);
36}
37
38size_t build_chunk_prefix(char *buf, size_t size, const char *event, uint32_t id, uint32_t reconnect, bool with_data) {
39 size_t len = CHUNK_HDR_LEN;
40 if (reconnect) {
41 len = buf_append_printf(buf, size, len, "retry: %" PRIu32 "\r\n", reconnect);
42 }
43 if (id) {
44 len = buf_append_printf(buf, size, len, "id: %" PRIu32 "\r\n", id);
45 }
46 if (event && *event) {
47 len = buf_append_str(buf, size, len, "event: ");
48 len = buf_append_str(buf, size, len, event);
49 len = buf_append_str(buf, size, len, "\r\n");
50 }
51 if (with_data) {
52 len = buf_append_str(buf, size, len, "data: ");
53 }
54 return len;
55}
56
57void write_chunk_header(char *buf, size_t chunk_len) {
58 // Eight lowercase hex digits; the temp keeps the terminator format_hex_to writes out of buf
59 char digits[9];
60 format_hex_to(digits, static_cast<uint32_t>(chunk_len));
61 std::memcpy(buf, digits, 8);
62 buf[8] = '\r';
63 buf[9] = '\n';
64}
65
66} // namespace esphome::web_server_idf
const LogString * message
Definition component.cpp:35
constexpr size_t CHUNK_END_LEN
Definition sse_chunk.h:17
size_t build_chunk_prefix(char *buf, size_t size, const char *event, uint32_t id, uint32_t reconnect, bool with_data)
Definition sse_chunk.cpp:38
constexpr size_t SSE_SUFFIX_LEN
Definition sse_chunk.h:23
constexpr char CHUNK_END[]
Definition sse_chunk.h:16
constexpr char SSE_SEP[]
Definition sse_chunk.h:19
constexpr size_t SSE_SEP_LEN
Definition sse_chunk.h:20
void(*)(void *ctx, const char *piece, size_t len) ChunkPieceSink
Definition sse_chunk.h:26
void write_chunk_header(char *buf, size_t chunk_len)
Definition sse_chunk.cpp:57
constexpr size_t CHUNK_HDR_LEN
Definition sse_chunk.h:14
constexpr char SSE_SUFFIX[]
Definition sse_chunk.h:22
void for_each_chunk_piece(const char *message, size_t message_len, ChunkPieceSink sink, void *ctx)
Definition sse_chunk.cpp:10
size_t buf_append_str(char *buf, size_t size, size_t pos, const char *str)
Safely append a string to buffer, returning new position (capped at size).
Definition helpers.h:1228
const void size_t len
Definition hal.h:68
uint16_t size
Definition helpers.cpp:34
size_t size_t pos
Definition helpers.h:1179
char * format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as lowercase hex to buffer (base implementation).
Definition helpers.cpp:428
static void uint32_t
uint8_t end[39]
Definition sun_gtil2.cpp:17