ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
atc.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file atc.cpp
6 * @brief ATC field-I/O interop snapshot (see atc.h).
7 */
8
10#include "shared_primitives/strbuf.h" // pc_sb frame builder
11
12#if PC_ENABLE_ATC
13
14#include <string.h>
15
16namespace
17{
18void put_json_str(pc_sb *b, const char *s)
19{
20 pc_sb_put(b, "\"");
21 for (const char *p = s ? s : ""; *p; p++)
22 {
23 if (*p == '"' || *p == '\\')
24 {
25 char esc[3] = {'\\', *p, '\0'};
26 pc_sb_put(b, esc);
27 }
28 else
29 {
30 if (b->len + 1 >= b->cap)
31 {
32 b->ok = false;
33 return;
34 }
35 b->p[b->len++] = *p;
36 }
37 }
38 pc_sb_put(b, "\"");
39}
40
41void put_u8(pc_sb *b, uint8_t v)
42{
43 char t[4];
44 int n = 0;
45 do
46 {
47 t[n++] = (char)('0' + v % 10);
48 v /= 10;
49 } while (v);
50 char o[4];
51 for (int i = 0; i < n; i++)
52 {
53 o[i] = t[n - 1 - i];
54 }
55 o[n] = '\0';
56 pc_sb_put(b, o);
57}
58
59// Append the points of one direction (outputs or inputs) as a JSON array.
60void put_array(pc_sb *b, const AtcFieldIo *io, bool outputs)
61{
62 pc_sb_put(b, "[");
63 bool first = true;
64 for (size_t i = 0; i < io->count; i++)
65 {
66 if (io->points[i].is_output != outputs)
67 {
68 continue;
69 }
70 if (!first)
71 {
72 pc_sb_put(b, ",");
73 }
74 first = false;
75 pc_sb_put(b, "{\"name\":");
76 put_json_str(b, io->points[i].name);
77 pc_sb_put(b, ",\"value\":");
78 put_u8(b, io->points[i].value);
79 pc_sb_put(b, "}");
80 }
81 pc_sb_put(b, "]");
82}
83} // namespace
84
85size_t pc_atc_snapshot_json(const AtcFieldIo *io, char *out, size_t cap)
86{
87 if (!io || !out || (io->count && !io->points))
88 {
89 return 0;
90 }
91 pc_sb b = {out, cap, 0, cap > 0};
92 pc_sb_put(&b, "{\"inputs\":");
93 put_array(&b, io, false);
94 pc_sb_put(&b, ",\"outputs\":");
95 put_array(&b, io, true);
96 pc_sb_put(&b, "}");
97 if (!b.ok)
98 {
99 return 0;
100 }
101 out[b.len] = '\0';
102 return b.len;
103}
104
105bool pc_atc_set_output(AtcFieldIo *io, const char *name, uint8_t value)
106{
107 if (!io || !name || !io->points)
108 {
109 return false;
110 }
111 for (size_t i = 0; i < io->count; i++)
112 {
113 if (io->points[i].is_output && io->points[i].name && strcmp(io->points[i].name, name) == 0)
114 {
115 io->points[i].value = value;
116 return true;
117 }
118 }
119 return false;
120}
121
122uint8_t pc_atc_get(const AtcFieldIo *io, const char *name, bool *found)
123{
124 if (found)
125 {
126 *found = false;
127 }
128 if (!io || !name || !io->points)
129 {
130 return 0;
131 }
132 for (size_t i = 0; i < io->count; i++)
133 {
134 if (io->points[i].name && strcmp(io->points[i].name, name) == 0)
135 {
136 if (found)
137 {
138 *found = true;
139 }
140 return io->points[i].value;
141 }
142 }
143 return 0;
144}
145
146#endif // PC_ENABLE_ATC
ATC (Advanced Traffic Controller) field-I/O interop snapshot (PC_ENABLE_ATC).
Bounded no-heap string builder that fails closed on overflow (one shared copy).
void pc_sb_put(pc_sb *b, const char *s)
Append NUL-terminated s; leaves the buffer untouched and clears ok if it would not fit.
Definition strbuf.h:60
Bump-append target; ok latches false once an append would overflow cap.
Definition strbuf.h:30
char * p
Definition strbuf.h:31
size_t cap
Definition strbuf.h:32
size_t len
Definition strbuf.h:33
bool ok
Definition strbuf.h:34