28 #include <boost/lexical_cast.hpp> 29 #include <boost/utility/string_ref.hpp> 30 #include <boost/algorithm/string/predicate.hpp> 34 #undef MONERO_DEFAULT_LOG_CATEGORY 35 #define MONERO_DEFAULT_LOG_CATEGORY "serialization" 37 #define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100 41 using namespace misc_utils::parse;
46 #define CHECK_ISSPACE() if(!epee::misc_utils::parse::isspace(*it)){ ASSERT_MES_AND_THROW("Wrong JSON character at: " << std::string(it, buf_end));} 52 template<
class t_storage>
53 inline void run_handler(
typename t_storage::hsection current_section, std::string::const_iterator& sec_buf_begin, std::string::const_iterator buf_end, t_storage& stg,
unsigned int recursion)
61 match_state_lookup_for_section_start,
62 match_state_lookup_for_name,
63 match_state_waiting_separator,
64 match_state_wonder_after_separator,
65 match_state_wonder_after_value,
66 match_state_wonder_array,
67 match_state_array_after_value,
68 match_state_array_waiting_value,
74 array_mode_undifined = 0,
81 match_state
state = match_state_lookup_for_section_start;
82 array_mode array_md = array_mode_undifined;
83 std::string::const_iterator it = sec_buf_begin;
84 for(;it != buf_end;it++)
88 case match_state_lookup_for_section_start:
90 state = match_state_lookup_for_name;
93 case match_state_lookup_for_name:
98 state = match_state_waiting_separator;
109 case match_state_waiting_separator:
111 state = match_state_wonder_after_separator;
114 case match_state_wonder_after_separator:
121 state = match_state_wonder_after_value;
124 boost::string_ref val;
125 bool is_v_float =
false;
bool is_signed =
false;
132 int64_t nval = strtoll(val.data(), NULL, 10);
133 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
134 stg.set_value(
name,
int64_t(nval), current_section);
138 uint64_t nval = strtoull(val.data(), NULL, 10);
139 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
145 double nval = strtod(val.data(), NULL);
146 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
147 stg.set_value(
name,
double(nval), current_section);
149 state = match_state_wonder_after_value;
150 }
else if(isalpha(*it) )
152 boost::string_ref word;
154 if(boost::iequals(word,
"null"))
156 state = match_state_wonder_after_value;
158 }
else if(boost::iequals(word,
"true"))
160 stg.set_value(
name,
true, current_section);
161 state = match_state_wonder_after_value;
162 }
else if(boost::iequals(word,
"false"))
164 stg.set_value(
name,
false, current_section);
165 state = match_state_wonder_after_value;
166 }
else ASSERT_MES_AND_THROW(
"Unknown value keyword " << word);
171 CHECK_AND_ASSERT_THROW_MES(new_sec,
"Failed to insert new section in json: " <<
std::string(it, buf_end));
172 run_handler(new_sec, it, buf_end, stg, recursion + 1);
173 state = match_state_wonder_after_value;
176 state = match_state_wonder_array;
179 case match_state_wonder_after_value:
181 state = match_state_lookup_for_name;
189 case match_state_wonder_array:
192 ASSERT_MES_AND_THROW(
"array of array not suppoerted yet :( sorry");
199 h_array = stg.insert_first_section(
name, new_sec, current_section);
200 CHECK_AND_ASSERT_THROW_MES(h_array&&new_sec,
"failed to create new section");
201 run_handler(new_sec, it, buf_end, stg, recursion + 1);
202 state = match_state_array_after_value;
203 array_md = array_mode_sections;
209 h_array = stg.insert_first_value(
name,
std::move(val), current_section);
210 CHECK_AND_ASSERT_THROW_MES(h_array,
" failed to insert values entry");
211 state = match_state_array_after_value;
212 array_md = array_mode_string;
215 boost::string_ref val;
216 bool is_v_float =
false;
bool is_signed_val =
false;
223 int64_t nval = strtoll(val.data(), NULL, 10);
224 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
225 h_array = stg.insert_first_value(
name,
int64_t(nval), current_section);
229 uint64_t nval = strtoull(val.data(), NULL, 10);
230 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
231 h_array = stg.insert_first_value(
name,
uint64_t(nval), current_section);
233 CHECK_AND_ASSERT_THROW_MES(h_array,
" failed to insert values section entry");
237 double nval = strtod(val.data(), NULL);
238 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
239 h_array = stg.insert_first_value(
name,
double(nval), current_section);
240 CHECK_AND_ASSERT_THROW_MES(h_array,
" failed to insert values section entry");
243 state = match_state_array_after_value;
244 array_md = array_mode_numbers;
247 array_md = array_mode_undifined;
248 state = match_state_wonder_after_value;
249 }
else if(isalpha(*it) )
251 boost::string_ref word;
253 if(boost::iequals(word,
"true"))
255 h_array = stg.insert_first_value(
name,
true, current_section);
256 CHECK_AND_ASSERT_THROW_MES(h_array,
" failed to insert values section entry");
257 state = match_state_array_after_value;
258 array_md = array_mode_booleans;
259 }
else if(boost::iequals(word,
"false"))
261 h_array = stg.insert_first_value(
name,
false, current_section);
262 CHECK_AND_ASSERT_THROW_MES(h_array,
" failed to insert values section entry");
263 state = match_state_array_after_value;
264 array_md = array_mode_booleans;
266 }
else ASSERT_MES_AND_THROW(
"Unknown value keyword " << word)
269 case match_state_array_after_value:
271 state = match_state_array_waiting_value;
275 array_md = array_mode_undifined;
276 state = match_state_wonder_after_value;
279 case match_state_array_waiting_value:
282 case array_mode_sections:
286 bool res = stg.insert_next_section(h_array, new_sec);
287 CHECK_AND_ASSERT_THROW_MES(
res&&new_sec,
"failed to insert next section");
288 run_handler(new_sec, it, buf_end, stg, recursion + 1);
289 state = match_state_array_after_value;
292 case array_mode_string:
297 bool res = stg.insert_next_value(h_array,
std::move(val));
298 CHECK_AND_ASSERT_THROW_MES(
res,
"failed to insert values");
299 state = match_state_array_after_value;
302 case array_mode_numbers:
305 boost::string_ref val;
306 bool is_v_float =
false;
bool is_signed_val =
false;
308 bool insert_res =
false;
314 int64_t nval = strtoll(val.data(), NULL, 10);
315 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
316 insert_res = stg.insert_next_value(h_array,
int64_t(nval));
320 uint64_t nval = strtoull(val.data(), NULL, 10);
321 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
322 insert_res = stg.insert_next_value(h_array,
uint64_t(nval));
327 double nval = strtod(val.data(), NULL);
328 if (errno)
throw std::runtime_error(
"Invalid number: " +
std::string(val));
329 insert_res = stg.insert_next_value(h_array,
double(nval));
331 CHECK_AND_ASSERT_THROW_MES(insert_res,
"Failed to insert next value");
332 state = match_state_array_after_value;
333 array_md = array_mode_numbers;
336 case array_mode_booleans:
339 boost::string_ref word;
341 if(boost::iequals(word,
"true"))
343 bool r = stg.insert_next_value(h_array,
true);
344 CHECK_AND_ASSERT_THROW_MES(
r,
" failed to insert values section entry");
345 state = match_state_array_after_value;
346 }
else if(boost::iequals(word,
"false"))
348 bool r = stg.insert_next_value(h_array,
false);
349 CHECK_AND_ASSERT_THROW_MES(
r,
" failed to insert values section entry");
350 state = match_state_array_after_value;
352 else ASSERT_MES_AND_THROW(
"Unknown value keyword " << word);
355 case array_mode_undifined:
357 ASSERT_MES_AND_THROW(
"Bad array state");
360 case match_state_error:
362 ASSERT_MES_AND_THROW(
"WRONG JSON STATE");
395 template<
class t_storage>
398 std::string::const_iterator sec_buf_begin = buff_json.begin();
401 run_handler(
nullptr, sec_buf_begin, buff_json.end(), stg, 0);
404 catch(
const std::exception& ex)
406 MERROR(
"Failed to parse json, what: " << ex.what());
411 MERROR(
"Failed to parse json");
const char * res
Definition: hmac_keccak.cpp:42
Definition: binary_utils.h:36
#define CHECK_ISSPACE()
Definition: portable_storage_from_json.h:46
array_entry * harray
Definition: portable_storage_base.h:175
bool isdigit(char c)
Definition: parserse_base_utils.h:91
::std::string string
Definition: gtest-port.h:1097
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL
Definition: portable_storage_from_json.h:37
section * hsection
Definition: portable_storage_base.h:174
ps load_from_json(std::string((const char *) buf, len))
void match_string2(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, std::string &val)
Definition: parserse_base_utils.cpp:95
void match_number2(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, boost::string_ref &val, bool &is_float_val, bool &is_signed_val)
Definition: parserse_base_utils.cpp:187
unsigned __int64 uint64_t
Definition: stdint.h:136
void run_handler(typename t_storage::hsection current_section, std::string::const_iterator &sec_buf_begin, std::string::const_iterator buf_end, t_storage &stg, unsigned int recursion)
Definition: portable_storage_from_json.h:53
void match_word2(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, boost::string_ref &val)
Definition: parserse_base_utils.cpp:223
r
Definition: testupnpigd.py:61
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
const T & move(const T &t)
Definition: gtest-port.h:1317
Definition: blake256.h:36
signed __int64 int64_t
Definition: stdint.h:135
const char * name
Definition: options.c:30
rapidjson::Document json
Definition: transport.cpp:49