rippled
Loading...
Searching...
No Matches
json_value.cpp
1#include <xrpl/beast/core/LexicalCast.h>
2#include <xrpl/beast/utility/instrumentation.h>
3#include <xrpl/json/detail/json_assert.h>
4#include <xrpl/json/json_forwards.h>
5#include <xrpl/json/json_value.h>
6#include <xrpl/json/json_writer.h>
7
8#include <cmath>
9#include <cstdlib>
10#include <cstring>
11#include <string>
12#include <utility>
13
14namespace Json {
15
16Value const Value::null;
17
19{
20public:
21 virtual ~DefaultValueAllocator() = default;
22
23 char*
24 makeMemberName(char const* memberName) override
25 {
26 return duplicateStringValue(memberName);
27 }
28
29 void
30 releaseMemberName(char* memberName) override
31 {
32 releaseStringValue(memberName);
33 }
34
35 char*
36 duplicateStringValue(char const* value, unsigned int length = unknown)
37 override
38 {
39 //@todo investigate this old optimization
40 // if ( !value || value[0] == 0 )
41 // return 0;
42
43 if (length == unknown)
44 length = value ? (unsigned int)strlen(value) : 0;
45
46 char* newString = static_cast<char*>(malloc(length + 1));
47 if (value)
48 memcpy(newString, value, length);
49 newString[length] = 0;
50 return newString;
51 }
52
53 void
54 releaseStringValue(char* value) override
55 {
56 if (value)
57 free(value);
58 }
59};
60
61static ValueAllocator*&
67
69{
71 {
72 valueAllocator(); // ensure valueAllocator() statics are initialized
73 // before main().
74 }
76
77// //////////////////////////////////////////////////////////////////
78// //////////////////////////////////////////////////////////////////
79// //////////////////////////////////////////////////////////////////
80// class Value::CZString
81// //////////////////////////////////////////////////////////////////
82// //////////////////////////////////////////////////////////////////
83// //////////////////////////////////////////////////////////////////
84
85// Notes: index_ indicates if the string was allocated when
86// a string is stored.
87
88Value::CZString::CZString(int index) : cstr_(0), index_(index)
89{
90}
91
93 : cstr_(
94 allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr)
95 , index_(allocate)
96{
97}
98
100 : cstr_(
101 other.index_ != noDuplication && other.cstr_ != 0
102 ? valueAllocator()->makeMemberName(other.cstr_)
103 : other.cstr_)
104 , index_(
105 other.cstr_
106 ? (other.index_ == noDuplication ? noDuplication : duplicate)
107 : other.index_)
108{
109}
110
112{
113 if (cstr_ && index_ == duplicate)
114 valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
115}
116
117bool
118Value::CZString::operator<(CZString const& other) const
119{
120 if (cstr_ && other.cstr_)
121 return strcmp(cstr_, other.cstr_) < 0;
122
123 return index_ < other.index_;
124}
125
126bool
128{
129 if (cstr_ && other.cstr_)
130 return strcmp(cstr_, other.cstr_) == 0;
131
132 return index_ == other.index_;
133}
134
135int
137{
138 return index_;
139}
140
141char const*
143{
144 return cstr_;
145}
146
147bool
149{
150 return index_ == noDuplication;
151}
152
153// //////////////////////////////////////////////////////////////////
154// //////////////////////////////////////////////////////////////////
155// //////////////////////////////////////////////////////////////////
156// class Value::Value
157// //////////////////////////////////////////////////////////////////
158// //////////////////////////////////////////////////////////////////
159// //////////////////////////////////////////////////////////////////
160
166{
167 switch (type)
168 {
169 case nullValue:
170 break;
171
172 case intValue:
173 case uintValue:
174 value_.int_ = 0;
175 break;
176
177 case realValue:
178 value_.real_ = 0.0;
179 break;
180
181 case stringValue:
182 value_.string_ = 0;
183 break;
184
185 case arrayValue:
186 case objectValue:
187 value_.map_ = new ObjectValues();
188 break;
189
190 case booleanValue:
191 value_.bool_ = false;
192 break;
193
194 // LCOV_EXCL_START
195 default:
196 UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
197 // LCOV_EXCL_STOP
198 }
199}
200
201Value::Value(Int value) : type_(intValue)
202{
203 value_.int_ = value;
204}
205
207{
208 value_.uint_ = value;
209}
210
211Value::Value(double value) : type_(realValue)
212{
213 value_.real_ = value;
214}
215
216Value::Value(char const* value) : type_(stringValue), allocated_(true)
217{
219}
220
221Value::Value(ripple::Number const& value) : type_(stringValue), allocated_(true)
222{
223 auto const tmp = to_string(value);
225 valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
226}
227
228Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
229{
231 value.c_str(), (unsigned int)value.length());
232}
233
234Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
235{
236 value_.string_ = const_cast<char*>(value.c_str());
237}
238
239Value::Value(bool value) : type_(booleanValue)
240{
241 value_.bool_ = value;
242}
243
244Value::Value(Value const& other) : type_(other.type_)
245{
246 switch (type_)
247 {
248 case nullValue:
249 case intValue:
250 case uintValue:
251 case realValue:
252 case booleanValue:
253 value_ = other.value_;
254 break;
255
256 case stringValue:
257 if (other.value_.string_)
258 {
260 other.value_.string_);
261 allocated_ = true;
262 }
263 else
264 value_.string_ = 0;
265
266 break;
267
268 case arrayValue:
269 case objectValue:
270 value_.map_ = new ObjectValues(*other.value_.map_);
271 break;
272
273 // LCOV_EXCL_START
274 default:
275 UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
276 // LCOV_EXCL_STOP
277 }
278}
279
281{
282 switch (type_)
283 {
284 case nullValue:
285 case intValue:
286 case uintValue:
287 case realValue:
288 case booleanValue:
289 break;
290
291 case stringValue:
292 if (allocated_)
294
295 break;
296
297 case arrayValue:
298 case objectValue:
299 if (value_.map_)
300 delete value_.map_;
301 break;
302
303 // LCOV_EXCL_START
304 default:
305 UNREACHABLE("Json::Value::~Value : invalid type");
306 // LCOV_EXCL_STOP
307 }
308}
309
310Value&
312{
313 Value tmp(other);
314 swap(tmp);
315 return *this;
316}
317
318Value::Value(Value&& other) noexcept
319 : value_(other.value_), type_(other.type_), allocated_(other.allocated_)
320{
321 other.type_ = nullValue;
322 other.allocated_ = 0;
323}
324
325Value&
327{
328 Value tmp(std::move(other));
329 swap(tmp);
330 return *this;
331}
332
333void
334Value::swap(Value& other) noexcept
335{
336 std::swap(value_, other.value_);
337
338 ValueType temp = type_;
339 type_ = other.type_;
340 other.type_ = temp;
341
342 int temp2 = allocated_;
343 allocated_ = other.allocated_;
344 other.allocated_ = temp2;
345}
346
349{
350 return type_;
351}
352
353static int
355{
356 // All negative numbers are less than all unsigned numbers.
357 if (i < 0)
358 return -1;
359
360 // Now we can safely compare.
361 return (i < ui) ? -1 : (i == ui) ? 0 : 1;
362}
363
364bool
365operator<(Value const& x, Value const& y)
366{
367 if (auto signum = x.type_ - y.type_)
368 {
369 if (x.type_ == intValue && y.type_ == uintValue)
370 signum = integerCmp(x.value_.int_, y.value_.uint_);
371 else if (x.type_ == uintValue && y.type_ == intValue)
372 signum = -integerCmp(y.value_.int_, x.value_.uint_);
373 return signum < 0;
374 }
375
376 switch (x.type_)
377 {
378 case nullValue:
379 return false;
380
381 case intValue:
382 return x.value_.int_ < y.value_.int_;
383
384 case uintValue:
385 return x.value_.uint_ < y.value_.uint_;
386
387 case realValue:
388 return x.value_.real_ < y.value_.real_;
389
390 case booleanValue:
391 return x.value_.bool_ < y.value_.bool_;
392
393 case stringValue:
394 return (x.value_.string_ == 0 && y.value_.string_) ||
395 (y.value_.string_ && x.value_.string_ &&
396 strcmp(x.value_.string_, y.value_.string_) < 0);
397
398 case arrayValue:
399 case objectValue: {
400 if (int signum = int(x.value_.map_->size()) - y.value_.map_->size())
401 return signum < 0;
402
403 return *x.value_.map_ < *y.value_.map_;
404 }
405
406 // LCOV_EXCL_START
407 default:
408 UNREACHABLE("Json::operator<(Value, Value) : invalid type");
409 // LCOV_EXCL_STOP
410 }
411
412 return 0; // unreachable
413}
414
415bool
416operator==(Value const& x, Value const& y)
417{
418 if (x.type_ != y.type_)
419 {
420 if (x.type_ == intValue && y.type_ == uintValue)
421 return !integerCmp(x.value_.int_, y.value_.uint_);
422 if (x.type_ == uintValue && y.type_ == intValue)
423 return !integerCmp(y.value_.int_, x.value_.uint_);
424 return false;
425 }
426
427 switch (x.type_)
428 {
429 case nullValue:
430 return true;
431
432 case intValue:
433 return x.value_.int_ == y.value_.int_;
434
435 case uintValue:
436 return x.value_.uint_ == y.value_.uint_;
437
438 case realValue:
439 return x.value_.real_ == y.value_.real_;
440
441 case booleanValue:
442 return x.value_.bool_ == y.value_.bool_;
443
444 case stringValue:
445 return x.value_.string_ == y.value_.string_ ||
446 (y.value_.string_ && x.value_.string_ &&
447 !strcmp(x.value_.string_, y.value_.string_));
448
449 case arrayValue:
450 case objectValue:
451 return x.value_.map_->size() == y.value_.map_->size() &&
452 *x.value_.map_ == *y.value_.map_;
453
454 // LCOV_EXCL_START
455 default:
456 UNREACHABLE("Json::operator==(Value, Value) : invalid type");
457 // LCOV_EXCL_STOP
458 }
459
460 return 0; // unreachable
461}
462
463char const*
465{
466 XRPL_ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
467 return value_.string_;
468}
469
472{
473 switch (type_)
474 {
475 case nullValue:
476 return "";
477
478 case stringValue:
479 return value_.string_ ? value_.string_ : "";
480
481 case booleanValue:
482 return value_.bool_ ? "true" : "false";
483
484 case intValue:
485 return std::to_string(value_.int_);
486
487 case uintValue:
489
490 case realValue:
492
493 case arrayValue:
494 case objectValue:
495 JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
496
497 // LCOV_EXCL_START
498 default:
499 UNREACHABLE("Json::Value::asString : invalid type");
500 // LCOV_EXCL_STOP
501 }
502
503 return ""; // unreachable
504}
505
508{
509 switch (type_)
510 {
511 case nullValue:
512 return 0;
513
514 case intValue:
515 return value_.int_;
516
517 case uintValue:
518 JSON_ASSERT_MESSAGE(
519 value_.uint_ < (unsigned)maxInt,
520 "integer out of signed integer range");
521 return value_.uint_;
522
523 case realValue:
524 JSON_ASSERT_MESSAGE(
526 "Real out of signed integer range");
527 return Int(value_.real_);
528
529 case booleanValue:
530 return value_.bool_ ? 1 : 0;
531
532 case stringValue: {
533 char const* const str{value_.string_ ? value_.string_ : ""};
534 return beast::lexicalCastThrow<int>(str);
535 }
536
537 case arrayValue:
538 case objectValue:
539 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
540
541 // LCOV_EXCL_START
542 default:
543 UNREACHABLE("Json::Value::asInt : invalid type");
544 // LCOV_EXCL_STOP
545 }
546
547 return 0; // unreachable;
548}
549
550UInt
552{
553 switch (type_)
554 {
555 case nullValue:
556 return 0;
557
558 case intValue: {
559 // Doing this conversion through int64 avoids overflow error for
560 // value_.int_ = -1 * 2^31 i.e. numeric_limits<int>::min().
561 if (value_.int_ < 0)
562 return static_cast<std::int64_t>(value_.int_) * -1;
563 return value_.int_;
564 }
565
566 case uintValue:
567 return value_.uint_;
568
569 case realValue: {
570 if (value_.real_ < 0)
571 {
572 JSON_ASSERT_MESSAGE(
573 -1 * value_.real_ <= maxUInt,
574 "Real out of unsigned integer range");
575 return UInt(-1 * value_.real_);
576 }
577 JSON_ASSERT_MESSAGE(
578 value_.real_ <= maxUInt, "Real out of unsigned integer range");
579 return UInt(value_.real_);
580 }
581
582 case booleanValue:
583 return value_.bool_ ? 1 : 0;
584
585 case stringValue: {
586 char const* const str{value_.string_ ? value_.string_ : ""};
587 auto const temp = beast::lexicalCastThrow<std::int64_t>(str);
588 if (temp < 0)
589 {
590 JSON_ASSERT_MESSAGE(
591 -1 * temp <= maxUInt,
592 "String out of unsigned integer range");
593 return -1 * temp;
594 }
595 JSON_ASSERT_MESSAGE(
596 temp <= maxUInt, "String out of unsigned integer range");
597 return temp;
598 }
599
600 case arrayValue:
601 case objectValue:
602 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
603
604 // LCOV_EXCL_START
605 default:
606 UNREACHABLE("Json::Value::asAbsInt : invalid type");
607 // LCOV_EXCL_STOP
608 }
609
610 return 0; // unreachable;
611}
612
615{
616 switch (type_)
617 {
618 case nullValue:
619 return 0;
620
621 case intValue:
622 JSON_ASSERT_MESSAGE(
623 value_.int_ >= 0,
624 "Negative integer can not be converted to unsigned integer");
625 return value_.int_;
626
627 case uintValue:
628 return value_.uint_;
629
630 case realValue:
631 JSON_ASSERT_MESSAGE(
632 value_.real_ >= 0 && value_.real_ <= maxUInt,
633 "Real out of unsigned integer range");
634 return UInt(value_.real_);
635
636 case booleanValue:
637 return value_.bool_ ? 1 : 0;
638
639 case stringValue: {
640 char const* const str{value_.string_ ? value_.string_ : ""};
641 return beast::lexicalCastThrow<unsigned int>(str);
642 }
643
644 case arrayValue:
645 case objectValue:
646 JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
647
648 // LCOV_EXCL_START
649 default:
650 UNREACHABLE("Json::Value::asUInt : invalid type");
651 // LCOV_EXCL_STOP
652 }
653
654 return 0; // unreachable;
655}
656
657double
659{
660 switch (type_)
661 {
662 case nullValue:
663 return 0.0;
664
665 case intValue:
666 return value_.int_;
667
668 case uintValue:
669 return value_.uint_;
670
671 case realValue:
672 return value_.real_;
673
674 case booleanValue:
675 return value_.bool_ ? 1.0 : 0.0;
676
677 case stringValue:
678 case arrayValue:
679 case objectValue:
680 JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
681
682 // LCOV_EXCL_START
683 default:
684 UNREACHABLE("Json::Value::asDouble : invalid type");
685 // LCOV_EXCL_STOP
686 }
687
688 return 0; // unreachable;
689}
690
691bool
693{
694 switch (type_)
695 {
696 case nullValue:
697 return false;
698
699 case intValue:
700 case uintValue:
701 return value_.int_ != 0;
702
703 case realValue:
704 return value_.real_ != 0.0;
705
706 case booleanValue:
707 return value_.bool_;
708
709 case stringValue:
710 return value_.string_ && value_.string_[0] != 0;
711
712 case arrayValue:
713 case objectValue:
714 return value_.map_->size() != 0;
715
716 // LCOV_EXCL_START
717 default:
718 UNREACHABLE("Json::Value::asBool : invalid type");
719 // LCOV_EXCL_STOP
720 }
721
722 return false; // unreachable;
723}
724
725bool
727{
728 switch (type_)
729 {
730 case nullValue:
731 return true;
732
733 case intValue:
734 return (other == nullValue && value_.int_ == 0) ||
735 other == intValue || (other == uintValue && value_.int_ >= 0) ||
736 other == realValue || other == stringValue ||
737 other == booleanValue;
738
739 case uintValue:
740 return (other == nullValue && value_.uint_ == 0) ||
741 (other == intValue && value_.uint_ <= (unsigned)maxInt) ||
742 other == uintValue || other == realValue ||
743 other == stringValue || other == booleanValue;
744
745 case realValue:
746 return (other == nullValue && value_.real_ == 0.0) ||
747 (other == intValue && value_.real_ >= minInt &&
748 value_.real_ <= maxInt) ||
749 (other == uintValue && value_.real_ >= 0 &&
750 value_.real_ <= maxUInt &&
751 std::fabs(round(value_.real_) - value_.real_) <
753 other == realValue || other == stringValue ||
754 other == booleanValue;
755
756 case booleanValue:
757 return (other == nullValue && value_.bool_ == false) ||
758 other == intValue || other == uintValue || other == realValue ||
759 other == stringValue || other == booleanValue;
760
761 case stringValue:
762 return other == stringValue ||
763 (other == nullValue &&
764 (!value_.string_ || value_.string_[0] == 0));
765
766 case arrayValue:
767 return other == arrayValue ||
768 (other == nullValue && value_.map_->size() == 0);
769
770 case objectValue:
771 return other == objectValue ||
772 (other == nullValue && value_.map_->size() == 0);
773
774 // LCOV_EXCL_START
775 default:
776 UNREACHABLE("Json::Value::isConvertible : invalid type");
777 // LCOV_EXCL_STOP
778 }
779
780 return false; // unreachable;
781}
782
786{
787 switch (type_)
788 {
789 case nullValue:
790 case intValue:
791 case uintValue:
792 case realValue:
793 case booleanValue:
794 case stringValue:
795 return 0;
796
797 case arrayValue: // size of the array is highest index + 1
798 if (!value_.map_->empty())
799 {
800 ObjectValues::const_iterator itLast = value_.map_->end();
801 --itLast;
802 return (*itLast).first.index() + 1;
803 }
804
805 return 0;
806
807 case objectValue:
808 return Int(value_.map_->size());
809
810 // LCOV_EXCL_START
811 default:
812 UNREACHABLE("Json::Value::size : invalid type");
813 // LCOV_EXCL_STOP
814 }
815
816 return 0; // unreachable;
817}
818
819Value::operator bool() const
820{
821 if (isNull())
822 return false;
823
824 if (isString())
825 {
826 auto s = asCString();
827 return s && s[0];
828 }
829
830 return !(isArray() || isObject()) || size();
831}
832
833void
835{
836 XRPL_ASSERT(
838 "Json::Value::clear : valid type");
839
840 switch (type_)
841 {
842 case arrayValue:
843 case objectValue:
844 value_.map_->clear();
845 break;
846
847 default:
848 break;
849 }
850}
851
852Value&
854{
855 XRPL_ASSERT(
857 "Json::Value::operator[](UInt) : valid type");
858
859 if (type_ == nullValue)
860 *this = Value(arrayValue);
861
862 CZString key(index);
863 ObjectValues::iterator it = value_.map_->lower_bound(key);
864
865 if (it != value_.map_->end() && (*it).first == key)
866 return (*it).second;
867
868 ObjectValues::value_type defaultValue(key, null);
869 it = value_.map_->insert(it, defaultValue);
870 return (*it).second;
871}
872
873Value const&
875{
876 XRPL_ASSERT(
878 "Json::Value::operator[](UInt) const : valid type");
879
880 if (type_ == nullValue)
881 return null;
882
883 CZString key(index);
884 ObjectValues::const_iterator it = value_.map_->find(key);
885
886 if (it == value_.map_->end())
887 return null;
888
889 return (*it).second;
890}
891
892Value&
893Value::operator[](char const* key)
894{
895 return resolveReference(key, false);
896}
897
898Value&
899Value::resolveReference(char const* key, bool isStatic)
900{
901 XRPL_ASSERT(
903 "Json::Value::resolveReference : valid type");
904
905 if (type_ == nullValue)
906 *this = Value(objectValue);
907
908 CZString actualKey(
910 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
911
912 if (it != value_.map_->end() && (*it).first == actualKey)
913 return (*it).second;
914
915 ObjectValues::value_type defaultValue(actualKey, null);
916 it = value_.map_->insert(it, defaultValue);
917 Value& value = (*it).second;
918 return value;
919}
920
921Value
922Value::get(UInt index, Value const& defaultValue) const
923{
924 Value const* value = &((*this)[index]);
925 return value == &null ? defaultValue : *value;
926}
927
928bool
930{
931 return index < size();
932}
933
934Value const&
935Value::operator[](char const* key) const
936{
937 XRPL_ASSERT(
939 "Json::Value::operator[](const char*) const : valid type");
940
941 if (type_ == nullValue)
942 return null;
943
944 CZString actualKey(key, CZString::noDuplication);
945 ObjectValues::const_iterator it = value_.map_->find(actualKey);
946
947 if (it == value_.map_->end())
948 return null;
949
950 return (*it).second;
951}
952
953Value&
955{
956 return (*this)[key.c_str()];
957}
958
959Value const&
961{
962 return (*this)[key.c_str()];
963}
964
965Value&
967{
968 return resolveReference(key, true);
969}
970
971Value const&
973{
974 return (*this)[key.c_str()];
975}
976
977Value&
978Value::append(Value const& value)
979{
980 return (*this)[size()] = value;
981}
982
983Value&
985{
986 return (*this)[size()] = std::move(value);
987}
988
989Value
990Value::get(char const* key, Value const& defaultValue) const
991{
992 Value const* value = &((*this)[key]);
993 return value == &null ? defaultValue : *value;
994}
995
996Value
997Value::get(std::string const& key, Value const& defaultValue) const
998{
999 return get(key.c_str(), defaultValue);
1000}
1001
1002Value
1003Value::removeMember(char const* key)
1004{
1005 XRPL_ASSERT(
1007 "Json::Value::removeMember : valid type");
1008
1009 if (type_ == nullValue)
1010 return null;
1011
1012 CZString actualKey(key, CZString::noDuplication);
1013 ObjectValues::iterator it = value_.map_->find(actualKey);
1014
1015 if (it == value_.map_->end())
1016 return null;
1017
1018 Value old(it->second);
1019 value_.map_->erase(it);
1020 return old;
1021}
1022
1023Value
1025{
1026 return removeMember(key.c_str());
1027}
1028
1029bool
1030Value::isMember(char const* key) const
1031{
1032 if (type_ != objectValue)
1033 return false;
1034
1035 Value const* value = &((*this)[key]);
1036 return value != &null;
1037}
1038
1039bool
1041{
1042 return isMember(key.c_str());
1043}
1044
1047{
1048 XRPL_ASSERT(
1050 "Json::Value::getMemberNames : valid type");
1051
1052 if (type_ == nullValue)
1053 return Value::Members();
1054
1055 Members members;
1056 members.reserve(value_.map_->size());
1057 ObjectValues::const_iterator it = value_.map_->begin();
1058 ObjectValues::const_iterator itEnd = value_.map_->end();
1059
1060 for (; it != itEnd; ++it)
1061 members.push_back(std::string((*it).first.c_str()));
1062
1063 return members;
1064}
1065
1066bool
1068{
1069 return type_ == nullValue;
1070}
1071
1072bool
1074{
1075 return type_ == booleanValue;
1076}
1077
1078bool
1080{
1081 return type_ == intValue;
1082}
1083
1084bool
1086{
1087 return type_ == uintValue;
1088}
1089
1090bool
1092{
1093 return type_ == intValue || type_ == uintValue || type_ == booleanValue;
1094}
1095
1096bool
1098{
1099 return type_ == realValue;
1100}
1101
1102bool
1104{
1105 return isIntegral() || isDouble();
1106}
1107
1108bool
1110{
1111 return type_ == stringValue;
1112}
1113
1114bool
1116{
1117 return type_ == arrayValue;
1118}
1119
1120bool
1122{
1123 return type_ == nullValue || type_ == arrayValue;
1124}
1125
1126bool
1128{
1129 return type_ == objectValue;
1130}
1131
1132bool
1134{
1135 return type_ == nullValue || type_ == objectValue;
1136}
1137
1140{
1141 StyledWriter writer;
1142 return writer.write(*this);
1143}
1144
1147{
1148 switch (type_)
1149 {
1150 case arrayValue:
1151 case objectValue:
1152 if (value_.map_)
1153 return const_iterator(value_.map_->begin());
1154
1155 break;
1156 default:
1157 break;
1158 }
1159
1160 return const_iterator();
1161}
1162
1165{
1166 switch (type_)
1167 {
1168 case arrayValue:
1169 case objectValue:
1170 if (value_.map_)
1171 return const_iterator(value_.map_->end());
1172
1173 break;
1174 default:
1175 break;
1176 }
1177
1178 return const_iterator();
1179}
1180
1183{
1184 switch (type_)
1185 {
1186 case arrayValue:
1187 case objectValue:
1188 if (value_.map_)
1189 return iterator(value_.map_->begin());
1190 break;
1191 default:
1192 break;
1193 }
1194
1195 return iterator();
1196}
1197
1200{
1201 switch (type_)
1202 {
1203 case arrayValue:
1204 case objectValue:
1205 if (value_.map_)
1206 return iterator(value_.map_->end());
1207 break;
1208 default:
1209 break;
1210 }
1211
1212 return iterator();
1213}
1214
1215} // namespace Json
T begin(T... args)
T c_str(T... args)
char * duplicateStringValue(char const *value, unsigned int length=unknown) override
virtual ~DefaultValueAllocator()=default
void releaseMemberName(char *memberName) override
char * makeMemberName(char const *memberName) override
void releaseStringValue(char *value) override
Lightweight wrapper to tag static string.
Definition json_value.h:45
constexpr char const * c_str() const
Definition json_value.h:58
Writes a Value in JSON format in a human friendly way.
Definition json_writer.h:72
std::string write(Value const &root) override
Serialize a Value in JSON format.
Experimental do not use: Allocator to customize member name and string value memory management done b...
Definition json_value.h:474
virtual void releaseStringValue(char *value)=0
virtual char * duplicateStringValue(char const *value, unsigned int length=unknown)=0
virtual void releaseMemberName(char *memberName)=0
const iterator for object and array value.
Definition json_value.h:559
Iterator for object and array value.
Definition json_value.h:620
bool isStaticString() const
char const * c_str() const
bool operator==(CZString const &other) const
bool operator<(CZString const &other) const
Represents a JSON value.
Definition json_value.h:131
const_iterator begin() const
Json::UInt UInt
Definition json_value.h:138
bool isArray() const
Value & append(Value const &value)
Append value to array at the end.
UInt size() const
Number of values in array or object.
std::string toStyledString() const
const_iterator end() const
bool isObjectOrNull() const
static Value const null
Definition json_value.h:142
bool isDouble() const
void clear()
Remove all object members and array elements.
char const * asCString() const
Int asInt() const
union Json::Value::ValueHolder value_
ValueIterator iterator
Definition json_value.h:136
ValueConstIterator const_iterator
Definition json_value.h:137
UInt asAbsUInt() const
Correct absolute value from int or unsigned int.
bool isString() const
UInt asUInt() const
Members getMemberNames() const
Return a list of the member names.
std::vector< std::string > Members
Definition json_value.h:135
ValueType type() const
bool isObject() const
Value & operator=(Value const &other)
Value removeMember(char const *key)
Remove and return the named member.
void swap(Value &other) noexcept
Swap values.
Json::Int Int
Definition json_value.h:139
bool isValidIndex(UInt index) const
Return true if index < size().
std::string asString() const
Returns the unquoted string value.
bool isBool() const
static constexpr Int maxInt
Definition json_value.h:144
bool isIntegral() const
bool asBool() const
ValueType type_
Definition json_value.h:425
bool isUInt() const
bool isNull() const
isNull() tests to see if this field is null.
bool isMember(char const *key) const
Return true if the object has a member named key.
bool isArrayOrNull() const
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
Value(ValueType type=nullValue)
Create a default Value of the given type.
static constexpr Int minInt
Definition json_value.h:143
std::map< CZString, Value > ObjectValues
Definition json_value.h:179
Value & resolveReference(char const *key, bool isStatic)
bool isConvertibleTo(ValueType other) const
bool isNumeric() const
double asDouble() const
Value & operator[](UInt index)
Access an array element (zero based index ).
static constexpr UInt maxUInt
Definition json_value.h:145
bool isInt() const
T clear(T... args)
T empty(T... args)
T end(T... args)
T erase(T... args)
T fabs(T... args)
T find(T... args)
T insert(T... args)
T lower_bound(T... args)
JSON (JavaScript Object Notation).
Definition json_errors.h:6
std::string to_string(Value const &)
Writes a Json::Value to an std::string.
Definition to_string.cpp:9
static struct Json::DummyValueAllocatorInitializer dummyValueAllocatorInitializer
ValueType
Type of the value held by a Value object.
Definition json_value.h:19
@ booleanValue
bool value
Definition json_value.h:25
@ nullValue
'null' value
Definition json_value.h:20
@ stringValue
UTF-8 string value.
Definition json_value.h:24
@ realValue
double value
Definition json_value.h:23
@ arrayValue
array value (ordered list)
Definition json_value.h:26
@ intValue
signed integer value
Definition json_value.h:21
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
@ uintValue
unsigned integer value
Definition json_value.h:22
bool operator<(Value const &, Value const &)
bool operator==(StaticString x, StaticString y)
Definition json_value.h:68
int Int
unsigned int UInt
static ValueAllocator *& valueAllocator()
static int integerCmp(Int i, UInt ui)
T push_back(T... args)
T reserve(T... args)
T length(T... args)
T swap(T... args)
T to_string(T... args)