Electroneum
Loading...
Searching...
No Matches
epee::serialization::json Namespace Reference

Functions

template<class t_storage>
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)
template<class t_storage>
bool load_from_json (const std::string &buff_json, t_storage &stg)

Function Documentation

◆ load_from_json()

template<class t_storage>
bool epee::serialization::json::load_from_json ( const std::string & buff_json,
t_storage & stg )
inline

Definition at line 393 of file portable_storage_from_json.h.

394 {
395 std::string::const_iterator sec_buf_begin = buff_json.begin();
396 try
397 {
398 run_handler(nullptr, sec_buf_begin, buff_json.end(), stg, 0);
399 return true;
400 }
401 catch(const std::exception& ex)
402 {
403 MERROR("Failed to parse json, what: " << ex.what());
404 return false;
405 }
406 catch(...)
407 {
408 MERROR("Failed to parse json");
409 return false;
410 }
411 }
#define MERROR(x)
Definition misc_log_ex.h:73
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)
Here is the call graph for this function:

◆ run_handler()

template<class t_storage>
void epee::serialization::json::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 )
inline

Definition at line 49 of file portable_storage_from_json.h.

50 {
51 CHECK_AND_ASSERT_THROW_MES(recursion < EPEE_JSON_RECURSION_LIMIT_INTERNAL, "Wrong JSON data: recursion limitation (" << EPEE_JSON_RECURSION_LIMIT_INTERNAL << ") exceeded");
52
53 std::string::const_iterator sub_element_start;
54 std::string name;
55 typename t_storage::harray h_array = nullptr;
56 enum match_state
57 {
58 match_state_lookup_for_section_start,
59 match_state_lookup_for_name,
60 match_state_waiting_separator,
61 match_state_wonder_after_separator,
62 match_state_wonder_after_value,
63 match_state_wonder_array,
64 match_state_array_after_value,
65 match_state_array_waiting_value,
66 match_state_error
67 };
68
69 enum array_mode
70 {
71 array_mode_undifined = 0,
72 array_mode_sections,
73 array_mode_string,
74 array_mode_numbers,
75 array_mode_booleans
76 };
77
78 match_state state = match_state_lookup_for_section_start;
79 array_mode array_md = array_mode_undifined;
80 std::string::const_iterator it = sec_buf_begin;
81 for(;it != buf_end;it++)
82 {
83 switch (state)
84 {
85 case match_state_lookup_for_section_start:
86 if(*it == '{')
87 state = match_state_lookup_for_name;
88 else CHECK_ISSPACE();
89 break;
90 case match_state_lookup_for_name:
91 switch(*it)
92 {
93 case '"':
94 match_string2(it, buf_end, name);
95 state = match_state_waiting_separator;
96 break;
97 case '}':
98 //this is it! section ends here.
99 //seems that it is empty section
100 sec_buf_begin = it;
101 return;
102 default:
104 }
105 break;
106 case match_state_waiting_separator:
107 if(*it == ':')
108 state = match_state_wonder_after_separator;
109 else CHECK_ISSPACE();
110 break;
111 case match_state_wonder_after_separator:
112 if(*it == '"')
113 {//just a named string value started
114 std::string val;
115 match_string2(it, buf_end, val);
116 //insert text value
117 stg.set_value(name, std::move(val), current_section);
118 state = match_state_wonder_after_value;
119 }else if (epee::misc_utils::parse::isdigit(*it) || *it == '-')
120 {//just a named number value started
121 boost::string_ref val;
122 bool is_v_float = false;bool is_signed = false;
123 match_number2(it, buf_end, val, is_v_float, is_signed);
124 if(!is_v_float)
125 {
126 if(is_signed)
127 {
128 errno = 0;
129 int64_t nval = strtoll(val.data(), NULL, 10);
130 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
131 stg.set_value(name, nval, current_section);
132 }else
133 {
134 errno = 0;
135 uint64_t nval = strtoull(val.data(), NULL, 10);
136 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
137 stg.set_value(name, nval, current_section);
138 }
139 }else
140 {
141 errno = 0;
142 double nval = strtod(val.data(), NULL);
143 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
144 stg.set_value(name, nval, current_section);
145 }
146 state = match_state_wonder_after_value;
147 }else if(isalpha(*it) )
148 {// could be null, true or false
149 boost::string_ref word;
150 match_word2(it, buf_end, word);
151 if(boost::iequals(word, "null"))
152 {
153 state = match_state_wonder_after_value;
154 //just skip this,
155 }else if(boost::iequals(word, "true"))
156 {
157 stg.set_value(name, true, current_section);
158 state = match_state_wonder_after_value;
159 }else if(boost::iequals(word, "false"))
160 {
161 stg.set_value(name, false, current_section);
162 state = match_state_wonder_after_value;
163 }else ASSERT_MES_AND_THROW("Unknown value keyword " << word);
164 }else if(*it == '{')
165 {
166 //sub section here
167 typename t_storage::hsection new_sec = stg.open_section(name, current_section, true);
168 CHECK_AND_ASSERT_THROW_MES(new_sec, "Failed to insert new section in json: " << std::string(it, buf_end));
169 run_handler(new_sec, it, buf_end, stg, recursion + 1);
170 state = match_state_wonder_after_value;
171 }else if(*it == '[')
172 {//array of something
173 state = match_state_wonder_array;
174 }else CHECK_ISSPACE();
175 break;
176 case match_state_wonder_after_value:
177 if(*it == ',')
178 state = match_state_lookup_for_name;
179 else if(*it == '}')
180 {
181 //this is it! section ends here.
182 sec_buf_begin = it;
183 return;
184 }else CHECK_ISSPACE();
185 break;
186 case match_state_wonder_array:
187 if(*it == '[')
188 {
189 ASSERT_MES_AND_THROW("array of array not suppoerted yet :( sorry");
190 //mean array of array
191 }
192 if(*it == '{')
193 {
194 //mean array of sections
195 typename t_storage::hsection new_sec = nullptr;
196 h_array = stg.insert_first_section(name, new_sec, current_section);
197 CHECK_AND_ASSERT_THROW_MES(h_array&&new_sec, "failed to create new section");
198 run_handler(new_sec, it, buf_end, stg, recursion + 1);
199 state = match_state_array_after_value;
200 array_md = array_mode_sections;
201 }else if(*it == '"')
202 {
203 //mean array of strings
204 std::string val;
205 match_string2(it, buf_end, val);
206 h_array = stg.insert_first_value(name, std::move(val), current_section);
207 CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values entry");
208 state = match_state_array_after_value;
209 array_md = array_mode_string;
210 }else if (epee::misc_utils::parse::isdigit(*it) || *it == '-')
211 {//array of numbers value started
212 boost::string_ref val;
213 bool is_v_float = false;bool is_signed_val = false;
214 match_number2(it, buf_end, val, is_v_float, is_signed_val);
215 if(!is_v_float)
216 {
217 if (is_signed_val)
218 {
219 errno = 0;
220 int64_t nval = strtoll(val.data(), NULL, 10);
221 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
222 h_array = stg.insert_first_value(name, nval, current_section);
223 }else
224 {
225 errno = 0;
226 uint64_t nval = strtoull(val.data(), NULL, 10);
227 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
228 h_array = stg.insert_first_value(name, nval, current_section);
229 }
230 CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
231 }else
232 {
233 errno = 0;
234 double nval = strtod(val.data(), NULL);
235 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
236 h_array = stg.insert_first_value(name, nval, current_section);
237 CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
238 }
239
240 state = match_state_array_after_value;
241 array_md = array_mode_numbers;
242 }else if(*it == ']')//empty array
243 {
244 array_md = array_mode_undifined;
245 state = match_state_wonder_after_value;
246 }else if(isalpha(*it) )
247 {// array of booleans
248 boost::string_ref word;
249 match_word2(it, buf_end, word);
250 if(boost::iequals(word, "true"))
251 {
252 h_array = stg.insert_first_value(name, true, current_section);
253 CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
254 state = match_state_array_after_value;
255 array_md = array_mode_booleans;
256 }else if(boost::iequals(word, "false"))
257 {
258 h_array = stg.insert_first_value(name, false, current_section);
259 CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
260 state = match_state_array_after_value;
261 array_md = array_mode_booleans;
262
263 }else ASSERT_MES_AND_THROW("Unknown value keyword " << word)
264 }else CHECK_ISSPACE();
265 break;
266 case match_state_array_after_value:
267 if(*it == ',')
268 state = match_state_array_waiting_value;
269 else if(*it == ']')
270 {
271 h_array = nullptr;
272 array_md = array_mode_undifined;
273 state = match_state_wonder_after_value;
274 }else CHECK_ISSPACE();
275 break;
276 case match_state_array_waiting_value:
277 switch(array_md)
278 {
279 case array_mode_sections:
280 if(*it == '{')
281 {
282 typename t_storage::hsection new_sec = NULL;
283 bool res = stg.insert_next_section(h_array, new_sec);
284 CHECK_AND_ASSERT_THROW_MES(res&&new_sec, "failed to insert next section");
285 run_handler(new_sec, it, buf_end, stg, recursion + 1);
286 state = match_state_array_after_value;
287 }else CHECK_ISSPACE();
288 break;
289 case array_mode_string:
290 if(*it == '"')
291 {
292 std::string val;
293 match_string2(it, buf_end, val);
294 bool res = stg.insert_next_value(h_array, std::move(val));
295 CHECK_AND_ASSERT_THROW_MES(res, "failed to insert values");
296 state = match_state_array_after_value;
297 }else CHECK_ISSPACE();
298 break;
299 case array_mode_numbers:
300 if (epee::misc_utils::parse::isdigit(*it) || *it == '-')
301 {//array of numbers value started
302 boost::string_ref val;
303 bool is_v_float = false;bool is_signed_val = false;
304 match_number2(it, buf_end, val, is_v_float, is_signed_val);
305 bool insert_res = false;
306 if(!is_v_float)
307 {
308 if (is_signed_val)
309 {
310 errno = 0;
311 int64_t nval = strtoll(val.data(), NULL, 10);
312 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
313 insert_res = stg.insert_next_value(h_array, nval);
314 }else
315 {
316 errno = 0;
317 uint64_t nval = strtoull(val.data(), NULL, 10);
318 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
319 insert_res = stg.insert_next_value(h_array, nval);
320 }
321 }else
322 {
323 errno = 0;
324 double nval = strtod(val.data(), NULL);
325 if (errno) throw std::runtime_error("Invalid number: " + std::string(val));
326 insert_res = stg.insert_next_value(h_array, nval);
327 }
328 CHECK_AND_ASSERT_THROW_MES(insert_res, "Failed to insert next value");
329 state = match_state_array_after_value;
330 array_md = array_mode_numbers;
331 }else CHECK_ISSPACE();
332 break;
333 case array_mode_booleans:
334 if(isalpha(*it) )
335 {// array of booleans
336 boost::string_ref word;
337 match_word2(it, buf_end, word);
338 if(boost::iequals(word, "true"))
339 {
340 bool r = stg.insert_next_value(h_array, true);
341 CHECK_AND_ASSERT_THROW_MES(r, " failed to insert values section entry");
342 state = match_state_array_after_value;
343 }else if(boost::iequals(word, "false"))
344 {
345 bool r = stg.insert_next_value(h_array, false);
346 CHECK_AND_ASSERT_THROW_MES(r, " failed to insert values section entry");
347 state = match_state_array_after_value;
348 }
349 else ASSERT_MES_AND_THROW("Unknown value keyword " << word);
350 }else CHECK_ISSPACE();
351 break;
352 case array_mode_undifined:
353 default:
354 ASSERT_MES_AND_THROW("Bad array state");
355 }
356 break;
357 case match_state_error:
358 default:
359 ASSERT_MES_AND_THROW("WRONG JSON STATE");
360 }
361 }
362 }
const char * res
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
#define ASSERT_MES_AND_THROW(message)
void match_string2(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, std::string &val)
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)
void match_word2(std::string::const_iterator &star_end_string, std::string::const_iterator buf_end, boost::string_ref &val)
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL
#define CHECK_ISSPACE()
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
Here is the call graph for this function:
Here is the caller graph for this function: