ProtoCore v0.0.2
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
utmc.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 utmc.cpp
6 * @brief UTMC common-database codec (see utmc.h).
7 */
8
10#include "shared_primitives/strbuf.h" // pc_sb frame builder
11
12#if PC_ENABLE_UTMC
13
14#include <string.h>
15
16namespace
17{
18void put_u(pc_sb *b, uint32_t v)
19{
20 char tmp[11];
21 int n = 0;
22 do
23 {
24 tmp[n++] = (char)('0' + (int)(v % 10));
25 v /= 10;
26 } while (v);
27 char out[12];
28 for (int i = 0; i < n; i++)
29 {
30 out[i] = tmp[n - 1 - i];
31 }
32 out[n] = '\0';
33 pc_sb_put(b, out);
34}
35} // namespace
36
37size_t pc_utmc_request(const char *object_id, char *out, size_t cap)
38{
39 pc_sb b = {out, cap, 0, out != nullptr && cap > 0};
40 pc_sb_put(&b, "<?xml version=\"1.0\"?><UTMCRequest><object id=\"");
41 pc_sb_xml(&b, object_id);
42 pc_sb_put(&b, "\"/></UTMCRequest>");
43 return pc_sb_finish(&b);
44}
45
46size_t pc_utmc_response(const char *object_id, const char *value, uint8_t quality, const char *timestamp, char *out,
47 size_t cap)
48{
49 pc_sb b2 = {out, cap, 0, out != nullptr && cap > 0};
50 pc_sb_put(&b2, "<?xml version=\"1.0\"?><UTMCResponse><object id=\"");
51 pc_sb_xml(&b2, object_id);
52 pc_sb_put(&b2, "\" value=\"");
53 pc_sb_xml(&b2, value);
54 pc_sb_put(&b2, "\" quality=\"");
55 put_u(&b2, quality);
56 pc_sb_put(&b2, "\" timestamp=\"");
57 pc_sb_xml(&b2, timestamp);
58 pc_sb_put(&b2, "\"/></UTMCResponse>");
59 return pc_sb_finish(&b2);
60}
61
62size_t pc_utmc_parse_request(const char *xml, size_t len, char *out, size_t cap)
63{
64 if (!xml || !out || cap == 0)
65 {
66 return 0;
67 }
68 // Find `id="` and copy up to the next quote.
69 const char *key = "id=\"";
70 size_t kl = 4;
71 for (size_t i = 0; i + kl < len; i++)
72 {
73 if (memcmp(xml + i, key, kl) != 0)
74 {
75 continue;
76 }
77 size_t j = i + kl;
78 size_t k = 0;
79 while (j < len && xml[j] != '"')
80 {
81 if (k + 1 >= cap)
82 {
83 return 0;
84 }
85 out[k++] = xml[j++];
86 }
87 if (j >= len) // unterminated
88 {
89 return 0;
90 }
91 out[k] = '\0';
92 return k;
93 }
94 return 0;
95}
96
97#endif // PC_ENABLE_UTMC
Bounded no-heap string builder that fails closed on overflow (one shared copy).
size_t pc_sb_finish(pc_sb *b)
NUL-terminate and return the built length, or 0 if the build overflowed.
Definition strbuf.h:648
void pc_sb_xml(pc_sb *b, const char *s)
Append s XML-escaped (& < > "); a NULL s appends nothing.
Definition strbuf.h:143
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
UTMC (Urban Traffic Management and Control) common-database codec (PC_ENABLE_UTMC).