JsoNeat
Some JSON parse/iterate C++ classes build on top of Jsmn
Loading...
Searching...
No Matches
jsoneat.hh
Go to the documentation of this file.
1/**
2 * \file jsoneat/jsoneat.hh
3 * \brief helper class to iterate the JSMN token array and extract data
4 * \author Bert Winkelmann (github.com/zwiebert)
5 */
6
7#pragma once
8
9#include "jsmn/jsmn.h"
10
11#include <iterator>
12#include <type_traits>
13#include <cstddef>
14#include <cstring>
15#include <cstdlib>
16#include <cassert>
17#include <string>
18
19namespace jsoneat {
20/**
21 * \brief Parse JSON into tokens and iterate over it. Will handle all allocations.
22 *
23 * \tparam input_type type of JSON input buffer. should be char* or const char*
24 */
25template<typename input_type = const char*>
26class JsoNeat {
27 using pointer = jsmntok_t *;
28
29protected:
30 JsoNeat(input_type json, jsmntok_t *tok, unsigned tok_max) :
31 m_json(json), m_tok_heap_alloc(nullptr), m_tok(tok), m_tok_max(tok_max), m_nmb_tok(do_parse(json)) {
32 }
33public:
34
35 JsoNeat(input_type json, unsigned tok_max) :
37 }
38
39 ~JsoNeat() {
40 delete[] m_tok_heap_alloc;
41 }
42
43 operator bool() const {
44 return m_json && m_nmb_tok > 0;
45 }
46
47 /**
48 * \brief get json buffer passed to ctor
49 *
50 * \return pointer to json text buffer
51 */
52 input_type get_json() {
53 return m_json;
54 }
55
56 /**
57 * \brief This has iterator functionality, but also provides lots of token related member functions
58 *
59 * With Jsmn, the token holds indexes of the original JSON buffer.
60 * Like a normal iterator, this struct holds a pointer to the token, which is an element of \ref m_tok_arr
61 *
62 * To access the actual JSON data (\ref m_json in class \ref JsoNeat), \ref m_container in this struct holds a
63 * references, which then can also be used to call member functions of JsoNeat object.
64 *
65 */
66 class Iterator {
67 public:
68 using iterator_category = std::forward_iterator_tag;
69 using difference_type = std::ptrdiff_t;
70 using value_type = jsmntok_t;
71 using pointer = value_type *;
72 using reference = value_type &;
73 using container_type = JsoNeat;
74
75 Iterator(pointer ptr, container_type &container) :
76 m_ptr(ptr), m_container(container) {
77 }
78
79 public:
80
81 /**
82 * \brief Test type and character string of value for being equal
83 * \param s expected string
84 * \param type expected type
85 * \return true for match
86 */
87 bool value_st_equal(const char *s, jsmntype_t type) const {
88 const unsigned slen = strlen(s);
89
90 if (m_ptr->type != type) // not same type
91 return false;
92
93 if (slen != m_ptr->end - m_ptr->start) // not same length
94 return false;
95
96 if (strncmp(m_container.get_json() + m_ptr->start, s, slen) != 0) // not same content
97 return false;
98
99 return true;
100 }
101
102 /**
103 * \brief test for value being null pointer
104 * \return true for match
105 */
106 bool value_equals_null() const {
107 return value_st_equal("null", JSMN_PRIMITIVE);
108 }
109
110 /**
111 * \brief test for value being boolean false
112 * \return true for match
113 */
114 bool value_equals_false() const {
115 return value_st_equal("false", JSMN_PRIMITIVE);
116 }
117
118 /**
119 * \brief test for value being boolean true
120 * \return true for match
121 */
122 bool value_equals_true() const {
123 return value_st_equal("true", JSMN_PRIMITIVE);
124 }
125
126 /**
127 * \brief get json text buffer
128 */
129 input_type get_json() {
130 return m_container.get_json();
131 }
132 /**
133 * \brief test if key matches
134 * \param key key to match
135 * \return false if key does not match or type is not JSMN_STRING
136 */
137 bool keyIsEqual(const char *key) const {
138 return value_st_equal(key, JSMN_STRING); // JSON keys are strings
139 }
140
141 /**
142 * \brief test if both key and value-type matches
143 * \param key string to match key or nullptr to match any key
144 * \param val_type type of value to match
145 * \return false for mismatch or key type not JSMN_STRING
146 */
147 bool keyIsEqual(const char *key, jsmntype_t val_type) const {
148 if (val_type != m_ptr[1].type)
149 return false;
150 return !key || keyIsEqual(key);
151 }
152
153 /**
154 * \brief test if key matches
155 * \param key key to match
156 * \return false if key does not match or type is not JSMN_STRING
157 */
158 bool keyStartsWith(const char *key) const {
159 return m_ptr->type == JSMN_STRING // JSON keys are strings
160 && strlen(key) < m_ptr->end - m_ptr->start // key should be smaller
161 && strncmp(m_container.get_json() + m_ptr->start, key, strlen(key)) == 0; // same content
162 }
163
164 /**
165 * \brief test if both key and value-type matches
166 * \param key string to match key or nullptr to match any key
167 * \param val_type type of value to match
168 * \return false for mismatch or key type not JSMN_STRING
169 */
170 bool keyStartsWith(const char *key, jsmntype_t val_type) const {
171 if (val_type != m_ptr[1].type)
172 return false;
173 return !key || keyStartsWith(key);
174 }
175
176 /**
177 * \brief Get value
178 * \param dst value will be written to dst
179 * \return false if value type is not JSMN_PRIMITIVE Or JSMN_STRING
180 */
181 template<typename T>
182 bool getValue(T &dst) const {
183 return m_container.get_value(dst, m_ptr);
184 }
185 /**
186 * \brief Get value of key/value pair and advance iterator
187 * \param dst value will be written to dst
188 * \return false if value type is not JSMN_PRIMITIVE Or JSMN_STRING
189 */
190 template<typename T>
191 bool takeValue(T &dst) {
192 if (!getValue(dst))
193 return false;
194 *this += 1;
195 return true;
196 }
197
198 /**
199 * \brief Get value as string instead of number or boolean
200 * \param dst value will be written to dst
201 * \return false if value type is not JSMN_PRIMITIVE Or JSMN_STRING
202 */
203 template<size_t size>
204 bool getValueAsString(char (&dst)[size]) const {
205 return m_container.get_value_as_string(dst, size, m_ptr);
206 }
207 /**
208 * \brief Get value as string instead of number or boolean
209 * \param dst value will be written to dst
210 * \param size space available in dst
211 * \return false if value type is not JSMN_PRIMITIVE Or JSMN_STRING
212 */
213 bool getValueAsString(char *dst, size_t size) const {
214 return m_container.get_value_as_string(dst, size, m_ptr);
215 }
216
217 /**
218 * \brief Get value as string null terminated string (in place)
219 *
220 * This works only for non constant input_type, because it writes
221 * into the json text buffer to terminate strings.
222 *
223 * \return pointer to null terminated string. If not JSMN_STRING or JSMN_PRIMITIVE it returns null
224 */
225 char* getValueAsString() const {
226 return m_container.get_value_as_string(m_ptr);
227 }
228
229 /**
230 * \brief Get value of key/value pair if key
231 * \param key key to match or nullptr to match any key
232 * \param dst value will be written to dst
233 * \return false if key does not match, or value type is not JSMN_PRIMITIVE or JSMN_STRING
234 */
235 template<typename T>
236 bool getValue(T &dst, const char *key) const {
237 return keyIsEqual(key) && m_container.get_value(dst, m_ptr + 1);
238 }
239 /**
240 * \brief Get value of key/value pair and advance iterator
241 * \param key key to match or nullptr to match any key
242 * \param dst value will be written to dst
243 * \return false if key does not match, or value type is not JSMN_PRIMITIVE or JSMN_STRING
244 */
245 template<typename T>
246 bool takeValue(T &dst, const char *key) {
247 if (!getValue(dst, key))
248 return false;
249 *this += 2;
250 return true;
251 }
252
253 /**
254 * \brief Get values from array and advance iterator
255 * \tparam T type of array members
256 * \tparam N array_size
257 * \param key key to match or nullptr to match any key
258 * \param dst values will be written to array dst
259 * \return success
260 */
261 template<typename T, std::size_t N>
262 bool takeValueArray(T (&dst)[N], const char *key) {
263 if (!keyIsEqual(key, JSMN_ARRAY))
264 return false;
266
267 auto &it = *this;
268
269 auto count = it->size; // get array size
270 ++it; // skip array token
271 for (int i = 0; i < count && i < N; ++i) {
272 if (!m_container.get_value(dst[i], m_ptr))
273 return false;
274 ++it;
275 }
276 return true;
277 }
278
279 /**
280 * \brief Get object of key/value pair and advance iterator
281 * \param key key to match or nullptr to match any key
282 * \param dst object will be written to dst
283 * \return false if key does not match, or value type is not JSMN_OBJECT
284 */
285 template<typename T>
286 bool takeObject(T &dst, const char *key) {
287 if (!keyIsEqual(key, JSMN_OBJECT))
288 return false;
290 return dst._from_json(*this);
291 }
292
293 /**
294 * \brief Get objects from array and advance iterator
295 * \tparam T type of array members
296 * \tparam N array_size
297 * \param key key to match or nullptr to match any key
298 * \param dst objects will be written to array dst
299 * \return success
300 */
301 template<typename T, size_t N>
302 bool takeObjectArray(T (&dst)[N], const char *key) {
303 if (!keyIsEqual(key, JSMN_ARRAY))
304 return false;
306
307 auto &it = *this;
308
309 auto count = it->size; // get array size
310 ++it; // skip array token
311 for (int i = 0; i < count && i < N; ++i) {
312 if (!dst[i]._from_json(it))
313 return false;
314 }
315 return true;
316 }
317
318 /**
319 * \brief Get objects from array and advance iterator
320 * \tparam T type of array members
321 * \tparam N array_size
322 * \param key key to match or nullptr to match any key
323 * \param dst objects will be written to array dst
324 * \return success
325 */
326 template<typename T, size_t N>
327 bool takeObjectArray(std::array<T, N> &dst, const char *key) {
328 if (!keyIsEqual(key, JSMN_ARRAY))
329 return false;
331
332 auto &it = *this;
333
334 auto count = it->size; // get array size
335 ++it; // skip array token
336 for (int i = 0; i < count && i < N; ++i) {
337 if (!dst[i]._from_json(it))
338
339 return false;
340 }
341 return true;
342 }
343
344 public: // operators
345 reference operator*() const {
346 return *m_ptr;
347 }
348 pointer operator->() {
349 return m_ptr;
350 }
351
352 Iterator operator+(int n) {
353 Iterator tmp = *this;
354 return tmp += n;
355 }
356
357 Iterator operator-(int n) {
358 Iterator tmp = *this;
359 return tmp -= n;
360 }
361
362 Iterator& operator+=(int n) {
363 m_ptr += n;
364 return *this;
365 }
366
367 Iterator& operator-=(int n) {
368 m_ptr -= n;
369 return *this;
370 }
371
372 // Prefix increment
373 Iterator& operator++() {
374 m_ptr++;
375 return *this;
376 }
377
378 // Postfix increment
379 Iterator operator++(int) {
380 Iterator tmp = *this;
381 ++(*this);
382 return tmp;
383 }
384
385 reference operator[](int idx) {
386 return m_ptr[idx];
387 }
388
389 operator bool() const {
390 return m_ptr >= &m_container.m_tok[0] && &m_container.m_tok[0] + m_container.m_nmb_tok > m_ptr;
391 }
392
393 friend bool operator==(const Iterator &a, const Iterator &b) {
394 return a.m_ptr == b.m_ptr;
395 }
396
397 friend bool operator!=(const Iterator &a, const Iterator &b) {
398 return a.m_ptr != b.m_ptr;
399 }
400
401 friend bool operator<(const Iterator &a, const Iterator &b) {
402 return a.m_ptr < b.m_ptr;
403 }
404
405 friend bool operator>(const Iterator &a, const Iterator &b) {
406 return a.m_ptr > b.m_ptr;
407 }
408
409 public:
410 /**
411 * \brief skip this value (of an array)
412 *
413 * \return success.
414 */
415 bool skip_value() {
416 auto &it = *this;
417 if (!it)
418 return false;
419
420 if (it->type == JSMN_OBJECT) {
421 auto count = it->size;
422 for (++it; count > 0 && it; --count) {
423
424 assert(it->type == JSMN_STRING);
426 }
427 return true;
428 }
429
430 if (it->type == JSMN_ARRAY) {
431 auto count = it->size;
432 for (++it; count > 0 && it; --count) {
434 }
435 return true;
436 }
437
438 ++it;
439 return true;
440 }
441
442 /**
443 * \brief skip this key/value pair (in and object)
444 *
445 * \return success.
446 */
448 auto &it = *this;
449 ++it;
450 if (!it)
451 return false;
452 return skip_value();
453 }
454
455 /**
456 * \brief skip this key
457 *
458 * \return success.
459 */
460 bool skip_key() {
461 auto &it = *this;
462 assert(it->type == JSMN_STRING);
463 ++it;
464 return true;
465 }
466
467 private:
468 pointer m_ptr;
469 container_type &m_container;
470 };
471
472 /**
473 * \brief get JSON root object iterator
474 *
475 * \return iterator pointing to root object
476 */
478 return Iterator(&m_tok[0], *this);
479 }
480 /**
481 * \brief get JSON root object end iterator
482 *
483 * \return iterator pointing one behind root object
484 */
486 return Iterator(&m_tok[m_nmb_tok], *this);
487 }
488
489private:
490 int do_parse(const char *json) {
491 if (!json)
492 return false;
493
494 jsmn_parser parser;
495
496 jsmn_init(&parser);
497 int r = jsmn_parse(&parser, json, strlen(json), m_tok, m_tok_max);
498 if (r < 0) {
499 return 0;
500 }
501 if (r < 1 || m_tok[0].type != JSMN_OBJECT) {
502 return 0;
503 }
504 return r;
505 }
506 /**
507 * \brief copy string from a token to a buffer
508 *
509 * \param buf destination buffer to copy to
510 * \param buf_size size of destination buffer
511 * \param ptr pointer to token
512 * \return pointer to buffer on success. null-pointer on failure
513 */
514 char* copy_string(char *buf, size_t buf_size, pointer ptr) const {
515 size_t str_length = ptr->end - ptr->start;
516 if (buf_size <= str_length)
517 return NULL;
518 memcpy(buf, m_json + ptr->start, str_length);
519 buf[str_length] = '\0';
520 return buf;
521 }
522
523 /**
524 * \brief try to read token value into a float reference
525 *
526 * \param dst destination variable reference
527 * \param ptr pointer to token
528 * \return success
529 */
530 bool get_value(float &dst, pointer ptr) const {
531 char buf[32];
532 if (ptr->type == JSMN_PRIMITIVE && copy_string(buf, sizeof buf, ptr)) {
533 dst = atof(buf);
534 return true;
535 }
536 return false;
537 }
538
539 /**
540 * \brief try to read token value into a bool reference
541 *
542 * \param dst destination variable reference
543 * \param ptr pointer to token
544 * \return success
545 */
546 bool get_value(bool &dst, pointer ptr) const {
547 char buf[32];
548 if (ptr->type == JSMN_PRIMITIVE && copy_string(buf, sizeof buf, ptr)) {
549 if (0 == strcmp(buf, "true") || 0 == strcmp(buf, "1")) {
550 dst = true;
551 return true;
552 }
553 if (0 == strcmp(buf, "false") || 0 == strcmp(buf, "0")) {
554 dst = false;
555 return true;
556 }
557 }
558 return false;
559 }
560
561 /**
562 * \brief try to read token value into a std::string reference
563 *
564 * \param dst destination variable reference
565 * \param ptr pointer to token
566 * \return success
567 */
568 bool get_value(std::string &dst, pointer ptr) const {
569 if (ptr->type == JSMN_STRING) {
570 size_t str_length = ptr->end - ptr->start;
571 dst = std::string(ptr->start, str_length);
572 return true;
573 }
574 return false;
575 }
576
577 /**
578 * \brief try to read token value into an integer reference
579 *
580 * the value is converted by standard atol() and casted
581 *
582 * \tparam T type of integer
583 * \param dst destination reference
584 * \param ptr pointer to token
585 * \return success
586 */
587 template<typename T>
588 bool get_value(T &dst, pointer ptr) const {
589 char buf[32];
590 if (ptr->type == JSMN_PRIMITIVE && copy_string(buf, sizeof buf, ptr)) {
591 dst = static_cast<T>(atol(buf));
592 return true;
593 }
594 return false;
595 }
596
597 /**
598 * \brief try to read token value into a char array
599 *
600 * \tparam size array size
601 * \param dst destination array
602 * \param ptr pointer to token
603 * \return success
604 */
605 template<size_t size>
606 bool get_value(char (&dst)[size], pointer ptr) const {
607 if (ptr->type == JSMN_STRING && copy_string(dst, size, ptr)) {
608 return true;
609 }
610 return false;
611 }
612
613 /**
614 * \brief Copy token value string into buffer
615 *
616 * \param dst destination buffer
617 * \param size destination buffer size
618 * \param ptr pointer to token
619 * \return success
620 */
621 bool get_value_as_string(char *dst, size_t size, pointer ptr) const {
622 if ((ptr->type == JSMN_STRING || ptr->type == JSMN_PRIMITIVE) && copy_string(dst, size, ptr)) {
623 return true;
624 }
625 return false;
626 }
627
628 /**
629 * \brief Terminate token value with a null and return the resulting string
630 *
631 * This will modify the parsed JSON buffer
632 *
633 * \param ptr pointer to token
634 * \return null terminated token value string
635 */
636 char* get_value_as_string(pointer ptr) {
637 if (ptr->type != JSMN_STRING && ptr->type != JSMN_PRIMITIVE)
638 return nullptr;
639
640 m_json[ptr->end] = '\0';
641 return m_json + ptr->start;
642 }
643
644private:
645 input_type m_json; ///< the JSON data we work on
646 jsmntok_t *m_tok_heap_alloc; ///< token array pointer on heap used for realloc(), free() only. use \ref m_tok for anything else.
647 jsmntok_t *m_tok; ///< token array we work with
648 unsigned m_tok_max; ///< how many elements \ref m_tok can hold
649 unsigned m_nmb_tok; ///< the actual number of tokens Jsmn has parsed from /ref m_json
650
651};
652
653/**
654 * \brief Parse JSON into fixed size token array.
655 *
656 * \tparam JSON_MAX_TOKENS number of elments in token array
657 * \tparam input_type type of JSON input buffer. should be char* or const char*
658 */
659template<size_t JSON_MAX_TOKENS, typename input_type = const char*>
660class JsoNeat_fs: public JsoNeat<input_type> {
661public:
662 JsoNeat_fs(input_type json) :
663 JsoNeat<input_type>(json, &m_tok_arr[0], JSON_MAX_TOKENS) {
664 }
665private:
666 jsmntok_t m_tok_arr[JSON_MAX_TOKENS]; ///< fixed size token array, suitable for stack
667};
668
669using JsonNeat_cp = JsoNeat<char *>;
670///< working on non-const char JSON. this allows null terminating strings in place with \ref get_value_as_string
671using JsonNeat_ccp = JsoNeat<const char *>;
672///< working on const char JSON.
673
674/**
675 * \brief convenient function template to de-serialize from a JSON string (FIXME: should not be in this header)
676 * \tparam S Type of JSON string like char *, const char *, std::string, ...
677 * \tparam T Type of object. The object has to have a from_json(jsmn_iter) member function template
678 * \tparam MaxTokens fixed size of JSMN token array (allocated on stack)
679 * \param json JSON string
680 * \return success
681 */
682template<int MaxTokens = 32, typename T, typename S>
683bool from_json_member(T &obj, S json) {
684 // tokenize JSON string using JSMN
685 auto jsmn = JsoNeat_fs<MaxTokens, S>(json);
686 if (!jsmn)
687 return false;
688
689 // pass the rest of the work to an overloaded from_json() member
690 auto it = jsmn.begin();
691
692 return obj._from_json(it);
693}
694
695/**
696 * \brief pair of a reference and a json-key
697 * \tparam D type of data value or object
698 */
699template<typename D>
700struct KvPair {
701 /**
702 * \brief construct object according of arguments.
703 * \param value reference to value variable
704 * \param json_key pointer to json key as cstring
705 */
706 KvPair(const char *json_key, D &value) :
707 key(json_key), val(value) {
708 }
709
710 const char *key;
711 D &val;
712};
713
714// private macros for creating argument list of reference/key-string pairs
715#define _JSONEAT_COUNT_N(_1, _2, _3, _4, _5, _6, _7,_8, _9, _10, N, ...) N
716#define _JSONEAT_COUNT(...) _JSONEAT_COUNT_N( __VA_ARGS__, 10, 9, 8, 7, 6, 5 ,4, 3, 2, 1)
717#define _JSONEAT_BUILD_CHAIN_1(_1) _JSONEAT_KvPairs_ACT(_1)
718#define _JSONEAT_BUILD_CHAIN_2(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_1(__VA_ARGS__)
719#define _JSONEAT_BUILD_CHAIN_3(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_2(__VA_ARGS__)
720#define _JSONEAT_BUILD_CHAIN_4(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_3(__VA_ARGS__)
721#define _JSONEAT_BUILD_CHAIN_5(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_4(__VA_ARGS__)
722#define _JSONEAT_BUILD_CHAIN_6(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_5(__VA_ARGS__)
723#define _JSONEAT_BUILD_CHAIN_7(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_6(__VA_ARGS__)
724#define _JSONEAT_BUILD_CHAIN_8(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_7(__VA_ARGS__)
725#define _JSONEAT_BUILD_CHAIN_9(_1, ...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_8(__VA_ARGS__)
726#define _JSONEAT_BUILD_CHAIN_10(_1,...) _JSONEAT_KvPairs_ACT(_1) , _JSONEAT_BUILD_CHAIN_9(__VA_ARGS__)
727#define _JSONEAT_BUILD_CHAIN_INC( CT, ...) _JSONEAT_BUILD_CHAIN_ ## CT (__VA_ARGS__)
728#define _JSONEAT_BUILD_CHAIN( CT, ...) _JSONEAT_BUILD_CHAIN_INC(CT, __VA_ARGS__)
729#define _JSONEAT_KvPairs_ACT(x) jsoneat::KvPair(#x, x)
730
731/**
732 * \brief Create argument list of jsoneat::KvPair-pairs, each containg a data-member reference and the corrosponding JSON key with the same name as the data-member
733 * \args list of all data-members to be de-serialized.
734 */
735#define JSONEAT_KvPairs(...) _JSONEAT_BUILD_CHAIN( _JSONEAT_COUNT(__VA_ARGS__), __VA_ARGS__)
736
737}
This has iterator functionality, but also provides lots of token related member functions.
Definition jsoneat.hh:66
bool getValue(T &dst) const
Get value.
Definition jsoneat.hh:182
bool keyStartsWith(const char *key) const
test if key matches
Definition jsoneat.hh:158
bool skip_key_and_value()
skip this key/value pair (in and object)
Definition jsoneat.hh:447
bool value_equals_true() const
test for value being boolean true
Definition jsoneat.hh:122
bool keyIsEqual(const char *key, jsmntype_t val_type) const
test if both key and value-type matches
Definition jsoneat.hh:147
bool getValueAsString(char *dst, size_t size) const
Get value as string instead of number or boolean.
Definition jsoneat.hh:213
bool keyIsEqual(const char *key) const
test if key matches
Definition jsoneat.hh:137
bool takeValue(T &dst, const char *key)
Get value of key/value pair and advance iterator.
Definition jsoneat.hh:246
char * getValueAsString() const
Get value as string null terminated string (in place)
Definition jsoneat.hh:225
bool getValueAsString(char(&dst)[size]) const
Get value as string instead of number or boolean.
Definition jsoneat.hh:204
bool keyStartsWith(const char *key, jsmntype_t val_type) const
test if both key and value-type matches
Definition jsoneat.hh:170
bool takeObject(T &dst, const char *key)
Get object of key/value pair and advance iterator.
Definition jsoneat.hh:286
bool skip_value()
skip this value (of an array)
Definition jsoneat.hh:415
bool getValue(T &dst, const char *key) const
Get value of key/value pair if key.
Definition jsoneat.hh:236
bool takeObjectArray(std::array< T, N > &dst, const char *key)
Get objects from array and advance iterator.
Definition jsoneat.hh:327
bool takeValueArray(T(&dst)[N], const char *key)
Get values from array and advance iterator.
Definition jsoneat.hh:262
bool skip_key()
skip this key
Definition jsoneat.hh:460
bool value_st_equal(const char *s, jsmntype_t type) const
Test type and character string of value for being equal.
Definition jsoneat.hh:87
bool value_equals_false() const
test for value being boolean false
Definition jsoneat.hh:114
bool takeValue(T &dst)
Get value of key/value pair and advance iterator.
Definition jsoneat.hh:191
bool takeObjectArray(T(&dst)[N], const char *key)
Get objects from array and advance iterator.
Definition jsoneat.hh:302
bool value_equals_null() const
test for value being null pointer
Definition jsoneat.hh:106
input_type get_json()
get json text buffer
Definition jsoneat.hh:129
Parse JSON into fixed size token array.
Definition jsoneat.hh:660
Parse JSON into tokens and iterate over it. Will handle all allocations.
Definition jsoneat.hh:26
Iterator end()
get JSON root object end iterator
Definition jsoneat.hh:485
input_type get_json()
get json buffer passed to ctor
Definition jsoneat.hh:52
Iterator begin()
get JSON root object iterator
Definition jsoneat.hh:477
#define _JSONEAT_BUILD_CHAIN_6(_1,...)
Definition jsoneat.hh:722
#define _JSONEAT_BUILD_CHAIN_1(_1)
Definition jsoneat.hh:717
#define _JSONEAT_BUILD_CHAIN(CT,...)
Definition jsoneat.hh:728
#define _JSONEAT_BUILD_CHAIN_INC(CT,...)
Definition jsoneat.hh:727
#define _JSONEAT_BUILD_CHAIN_4(_1,...)
Definition jsoneat.hh:720
#define _JSONEAT_COUNT_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N,...)
Definition jsoneat.hh:715
#define _JSONEAT_COUNT(...)
Definition jsoneat.hh:716
#define _JSONEAT_BUILD_CHAIN_9(_1,...)
Definition jsoneat.hh:725
#define _JSONEAT_BUILD_CHAIN_7(_1,...)
Definition jsoneat.hh:723
#define _JSONEAT_BUILD_CHAIN_8(_1,...)
Definition jsoneat.hh:724
#define _JSONEAT_BUILD_CHAIN_2(_1,...)
Definition jsoneat.hh:718
#define _JSONEAT_KvPairs_ACT(x)
Definition jsoneat.hh:729
#define _JSONEAT_BUILD_CHAIN_5(_1,...)
Definition jsoneat.hh:721
bool from_json_member(T &obj, S json)
convenient function template to de-serialize from a JSON string (FIXME: should not be in this header)
Definition jsoneat.hh:683
#define _JSONEAT_BUILD_CHAIN_3(_1,...)
Definition jsoneat.hh:719
pair of a reference and a json-key
Definition jsoneat.hh:700
KvPair(const char *json_key, D &value)
construct object according of arguments.
Definition jsoneat.hh:706