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