MySQL 9.3.0
Source Code Documentation
rapid_json_to_struct.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2023, 2025, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef ROUTER_SRC_REST_MRS_SRC_HELPER_JSON_RAPID_JSON_TO_STRUCT_H_
27#define ROUTER_SRC_REST_MRS_SRC_HELPER_JSON_RAPID_JSON_TO_STRUCT_H_
28
29#include <list>
30#include <string>
31#include <utility>
32
33#include <my_rapidjson_size_t.h>
34#include <rapidjson/reader.h>
35
36namespace helper {
37namespace json {
38
39/**
40 * This class is a adapter for Reader from RapidJson.
41 *
42 * This class adapts std::map of strings (keys and values are strings)
43 * to be destination of text document conversion done be `rapidjson::Reader`.
44 * There are some constrains to what is converted:
45 * * values from top level document are inserted into the map,
46 * * value must be a simple type, sub objects, or arrays are ignored.
47 */
48template <typename UserResult>
50 : public rapidjson::BaseReaderHandler<
51 rapidjson::UTF8<>, RapidReaderHandlerToStruct<UserResult>> {
52 public:
53 constexpr static rapidjson::ParseFlag k_parse_flags{
54 rapidjson::kParseNumbersAsStringsFlag};
55
57 using Parent =
58 rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
60 using Ch = typename Parent::Ch;
61 RapidReaderHandlerToStruct(const std::string &separator = ".")
63 virtual ~RapidReaderHandlerToStruct() = default;
64
65 using Result = UserResult;
66 const UserResult &get_result() { return result_; }
67
68 virtual bool on_new_value() {
70 auto &pk = get_parent_key();
71 if (pk.is_array) {
72 key_.name = std::to_string(pk.array_idx++);
74
75 return true;
76 }
77 return false;
78 }
79
80 public: // template overwrites methods from `rapidjson::BaseReaderHandler`
81 virtual bool Null() {
83 return true;
84 }
85
86 virtual bool Bool(bool) {
88 return true;
89 }
90
91 virtual bool String(const Ch *, rapidjson::SizeType, bool) {
93 return true;
94 }
95
96 virtual bool Int(int) {
98 return true;
99 }
100
101 virtual bool Uint(unsigned) {
102 on_new_value();
103 return true;
104 }
105
106 virtual bool Int64(int64_t) {
107 on_new_value();
108 return true;
109 }
110
111 virtual bool Uint64(uint64_t) {
112 on_new_value();
113 return true;
114 }
115
116 virtual bool Double(double) {
117 on_new_value();
118 return true;
119 }
120
121 virtual void empty_object() {}
122
123 virtual void empty_array() {}
124
125 /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use
126 /// length)
127 virtual bool RawNumber(const Ch *, rapidjson::SizeType, bool) {
128 on_new_value();
129 return true;
130 }
131
132 bool StartObject() {
133 on_new_value();
134 auto k = key_;
136 keys_.push_back(k);
137 ++level_;
138 return true;
139 }
140
142 --level_;
143 if (!keys_.empty()) {
144 auto &b = keys_.back();
145 if (level_ == b.level) {
146 if (b.processed == values_processed_) empty_object();
147 keys_.pop_back();
148 }
149 }
150
151 return true;
152 }
153
154 bool Key(const Ch *str, rapidjson::SizeType len, bool) {
155 key_.name.assign(str, len);
156 key_.level = level_;
157 return true;
158 }
159
160 // Ignore arrays
161 bool StartArray() {
162 on_new_value();
163 auto k = key_;
164 k.is_array = true;
165 k.array_idx = 1;
166 k.processed = values_processed_;
167 keys_.push_back(k);
168
169 ++level_;
170 ++arrays_;
171 return true;
172 }
173
175 --level_;
176 --arrays_;
177 if (!keys_.empty()) {
178 auto &b = keys_.back();
179 if (level_ == b.level) {
180 if (b.processed == values_processed_) empty_array();
181 keys_.pop_back();
182 }
183 }
184 return true;
185 }
186
187 protected:
188 UserResult result_{};
189
190 bool is_object_path() { return level_ > 0 && arrays_ == 0; }
191 bool is_array_value() { return arrays_ > 0; }
192 int get_level() const { return level_; }
193
194 std::string get_current_key() const {
195 std::string result;
196 for (const auto &key : keys_) {
197 // Skip first elemnt if its an array
198 if (key.name.empty()) continue;
199
200 result += key.name + separator_;
201 }
202 return result + key_.name;
203 }
204
205 const std::string separator_;
206
207 struct KeyValue {
208 std::string name;
209 bool is_array{false};
210 int array_idx{0};
211 int level{0};
212 bool leaf{false};
213 uint64_t processed{0};
214 };
215
216 std::list<KeyValue> get_keys() const {
217 auto keys = keys_;
218 auto key = key_;
219 key.leaf = true;
220 keys.push_back(key);
221 return keys;
222 }
223
224 private:
226 if (keys_.empty()) {
227 static KeyValue k_empty;
228 return k_empty;
229 }
230
231 return keys_.back();
232 }
233
234 uint64_t values_processed_{0};
235 std::list<KeyValue> keys_;
237 int level_{0};
238 int arrays_{0};
239};
240
241template <typename UserResult>
243 : public RapidReaderHandlerToStruct<UserResult> {
244 public:
246 using Ch = typename Handler::Ch;
247
248 virtual void handle_object_value(const std::string &key,
249 std::string &&value) = 0;
250
251 virtual void handle_array_value(const std::string &, std::string &&) {}
252
253 void handle_value(std::string &&vt) {
254 const auto &key = Handler::get_current_key();
256 handle_object_value(key, std::move(vt));
257 } else if (Handler::is_array_value()) {
258 handle_array_value(key, std::move(vt));
259 }
260 }
261
262 bool String(const Ch *v, rapidjson::SizeType v_len, bool) override {
263 handle_value(std::string{v, v_len});
264 return true;
265 }
266
267 bool RawNumber(const Ch *v, rapidjson::SizeType v_len, bool) override {
268 handle_value(std::string{v, v_len});
269 return true;
270 }
271
272 bool Bool(bool v) override {
273 handle_value(v ? "true" : "false");
274 return true;
275 }
276};
277
278} // namespace json
279} // namespace helper
280
281#endif // ROUTER_SRC_REST_MRS_SRC_HELPER_JSON_RAPID_JSON_TO_STRUCT_H_
Definition: rapid_json_to_struct.h:243
virtual void handle_array_value(const std::string &, std::string &&)
Definition: rapid_json_to_struct.h:251
void handle_value(std::string &&vt)
Definition: rapid_json_to_struct.h:253
bool RawNumber(const Ch *v, rapidjson::SizeType v_len, bool) override
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
Definition: rapid_json_to_struct.h:267
virtual void handle_object_value(const std::string &key, std::string &&value)=0
bool String(const Ch *v, rapidjson::SizeType v_len, bool) override
Definition: rapid_json_to_struct.h:262
bool Bool(bool v) override
Definition: rapid_json_to_struct.h:272
This class is a adapter for Reader from RapidJson.
Definition: rapid_json_to_struct.h:51
constexpr static rapidjson::ParseFlag k_parse_flags
Definition: rapid_json_to_struct.h:53
bool is_array_value()
Definition: rapid_json_to_struct.h:191
virtual bool Double(double)
Definition: rapid_json_to_struct.h:116
const UserResult & get_result()
Definition: rapid_json_to_struct.h:66
virtual bool Bool(bool)
Definition: rapid_json_to_struct.h:86
KeyValue key_
Definition: rapid_json_to_struct.h:236
KeyValue & get_parent_key()
Definition: rapid_json_to_struct.h:225
int arrays_
Definition: rapid_json_to_struct.h:238
virtual void empty_object()
Definition: rapid_json_to_struct.h:121
rapidjson::BaseReaderHandler< rapidjson::UTF8<>, RapidReaderHandlerToStruct< UserResult > > Parent
Definition: rapid_json_to_struct.h:59
int get_level() const
Definition: rapid_json_to_struct.h:192
RapidReaderHandlerToStruct(const std::string &separator=".")
Definition: rapid_json_to_struct.h:61
bool StartArray()
Definition: rapid_json_to_struct.h:161
std::list< KeyValue > get_keys() const
Definition: rapid_json_to_struct.h:216
typename Parent::Ch Ch
Definition: rapid_json_to_struct.h:60
int level_
Definition: rapid_json_to_struct.h:237
uint64_t values_processed_
Definition: rapid_json_to_struct.h:234
bool Key(const Ch *str, rapidjson::SizeType len, bool)
Definition: rapid_json_to_struct.h:154
virtual bool on_new_value()
Definition: rapid_json_to_struct.h:68
virtual bool Int64(int64_t)
Definition: rapid_json_to_struct.h:106
virtual bool Uint64(uint64_t)
Definition: rapid_json_to_struct.h:111
virtual bool Null()
Definition: rapid_json_to_struct.h:81
virtual bool String(const Ch *, rapidjson::SizeType, bool)
Definition: rapid_json_to_struct.h:91
const std::string separator_
Definition: rapid_json_to_struct.h:205
bool is_object_path()
Definition: rapid_json_to_struct.h:190
bool StartObject()
Definition: rapid_json_to_struct.h:132
virtual bool RawNumber(const Ch *, rapidjson::SizeType, bool)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
Definition: rapid_json_to_struct.h:127
bool EndObject(rapidjson::SizeType)
Definition: rapid_json_to_struct.h:141
UserResult Result
Definition: rapid_json_to_struct.h:65
UserResult result_
Definition: rapid_json_to_struct.h:188
std::list< KeyValue > keys_
Definition: rapid_json_to_struct.h:235
virtual bool Uint(unsigned)
Definition: rapid_json_to_struct.h:101
bool EndArray(rapidjson::SizeType)
Definition: rapid_json_to_struct.h:174
virtual bool Int(int)
Definition: rapid_json_to_struct.h:96
virtual void empty_array()
Definition: rapid_json_to_struct.h:123
std::string get_current_key() const
Definition: rapid_json_to_struct.h:194
static uint keys
Definition: hp_test2.cc:49
static const char separator
Definition: item_func.cc:4454
static std::string to_string(const LEX_STRING &str)
Definition: lex_string.h:50
Define rapidjson::SizeType to be std::uint64_t.
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1084
Definition: cache.h:33
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
const mysqlrouter::sqlstring k_empty
Definition: query_entries_content_file.cc:34
typedef::std::uint64_t SizeType
Definition: my_rapidjson_size_t.h:39
struct result result
Definition: result.h:34
required string key
Definition: replication_asynchronous_connection_failover.proto:60
Definition: rapid_json_to_struct.h:207
int level
Definition: rapid_json_to_struct.h:211
bool is_array
Definition: rapid_json_to_struct.h:209
bool leaf
Definition: rapid_json_to_struct.h:212
uint64_t processed
Definition: rapid_json_to_struct.h:213
int array_idx
Definition: rapid_json_to_struct.h:210
std::string name
Definition: rapid_json_to_struct.h:208
Definition: result.h:30