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