microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
gdb_packet_recognizer.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2// SPDX-License-Identifier: BSD-2-Clause
3
4#pragma once
5
8#include "../microfmt.hpp"
9#include "gdb_packet_types.hpp" // Contains packet_type enum
10#include <cstddef>
11#include <cstdint>
12
13namespace microfmt::gdb {
14
19public:
20 struct RELOCO_POINTER packet_entry {
21 // Aggregate used by the enclosing class's constexpr tables: a default member initializer cannot be used there.
22 microfmt::string_view prefix;
23 packet_type type; // NOLINT(reloco-member-init)
24
25 constexpr bool operator<(const packet_entry &other) const noexcept { return prefix < other.prefix; }
26 };
27
28 static constexpr size_t k_count_multichar = []() -> size_t {
29 size_t count = 0;
30#define __INSPECTOR_GDB_PACKET_TYPE_X(name, str) \
31 if constexpr (sizeof(str) > 2) { \
32 ++count; \
33 }
35#undef __INSPECTOR_GDB_PACKET_TYPE_X
36 return count;
37 }();
38
39 static constexpr auto k_multi_char_table = []() {
40 reloco::array<packet_entry, k_count_multichar> sub{};
41 size_t idx = 0;
42#define __INSPECTOR_GDB_PACKET_TYPE_X(name, str) \
43 if constexpr (sizeof(str) > 2) { \
44 sub[idx++] = packet_entry{str, packet_type::name}; \
45 }
47#undef __INSPECTOR_GDB_PACKET_TYPE_X
48
49 return sub;
50 }();
51
53 packet_type type; // NOLINT(reloco-member-init)
54 bool is_multi_char; // NOLINT(reloco-member-init)
55 };
56
57 static constexpr auto k_first_byte_table = []() {
58 reloco::array<packet_type, 128> table{};
59 for (size_t i = 0; i < 128; ++i) {
60 table[i] = packet_type::unknown;
61 }
62
63#define __INSPECTOR_GDB_PACKET_TYPE_X(name, str) \
64 if constexpr (sizeof(str) > 2) { \
65 const unsigned char c = static_cast<unsigned char>((str)[0]); \
66 if (c < 128) { \
67 table[c] = packet_type::_multi_char_marker; \
68 } \
69 } else if constexpr (sizeof(str) == 2) { \
70 const unsigned char c = static_cast<unsigned char>((str)[0]); \
71 if (c < 128) { \
72 table[c] = packet_type::name; \
73 } \
74 }
76#undef __INSPECTOR_GDB_PACKET_TYPE_X
77
78 return table;
79 }();
80
87 [[nodiscard]] static constexpr packet_type recognize(string_view payload) noexcept {
88 if (payload.empty()) {
89 return packet_type::unknown;
90 }
91
92 const unsigned char first_char = static_cast<unsigned char>(payload[0]);
93 if (first_char >= 128) {
94 return packet_type::unknown;
95 }
96
97 const packet_type match = k_first_byte_table[first_char];
98
99 // Level 1: O(1) Direct match for single-character commands
100 if (match != packet_type::_multi_char_marker) {
101 return match;
102 }
103
104 // Level 2: Linear search over the small unified multi-character table (~23 entries)
105 for (const auto &entry : k_multi_char_table) {
106 if (payload.substr(0, entry.prefix.size()) == entry.prefix) {
107 return entry.type;
108 }
109 }
110
111 return packet_type::unknown;
112 }
113};
114
115} // namespace microfmt::gdb
Zero-allocation packet payload recognizer.
Definition gdb_packet_recognizer.hpp:18
static constexpr packet_type recognize(string_view payload) noexcept
Identifies the high-level packet_type from a raw GDB packet payload.
Definition gdb_packet_recognizer.hpp:87
#define MICROFMT_API_CLASS
Definition compat.hpp:181
#define __INSPECTOR_GDB_PACKET_TYPE_X(name, str)
Comprehensive enumeration of GDB RSP packet types.
#define INSPECTOR_GDB_PACKET_LIST(X)
Definition gdb_packet_types.hpp:12
Definition gdb_decoders.hpp:15
packet_type
High-level classification of GDB Remote Serial Protocol commands.
Definition gdb_packet_types.hpp:64
Definition gdb_packet_recognizer.hpp:52
bool is_multi_char
Definition gdb_packet_recognizer.hpp:54
packet_type type
Definition gdb_packet_recognizer.hpp:53
Definition gdb_packet_recognizer.hpp:20
packet_type type
Definition gdb_packet_recognizer.hpp:23
microfmt::string_view prefix
Definition gdb_packet_recognizer.hpp:22
constexpr bool operator<(const packet_entry &other) const noexcept
Definition gdb_packet_recognizer.hpp:25