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