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;
17Int const Value::minInt = Int(~(UInt(-1) / 2));
18Int const Value::maxInt = Int(UInt(-1) / 2);
19UInt const Value::maxUInt = UInt(-1);
20
22{
23public:
24 virtual ~DefaultValueAllocator() = default;
25
26 char*
27 makeMemberName(char const* memberName) override
28 {
29 return duplicateStringValue(memberName);
30 }
31
32 void
33 releaseMemberName(char* memberName) override
34 {
35 releaseStringValue(memberName);
36 }
37
38 char*
39 duplicateStringValue(char const* value, unsigned int length = unknown)
40 override
41 {
42 //@todo investigate this old optimization
43 // if ( !value || value[0] == 0 )
44 // return 0;
45
46 if (length == unknown)
47 length = value ? (unsigned int)strlen(value) : 0;
48
49 char* newString = static_cast<char*>(malloc(length + 1));
50 if (value)
51 memcpy(newString, value, length);
52 newString[length] = 0;
53 return newString;
54 }
55
56 void
57 releaseStringValue(char* value) override
58 {
59 if (value)
60 free(value);
61 }
62};
63
64static ValueAllocator*&
70
72{
74 {
75 valueAllocator(); // ensure valueAllocator() statics are initialized
76 // before main().
77 }
79
80// //////////////////////////////////////////////////////////////////
81// //////////////////////////////////////////////////////////////////
82// //////////////////////////////////////////////////////////////////
83// class Value::CZString
84// //////////////////////////////////////////////////////////////////
85// //////////////////////////////////////////////////////////////////
86// //////////////////////////////////////////////////////////////////
87
88// Notes: index_ indicates if the string was allocated when
89// a string is stored.
90
91Value::CZString::CZString(int index) : cstr_(0), index_(index)
92{
93}
94
96 : cstr_(
97 allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr)
98 , index_(allocate)
99{
100}
101
103 : cstr_(
104 other.index_ != noDuplication && other.cstr_ != 0
105 ? valueAllocator()->makeMemberName(other.cstr_)
106 : other.cstr_)
107 , index_(
108 other.cstr_
109 ? (other.index_ == noDuplication ? noDuplication : duplicate)
110 : other.index_)
111{
112}
113
115{
116 if (cstr_ && index_ == duplicate)
117 valueAllocator()->releaseMemberName(const_cast<char*>(cstr_));
118}
119
120bool
121Value::CZString::operator<(CZString const& other) const
122{
123 if (cstr_ && other.cstr_)
124 return strcmp(cstr_, other.cstr_) < 0;
125
126 return index_ < other.index_;
127}
128
129bool
131{
132 if (cstr_ && other.cstr_)
133 return strcmp(cstr_, other.cstr_) == 0;
134
135 return index_ == other.index_;
136}
137
138int
140{
141 return index_;
142}
143
144char const*
146{
147 return cstr_;
148}
149
150bool
152{
153 return index_ == noDuplication;
154}
155
156// //////////////////////////////////////////////////////////////////
157// //////////////////////////////////////////////////////////////////
158// //////////////////////////////////////////////////////////////////
159// class Value::Value
160// //////////////////////////////////////////////////////////////////
161// //////////////////////////////////////////////////////////////////
162// //////////////////////////////////////////////////////////////////
163
169{
170 switch (type)
171 {
172 case nullValue:
173 break;
174
175 case intValue:
176 case uintValue:
177 value_.int_ = 0;
178 break;
179
180 case realValue:
181 value_.real_ = 0.0;
182 break;
183
184 case stringValue:
185 value_.string_ = 0;
186 break;
187
188 case arrayValue:
189 case objectValue:
190 value_.map_ = new ObjectValues();
191 break;
192
193 case booleanValue:
194 value_.bool_ = false;
195 break;
196
197 // LCOV_EXCL_START
198 default:
199 UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
200 // LCOV_EXCL_STOP
201 }
202}
203
204Value::Value(Int value) : type_(intValue)
205{
206 value_.int_ = value;
207}
208
210{
211 value_.uint_ = value;
212}
213
214Value::Value(double value) : type_(realValue)
215{
216 value_.real_ = value;
217}
218
219Value::Value(char const* value) : type_(stringValue), allocated_(true)
220{
222}
223
224Value::Value(ripple::Number const& value) : type_(stringValue), allocated_(true)
225{
226 auto const tmp = to_string(value);
228 valueAllocator()->duplicateStringValue(tmp.c_str(), tmp.length());
229}
230
231Value::Value(std::string const& value) : type_(stringValue), allocated_(true)
232{
234 value.c_str(), (unsigned int)value.length());
235}
236
237Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
238{
239 value_.string_ = const_cast<char*>(value.c_str());
240}
241
242Value::Value(bool value) : type_(booleanValue)
243{
244 value_.bool_ = value;
245}
246
247Value::Value(Value const& other) : type_(other.type_)
248{
249 switch (type_)
250 {
251 case nullValue:
252 case intValue:
253 case uintValue:
254 case realValue:
255 case booleanValue:
256 value_ = other.value_;
257 break;
258
259 case stringValue:
260 if (other.value_.string_)
261 {
263 other.value_.string_);
264 allocated_ = true;
265 }
266 else
267 value_.string_ = 0;
268
269 break;
270
271 case arrayValue:
272 case objectValue:
273 value_.map_ = new ObjectValues(*other.value_.map_);
274 break;
275
276 // LCOV_EXCL_START
277 default:
278 UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
279 // LCOV_EXCL_STOP
280 }
281}
282
284{
285 switch (type_)
286 {
287 case nullValue:
288 case intValue:
289 case uintValue:
290 case realValue:
291 case booleanValue:
292 break;
293
294 case stringValue:
295 if (allocated_)
297
298 break;
299
300 case arrayValue:
301 case objectValue:
302 if (value_.map_)
303 delete value_.map_;
304 break;
305
306 // LCOV_EXCL_START
307 default:
308 UNREACHABLE("Json::Value::~Value : invalid type");
309 // LCOV_EXCL_STOP
310 }
311}
312
313Value&
315{
316 Value tmp(other);
317 swap(tmp);
318 return *this;
319}
320
321Value::Value(Value&& other) noexcept
322 : value_(other.value_), type_(other.type_), allocated_(other.allocated_)
323{
324 other.type_ = nullValue;
325 other.allocated_ = 0;
326}
327
328Value&
330{
331 Value tmp(std::move(other));
332 swap(tmp);
333 return *this;
334}
335
336void
337Value::swap(Value& other) noexcept
338{
339 std::swap(value_, other.value_);
340
341 ValueType temp = type_;
342 type_ = other.type_;
343 other.type_ = temp;
344
345 int temp2 = allocated_;
346 allocated_ = other.allocated_;
347 other.allocated_ = temp2;
348}
349
352{
353 return type_;
354}
355
356static int
358{
359 // All negative numbers are less than all unsigned numbers.
360 if (i < 0)
361 return -1;
362
363 // Now we can safely compare.
364 return (i < ui) ? -1 : (i == ui) ? 0 : 1;
365}
366
367bool
368operator<(Value const& x, Value const& y)
369{
370 if (auto signum = x.type_ - y.type_)
371 {
372 if (x.type_ == intValue && y.type_ == uintValue)
373 signum = integerCmp(x.value_.int_, y.value_.uint_);
374 else if (x.type_ == uintValue && y.type_ == intValue)
375 signum = -integerCmp(y.value_.int_, x.value_.uint_);
376 return signum < 0;
377 }
378
379 switch (x.type_)
380 {
381 case nullValue:
382 return false;
383
384 case intValue:
385 return x.value_.int_ < y.value_.int_;
386
387 case uintValue:
388 return x.value_.uint_ < y.value_.uint_;
389
390 case realValue:
391 return x.value_.real_ < y.value_.real_;
392
393 case booleanValue:
394 return x.value_.bool_ < y.value_.bool_;
395
396 case stringValue:
397 return (x.value_.string_ == 0 && y.value_.string_) ||
398 (y.value_.string_ && x.value_.string_ &&
399 strcmp(x.value_.string_, y.value_.string_) < 0);
400
401 case arrayValue:
402 case objectValue: {
403 if (int signum = int(x.value_.map_->size()) - y.value_.map_->size())
404 return signum < 0;
405
406 return *x.value_.map_ < *y.value_.map_;
407 }
408
409 // LCOV_EXCL_START
410 default:
411 UNREACHABLE("Json::operator<(Value, Value) : invalid type");
412 // LCOV_EXCL_STOP
413 }
414
415 return 0; // unreachable
416}
417
418bool
419operator==(Value const& x, Value const& y)
420{
421 if (x.type_ != y.type_)
422 {
423 if (x.type_ == intValue && y.type_ == uintValue)
424 return !integerCmp(x.value_.int_, y.value_.uint_);
425 if (x.type_ == uintValue && y.type_ == intValue)
426 return !integerCmp(y.value_.int_, x.value_.uint_);
427 return false;
428 }
429
430 switch (x.type_)
431 {
432 case nullValue:
433 return true;
434
435 case intValue:
436 return x.value_.int_ == y.value_.int_;
437
438 case uintValue:
439 return x.value_.uint_ == y.value_.uint_;
440
441 case realValue:
442 return x.value_.real_ == y.value_.real_;
443
444 case booleanValue:
445 return x.value_.bool_ == y.value_.bool_;
446
447 case stringValue:
448 return x.value_.string_ == y.value_.string_ ||
449 (y.value_.string_ && x.value_.string_ &&
450 !strcmp(x.value_.string_, y.value_.string_));
451
452 case arrayValue:
453 case objectValue:
454 return x.value_.map_->size() == y.value_.map_->size() &&
455 *x.value_.map_ == *y.value_.map_;
456
457 // LCOV_EXCL_START
458 default:
459 UNREACHABLE("Json::operator==(Value, Value) : invalid type");
460 // LCOV_EXCL_STOP
461 }
462
463 return 0; // unreachable
464}
465
466char const*
468{
469 XRPL_ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
470 return value_.string_;
471}
472
475{
476 switch (type_)
477 {
478 case nullValue:
479 return "";
480
481 case stringValue:
482 return value_.string_ ? value_.string_ : "";
483
484 case booleanValue:
485 return value_.bool_ ? "true" : "false";
486
487 case intValue:
488 return std::to_string(value_.int_);
489
490 case uintValue:
492
493 case realValue:
495
496 case arrayValue:
497 case objectValue:
498 JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
499
500 // LCOV_EXCL_START
501 default:
502 UNREACHABLE("Json::Value::asString : invalid type");
503 // LCOV_EXCL_STOP
504 }
505
506 return ""; // unreachable
507}
508
511{
512 switch (type_)
513 {
514 case nullValue:
515 return 0;
516
517 case intValue:
518 return value_.int_;
519
520 case uintValue:
521 JSON_ASSERT_MESSAGE(
522 value_.uint_ < (unsigned)maxInt,
523 "integer out of signed integer range");
524 return value_.uint_;
525
526 case realValue:
527 JSON_ASSERT_MESSAGE(
529 "Real out of signed integer range");
530 return Int(value_.real_);
531
532 case booleanValue:
533 return value_.bool_ ? 1 : 0;
534
535 case stringValue: {
536 char const* const str{value_.string_ ? value_.string_ : ""};
537 return beast::lexicalCastThrow<int>(str);
538 }
539
540 case arrayValue:
541 case objectValue:
542 JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
543
544 // LCOV_EXCL_START
545 default:
546 UNREACHABLE("Json::Value::asInt : invalid type");
547 // LCOV_EXCL_STOP
548 }
549
550 return 0; // unreachable;
551}
552
555{
556 switch (type_)
557 {
558 case nullValue:
559 return 0;
560
561 case intValue:
562 JSON_ASSERT_MESSAGE(
563 value_.int_ >= 0,
564 "Negative integer can not be converted to unsigned integer");
565 return value_.int_;
566
567 case uintValue:
568 return value_.uint_;
569
570 case realValue:
571 JSON_ASSERT_MESSAGE(
572 value_.real_ >= 0 && value_.real_ <= maxUInt,
573 "Real out of unsigned integer range");
574 return UInt(value_.real_);
575
576 case booleanValue:
577 return value_.bool_ ? 1 : 0;
578
579 case stringValue: {
580 char const* const str{value_.string_ ? value_.string_ : ""};
581 return beast::lexicalCastThrow<unsigned int>(str);
582 }
583
584 case arrayValue:
585 case objectValue:
586 JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
587
588 // LCOV_EXCL_START
589 default:
590 UNREACHABLE("Json::Value::asUInt : invalid type");
591 // LCOV_EXCL_STOP
592 }
593
594 return 0; // unreachable;
595}
596
597double
599{
600 switch (type_)
601 {
602 case nullValue:
603 return 0.0;
604
605 case intValue:
606 return value_.int_;
607
608 case uintValue:
609 return value_.uint_;
610
611 case realValue:
612 return value_.real_;
613
614 case booleanValue:
615 return value_.bool_ ? 1.0 : 0.0;
616
617 case stringValue:
618 case arrayValue:
619 case objectValue:
620 JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
621
622 // LCOV_EXCL_START
623 default:
624 UNREACHABLE("Json::Value::asDouble : invalid type");
625 // LCOV_EXCL_STOP
626 }
627
628 return 0; // unreachable;
629}
630
631bool
633{
634 switch (type_)
635 {
636 case nullValue:
637 return false;
638
639 case intValue:
640 case uintValue:
641 return value_.int_ != 0;
642
643 case realValue:
644 return value_.real_ != 0.0;
645
646 case booleanValue:
647 return value_.bool_;
648
649 case stringValue:
650 return value_.string_ && value_.string_[0] != 0;
651
652 case arrayValue:
653 case objectValue:
654 return value_.map_->size() != 0;
655
656 // LCOV_EXCL_START
657 default:
658 UNREACHABLE("Json::Value::asBool : invalid type");
659 // LCOV_EXCL_STOP
660 }
661
662 return false; // unreachable;
663}
664
665bool
667{
668 switch (type_)
669 {
670 case nullValue:
671 return true;
672
673 case intValue:
674 return (other == nullValue && value_.int_ == 0) ||
675 other == intValue || (other == uintValue && value_.int_ >= 0) ||
676 other == realValue || other == stringValue ||
677 other == booleanValue;
678
679 case uintValue:
680 return (other == nullValue && value_.uint_ == 0) ||
681 (other == intValue && value_.uint_ <= (unsigned)maxInt) ||
682 other == uintValue || other == realValue ||
683 other == stringValue || other == booleanValue;
684
685 case realValue:
686 return (other == nullValue && value_.real_ == 0.0) ||
687 (other == intValue && value_.real_ >= minInt &&
688 value_.real_ <= maxInt) ||
689 (other == uintValue && value_.real_ >= 0 &&
690 value_.real_ <= maxUInt &&
691 std::fabs(round(value_.real_) - value_.real_) <
693 other == realValue || other == stringValue ||
694 other == booleanValue;
695
696 case booleanValue:
697 return (other == nullValue && value_.bool_ == false) ||
698 other == intValue || other == uintValue || other == realValue ||
699 other == stringValue || other == booleanValue;
700
701 case stringValue:
702 return other == stringValue ||
703 (other == nullValue &&
704 (!value_.string_ || value_.string_[0] == 0));
705
706 case arrayValue:
707 return other == arrayValue ||
708 (other == nullValue && value_.map_->size() == 0);
709
710 case objectValue:
711 return other == objectValue ||
712 (other == nullValue && value_.map_->size() == 0);
713
714 // LCOV_EXCL_START
715 default:
716 UNREACHABLE("Json::Value::isConvertible : invalid type");
717 // LCOV_EXCL_STOP
718 }
719
720 return false; // unreachable;
721}
722
726{
727 switch (type_)
728 {
729 case nullValue:
730 case intValue:
731 case uintValue:
732 case realValue:
733 case booleanValue:
734 case stringValue:
735 return 0;
736
737 case arrayValue: // size of the array is highest index + 1
738 if (!value_.map_->empty())
739 {
740 ObjectValues::const_iterator itLast = value_.map_->end();
741 --itLast;
742 return (*itLast).first.index() + 1;
743 }
744
745 return 0;
746
747 case objectValue:
748 return Int(value_.map_->size());
749
750 // LCOV_EXCL_START
751 default:
752 UNREACHABLE("Json::Value::size : invalid type");
753 // LCOV_EXCL_STOP
754 }
755
756 return 0; // unreachable;
757}
758
759Value::operator bool() const
760{
761 if (isNull())
762 return false;
763
764 if (isString())
765 {
766 auto s = asCString();
767 return s && s[0];
768 }
769
770 return !(isArray() || isObject()) || size();
771}
772
773void
775{
776 XRPL_ASSERT(
778 "Json::Value::clear : valid type");
779
780 switch (type_)
781 {
782 case arrayValue:
783 case objectValue:
784 value_.map_->clear();
785 break;
786
787 default:
788 break;
789 }
790}
791
792Value&
794{
795 XRPL_ASSERT(
797 "Json::Value::operator[](UInt) : valid type");
798
799 if (type_ == nullValue)
800 *this = Value(arrayValue);
801
802 CZString key(index);
803 ObjectValues::iterator it = value_.map_->lower_bound(key);
804
805 if (it != value_.map_->end() && (*it).first == key)
806 return (*it).second;
807
808 ObjectValues::value_type defaultValue(key, null);
809 it = value_.map_->insert(it, defaultValue);
810 return (*it).second;
811}
812
813Value const&
815{
816 XRPL_ASSERT(
818 "Json::Value::operator[](UInt) const : valid type");
819
820 if (type_ == nullValue)
821 return null;
822
823 CZString key(index);
824 ObjectValues::const_iterator it = value_.map_->find(key);
825
826 if (it == value_.map_->end())
827 return null;
828
829 return (*it).second;
830}
831
832Value&
833Value::operator[](char const* key)
834{
835 return resolveReference(key, false);
836}
837
838Value&
839Value::resolveReference(char const* key, bool isStatic)
840{
841 XRPL_ASSERT(
843 "Json::Value::resolveReference : valid type");
844
845 if (type_ == nullValue)
846 *this = Value(objectValue);
847
848 CZString actualKey(
850 ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
851
852 if (it != value_.map_->end() && (*it).first == actualKey)
853 return (*it).second;
854
855 ObjectValues::value_type defaultValue(actualKey, null);
856 it = value_.map_->insert(it, defaultValue);
857 Value& value = (*it).second;
858 return value;
859}
860
861Value
862Value::get(UInt index, Value const& defaultValue) const
863{
864 Value const* value = &((*this)[index]);
865 return value == &null ? defaultValue : *value;
866}
867
868bool
870{
871 return index < size();
872}
873
874Value const&
875Value::operator[](char const* key) const
876{
877 XRPL_ASSERT(
879 "Json::Value::operator[](const char*) const : valid type");
880
881 if (type_ == nullValue)
882 return null;
883
884 CZString actualKey(key, CZString::noDuplication);
885 ObjectValues::const_iterator it = value_.map_->find(actualKey);
886
887 if (it == value_.map_->end())
888 return null;
889
890 return (*it).second;
891}
892
893Value&
895{
896 return (*this)[key.c_str()];
897}
898
899Value const&
901{
902 return (*this)[key.c_str()];
903}
904
905Value&
907{
908 return resolveReference(key, true);
909}
910
911Value const&
913{
914 return (*this)[key.c_str()];
915}
916
917Value&
918Value::append(Value const& value)
919{
920 return (*this)[size()] = value;
921}
922
923Value&
925{
926 return (*this)[size()] = std::move(value);
927}
928
929Value
930Value::get(char const* key, Value const& defaultValue) const
931{
932 Value const* value = &((*this)[key]);
933 return value == &null ? defaultValue : *value;
934}
935
936Value
937Value::get(std::string const& key, Value const& defaultValue) const
938{
939 return get(key.c_str(), defaultValue);
940}
941
942Value
943Value::removeMember(char const* key)
944{
945 XRPL_ASSERT(
947 "Json::Value::removeMember : valid type");
948
949 if (type_ == nullValue)
950 return null;
951
952 CZString actualKey(key, CZString::noDuplication);
953 ObjectValues::iterator it = value_.map_->find(actualKey);
954
955 if (it == value_.map_->end())
956 return null;
957
958 Value old(it->second);
959 value_.map_->erase(it);
960 return old;
961}
962
963Value
965{
966 return removeMember(key.c_str());
967}
968
969bool
970Value::isMember(char const* key) const
971{
972 if (type_ != objectValue)
973 return false;
974
975 Value const* value = &((*this)[key]);
976 return value != &null;
977}
978
979bool
981{
982 return isMember(key.c_str());
983}
984
987{
988 XRPL_ASSERT(
990 "Json::Value::getMemberNames : valid type");
991
992 if (type_ == nullValue)
993 return Value::Members();
994
995 Members members;
996 members.reserve(value_.map_->size());
997 ObjectValues::const_iterator it = value_.map_->begin();
998 ObjectValues::const_iterator itEnd = value_.map_->end();
999
1000 for (; it != itEnd; ++it)
1001 members.push_back(std::string((*it).first.c_str()));
1002
1003 return members;
1004}
1005
1006bool
1008{
1009 return type_ == nullValue;
1010}
1011
1012bool
1014{
1015 return type_ == booleanValue;
1016}
1017
1018bool
1020{
1021 return type_ == intValue;
1022}
1023
1024bool
1026{
1027 return type_ == uintValue;
1028}
1029
1030bool
1032{
1033 return type_ == intValue || type_ == uintValue || type_ == booleanValue;
1034}
1035
1036bool
1038{
1039 return type_ == realValue;
1040}
1041
1042bool
1044{
1045 return isIntegral() || isDouble();
1046}
1047
1048bool
1050{
1051 return type_ == stringValue;
1052}
1053
1054bool
1056{
1057 return type_ == arrayValue;
1058}
1059
1060bool
1062{
1063 return type_ == nullValue || type_ == arrayValue;
1064}
1065
1066bool
1068{
1069 return type_ == objectValue;
1070}
1071
1072bool
1074{
1075 return type_ == nullValue || type_ == objectValue;
1076}
1077
1080{
1081 StyledWriter writer;
1082 return writer.write(*this);
1083}
1084
1087{
1088 switch (type_)
1089 {
1090 case arrayValue:
1091 case objectValue:
1092 if (value_.map_)
1093 return const_iterator(value_.map_->begin());
1094
1095 break;
1096 default:
1097 break;
1098 }
1099
1100 return const_iterator();
1101}
1102
1105{
1106 switch (type_)
1107 {
1108 case arrayValue:
1109 case objectValue:
1110 if (value_.map_)
1111 return const_iterator(value_.map_->end());
1112
1113 break;
1114 default:
1115 break;
1116 }
1117
1118 return const_iterator();
1119}
1120
1123{
1124 switch (type_)
1125 {
1126 case arrayValue:
1127 case objectValue:
1128 if (value_.map_)
1129 return iterator(value_.map_->begin());
1130 break;
1131 default:
1132 break;
1133 }
1134
1135 return iterator();
1136}
1137
1140{
1141 switch (type_)
1142 {
1143 case arrayValue:
1144 case objectValue:
1145 if (value_.map_)
1146 return iterator(value_.map_->end());
1147 break;
1148 default:
1149 break;
1150 }
1151
1152 return iterator();
1153}
1154
1155} // 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:44
constexpr char const * c_str() const
Definition json_value.h:57
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:469
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:554
Iterator for object and array value.
Definition json_value.h:615
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:130
const_iterator begin() const
Json::UInt UInt
Definition json_value.h:137
bool isArray() const
static Int const minInt
Definition json_value.h:142
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:141
bool isDouble() const
static UInt const maxUInt
Definition json_value.h:144
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:135
ValueConstIterator const_iterator
Definition json_value.h:136
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:134
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:138
bool isValidIndex(UInt index) const
Return true if index < size().
std::string asString() const
Returns the unquoted string value.
bool isBool() const
bool isIntegral() const
bool asBool() const
ValueType type_
Definition json_value.h:420
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.
std::map< CZString, Value > ObjectValues
Definition json_value.h:178
static Int const maxInt
Definition json_value.h:143
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 ).
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:18
@ booleanValue
bool value
Definition json_value.h:24
@ nullValue
'null' value
Definition json_value.h:19
@ stringValue
UTF-8 string value.
Definition json_value.h:23
@ realValue
double value
Definition json_value.h:22
@ arrayValue
array value (ordered list)
Definition json_value.h:25
@ intValue
signed integer value
Definition json_value.h:20
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
@ uintValue
unsigned integer value
Definition json_value.h:21
bool operator<(Value const &, Value const &)
bool operator==(StaticString x, StaticString y)
Definition json_value.h:67
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)