rippled
Loading...
Searching...
No Matches
STObject.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
21#define RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
22
23#include <xrpl/basics/CountedObject.h>
24#include <xrpl/basics/Slice.h>
25#include <xrpl/basics/chrono.h>
26#include <xrpl/basics/contract.h>
27#include <xrpl/beast/utility/instrumentation.h>
28#include <xrpl/protocol/FeeUnits.h>
29#include <xrpl/protocol/HashPrefix.h>
30#include <xrpl/protocol/SOTemplate.h>
31#include <xrpl/protocol/STAmount.h>
32#include <xrpl/protocol/STBase.h>
33#include <xrpl/protocol/STCurrency.h>
34#include <xrpl/protocol/STIssue.h>
35#include <xrpl/protocol/STPathSet.h>
36#include <xrpl/protocol/STVector256.h>
37#include <xrpl/protocol/detail/STVar.h>
38
39#include <boost/iterator/transform_iterator.hpp>
40
41#include <optional>
42#include <stdexcept>
43#include <type_traits>
44#include <utility>
45
46namespace ripple {
47
48class STArray;
49
50inline void
52{
53 Throw<std::runtime_error>("Field not found: " + field.getName());
54}
55
56class STObject : public STBase, public CountedObject<STObject>
57{
58 // Proxy value for a STBase derived class
59 template <class T>
60 class Proxy;
61 template <class T>
62 class ValueProxy;
63 template <class T>
64 class OptionalProxy;
65
66 struct Transform
67 {
68 explicit Transform() = default;
69
72
73 STBase const&
74 operator()(detail::STVar const& e) const;
75 };
76
78
81
82public:
83 using iterator = boost::
84 transform_iterator<Transform, STObject::list_type::const_iterator>;
85
86 virtual ~STObject() = default;
87 STObject(STObject const&) = default;
88
89 template <typename F>
90 STObject(SOTemplate const& type, SField const& name, F&& f)
91 : STObject(type, name)
92 {
93 f(*this);
94 }
95
97 operator=(STObject const&) = default;
100 operator=(STObject&& other);
101
102 STObject(const SOTemplate& type, SField const& name);
103 STObject(const SOTemplate& type, SerialIter& sit, SField const& name);
104 STObject(SerialIter& sit, SField const& name, int depth = 0);
105 STObject(SerialIter&& sit, SField const& name);
106 explicit STObject(SField const& name);
107
108 static STObject
109 makeInnerObject(SField const& name);
110
112 begin() const;
113
115 end() const;
116
117 bool
118 empty() const;
119
120 void
122
123 void
124 applyTemplate(const SOTemplate& type);
125
126 void
128
129 bool
130 isFree() const;
131
132 void
133 set(const SOTemplate&);
134
135 bool
136 set(SerialIter& u, int depth = 0);
137
139 getSType() const override;
140
141 bool
142 isEquivalent(const STBase& t) const override;
143
144 bool
145 isDefault() const override;
146
147 void
148 add(Serializer& s) const override;
149
151 getFullText() const override;
152
154 getText() const override;
155
156 // TODO(tom): options should be an enum.
158 getJson(JsonOptions options) const override;
159
160 void
162
164 getSerializer() const;
165
166 template <class... Args>
168 emplace_back(Args&&... args);
169
170 int
171 getCount() const;
172
175 bool isFlag(std::uint32_t) const;
176
178 getFlags() const;
179
180 uint256
181 getHash(HashPrefix prefix) const;
182
183 uint256
184 getSigningHash(HashPrefix prefix) const;
185
186 const STBase&
187 peekAtIndex(int offset) const;
188
189 STBase&
190 getIndex(int offset);
191
192 const STBase*
193 peekAtPIndex(int offset) const;
194
195 STBase*
196 getPIndex(int offset);
197
198 int
199 getFieldIndex(SField const& field) const;
200
201 SField const&
202 getFieldSType(int index) const;
203
204 const STBase&
205 peekAtField(SField const& field) const;
206
207 STBase&
208 getField(SField const& field);
209
210 const STBase*
211 peekAtPField(SField const& field) const;
212
213 STBase*
214 getPField(SField const& field, bool createOkay = false);
215
216 // these throw if the field type doesn't match, or return default values
217 // if the field is optional but not present
218 unsigned char
219 getFieldU8(SField const& field) const;
221 getFieldU16(SField const& field) const;
223 getFieldU32(SField const& field) const;
225 getFieldU64(SField const& field) const;
226 uint128
227 getFieldH128(SField const& field) const;
228
229 uint160
230 getFieldH160(SField const& field) const;
231 uint192
232 getFieldH192(SField const& field) const;
233 uint256
234 getFieldH256(SField const& field) const;
236 getAccountID(SField const& field) const;
237
238 Blob
239 getFieldVL(SField const& field) const;
240 STAmount const&
241 getFieldAmount(SField const& field) const;
242 STPathSet const&
243 getFieldPathSet(SField const& field) const;
244 const STVector256&
245 getFieldV256(SField const& field) const;
246 const STArray&
247 getFieldArray(SField const& field) const;
248 const STCurrency&
249 getFieldCurrency(SField const& field) const;
250 STNumber const&
251 getFieldNumber(SField const& field) const;
252
260 template <class T>
261 typename T::value_type
262 operator[](TypedField<T> const& f) const;
263
272 template <class T>
274 operator[](OptionaledField<T> const& of) const;
275
283 template <class T>
286
296 template <class T>
299
307 template <class T>
308 typename T::value_type
309 at(TypedField<T> const& f) const;
310
319 template <class T>
321 at(OptionaledField<T> const& of) const;
322
330 template <class T>
332 at(TypedField<T> const& f);
333
343 template <class T>
346
350 void
352
353 void
354 set(STBase&& v);
355
356 void
357 setFieldU8(SField const& field, unsigned char);
358 void
359 setFieldU16(SField const& field, std::uint16_t);
360 void
361 setFieldU32(SField const& field, std::uint32_t);
362 void
363 setFieldU64(SField const& field, std::uint64_t);
364 void
365 setFieldH128(SField const& field, uint128 const&);
366 void
367 setFieldH256(SField const& field, uint256 const&);
368 void
369 setFieldVL(SField const& field, Blob const&);
370 void
371 setFieldVL(SField const& field, Slice const&);
372
373 void
374 setAccountID(SField const& field, AccountID const&);
375
376 void
377 setFieldAmount(SField const& field, STAmount const&);
378 void
379 setFieldIssue(SField const& field, STIssue const&);
380 void
381 setFieldCurrency(SField const& field, STCurrency const&);
382 void
383 setFieldNumber(SField const& field, STNumber const&);
384 void
385 setFieldPathSet(SField const& field, STPathSet const&);
386 void
387 setFieldV256(SField const& field, STVector256 const& v);
388 void
389 setFieldArray(SField const& field, STArray const& v);
390
391 template <class Tag>
392 void
393 setFieldH160(SField const& field, base_uint<160, Tag> const& v);
394
395 STObject&
396 peekFieldObject(SField const& field);
397 STArray&
398 peekFieldArray(SField const& field);
399
400 bool
401 isFieldPresent(SField const& field) const;
402 STBase*
403 makeFieldPresent(SField const& field);
404 void
405 makeFieldAbsent(SField const& field);
406 bool
407 delField(SField const& field);
408 void
409 delField(int index);
410
411 bool
412 hasMatchingEntry(const STBase&);
413
414 bool
415 operator==(const STObject& o) const;
416 bool
417 operator!=(const STObject& o) const;
418
419 class FieldErr;
420
421private:
422 enum WhichFields : bool {
423 // These values are carefully chosen to do the right thing if passed
424 // to SField::shouldInclude (bool)
426 withAllFields = true
427 };
428
429 void
430 add(Serializer& s, WhichFields whichFields) const;
431
432 // Sort the entries in an STObject into the order that they will be
433 // serialized. Note: they are not sorted into pointer value order, they
434 // are sorted by SField::fieldCode.
436 getSortedFields(STObject const& objToSort, WhichFields whichFields);
437
438 // Implementation for getting (most) fields that return by value.
439 //
440 // The remove_cv and remove_reference are necessitated by the STBitString
441 // types. Their value() returns by const ref. We return those types
442 // by value.
443 template <
444 typename T,
445 typename V = typename std::remove_cv<typename std::remove_reference<
446 decltype(std::declval<T>().value())>::type>::type>
447 V
448 getFieldByValue(SField const& field) const;
449
450 // Implementations for getting (most) fields that return by const reference.
451 //
452 // If an absent optional field is deserialized we don't have anything
453 // obvious to return. So we insist on having the call provide an
454 // 'empty' value we return in that circumstance.
455 template <typename T, typename V>
456 V const&
457 getFieldByConstRef(SField const& field, V const& empty) const;
458
459 // Implementation for setting most fields with a setValue() method.
460 template <typename T, typename V>
461 void
462 setFieldUsingSetValue(SField const& field, V value);
463
464 // Implementation for setting fields using assignment
465 template <typename T>
466 void
467 setFieldUsingAssignment(SField const& field, T const& value);
468
469 // Implementation for peeking STObjects and STArrays
470 template <typename T>
471 T&
472 peekField(SField const& field);
473
474 STBase*
475 copy(std::size_t n, void* buf) const override;
476 STBase*
477 move(std::size_t n, void* buf) override;
478
479 friend class detail::STVar;
480};
481
482//------------------------------------------------------------------------------
483
484template <class T>
486{
487protected:
488 using value_type = typename T::value_type;
489
493
494 Proxy(Proxy const&) = default;
495
496 Proxy(STObject* st, TypedField<T> const* f);
497
499 value() const;
500
501 T const*
502 find() const;
503
504 template <class U>
505 void
506 assign(U&& u);
507};
508
509// Constraint += and -= ValueProxy operators
510// to value types that support arithmetic operations
511template <typename U>
512concept IsArithmetic = std::is_arithmetic_v<U> || std::is_same_v<U, STAmount>;
513
514template <class T>
516{
517private:
518 using value_type = typename T::value_type;
519
520public:
521 ValueProxy(ValueProxy const&) = default;
523 operator=(ValueProxy const&) = delete;
524
525 template <class U>
527 operator=(U&& u);
528
529 // Convenience operators for value types supporting
530 // arithmetic operations
531 template <IsArithmetic U>
533 operator+=(U const& u);
534
535 template <IsArithmetic U>
537 operator-=(U const& u);
538
539 operator value_type() const;
540
541private:
542 friend class STObject;
543
544 ValueProxy(STObject* st, TypedField<T> const* f);
545};
546
547template <class T>
549{
550private:
551 using value_type = typename T::value_type;
552
554
555public:
556 OptionalProxy(OptionalProxy const&) = default;
558 operator=(OptionalProxy const&) = delete;
559
565 explicit
566 operator bool() const noexcept;
567
575 operator*() const;
576
577 operator optional_type() const;
578
581 operator~() const;
582
583 friend bool
584 operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
585 {
586 return !lhs.engaged();
587 }
588
589 friend bool
591 {
592 return rhs == std::nullopt;
593 }
594
595 friend bool
596 operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
597 {
598 if (!lhs.engaged())
599 return !rhs;
600 if (!rhs)
601 return false;
602 return *lhs == *rhs;
603 }
604
605 friend bool
606 operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
607 {
608 return rhs == lhs;
609 }
610
611 friend bool
612 operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
613 {
614 if (lhs.engaged() != rhs.engaged())
615 return false;
616 return !lhs.engaged() || *lhs == *rhs;
617 }
618
619 friend bool
621 {
622 return !(lhs == std::nullopt);
623 }
624
625 friend bool
627 {
628 return !(rhs == std::nullopt);
629 }
630
631 friend bool
632 operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
633 {
634 return !(lhs == rhs);
635 }
636
637 friend bool
638 operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
639 {
640 return !(lhs == rhs);
641 }
642
643 friend bool
644 operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
645 {
646 return !(lhs == rhs);
647 }
648
649 // Emulate std::optional::value_or
651 value_or(value_type val) const;
652
658 operator=(optional_type const& v);
659
660 template <class U>
662 operator=(U&& u);
663
664private:
665 friend class STObject;
666
667 OptionalProxy(STObject* st, TypedField<T> const* f);
668
669 bool
670 engaged() const noexcept;
671
672 void
673 disengage();
674
676 optional_value() const;
677};
678
679class STObject::FieldErr : public std::runtime_error
680{
682};
683
684template <class T>
686{
687 if (st_->mType)
688 {
689 // STObject has associated template
690 if (!st_->peekAtPField(*f_))
691 Throw<STObject::FieldErr>(
692 "Template field error '" + this->f_->getName() + "'");
693 style_ = st_->mType->style(*f_);
694 }
695 else
696 {
698 }
699}
700
701template <class T>
702auto
704{
705 auto const t = find();
706 if (t)
707 return t->value();
708 if (style_ == soeINVALID)
709 {
710 Throw<STObject::FieldErr>("Value requested from invalid STObject.");
711 }
712 if (style_ != soeDEFAULT)
713 {
714 Throw<STObject::FieldErr>(
715 "Missing field '" + this->f_->getName() + "'");
716 }
717 return value_type{};
718}
719
720template <class T>
721inline T const*
723{
724 return dynamic_cast<T const*>(st_->peekAtPField(*f_));
725}
726
727template <class T>
728template <class U>
729void
731{
732 if (style_ == soeDEFAULT && u == value_type{})
733 {
734 st_->makeFieldAbsent(*f_);
735 return;
736 }
737 T* t;
738 if (style_ == soeINVALID)
739 t = dynamic_cast<T*>(st_->getPField(*f_, true));
740 else
741 t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
742 XRPL_ASSERT(t, "ripple::STObject::Proxy::assign : type cast succeeded");
743 *t = std::forward<U>(u);
744}
745
746//------------------------------------------------------------------------------
747
748template <class T>
749template <class U>
752{
753 this->assign(std::forward<U>(u));
754 return *this;
755}
756
757template <typename T>
758template <IsArithmetic U>
761{
762 this->assign(this->value() + u);
763 return *this;
764}
765
766template <class T>
767template <IsArithmetic U>
770{
771 this->assign(this->value() - u);
772 return *this;
773}
774
775template <class T>
777{
778 return this->value();
779}
780
781template <class T>
783 : Proxy<T>(st, f)
784{
785}
786
787//------------------------------------------------------------------------------
788
789template <class T>
791{
792 return engaged();
793}
794
795template <class T>
796auto
798{
799 return this->value();
800}
801
802template <class T>
804 T>::optional_type() const
805{
806 return optional_value();
807}
808
809template <class T>
812{
813 return optional_value();
814}
815
816template <class T>
817auto
819{
820 disengage();
821 return *this;
822}
823
824template <class T>
825auto
827{
828 if (v)
829 this->assign(std::move(*v));
830 else
831 disengage();
832 return *this;
833}
834
835template <class T>
836auto
838{
839 if (v)
840 this->assign(*v);
841 else
842 disengage();
843 return *this;
844}
845
846template <class T>
847template <class U>
850{
851 this->assign(std::forward<U>(u));
852 return *this;
853}
854
855template <class T>
857 : Proxy<T>(st, f)
858{
859}
860
861template <class T>
862bool
864{
865 return this->style_ == soeDEFAULT || this->find() != nullptr;
866}
867
868template <class T>
869void
871{
872 if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
873 Throw<STObject::FieldErr>(
874 "Template field error '" + this->f_->getName() + "'");
875 if (this->style_ == soeINVALID)
876 this->st_->delField(*this->f_);
877 else
878 this->st_->makeFieldAbsent(*this->f_);
879}
880
881template <class T>
882auto
884{
885 if (!engaged())
886 return std::nullopt;
887 return this->value();
888}
889
890template <class T>
893{
894 return engaged() ? this->value() : val;
895}
896
897//------------------------------------------------------------------------------
898
899inline STBase const&
901{
902 return e.get();
903}
904
905//------------------------------------------------------------------------------
906
907inline STObject::STObject(SerialIter&& sit, SField const& name)
908 : STObject(sit, name)
909{
910}
911
914{
915 return iterator(v_.begin());
916}
917
920{
921 return iterator(v_.end());
922}
923
924inline bool
926{
927 return v_.empty();
928}
929
930inline void
932{
933 v_.reserve(n);
934}
935
936inline bool
938{
939 return mType == nullptr;
940}
941
942inline void
944{
946}
947
948// VFALCO NOTE does this return an expensive copy of an object with a
949// dynamic buffer?
950// VFALCO TODO Remove this function and fix the few callers.
951inline Serializer
953{
954 Serializer s;
955 add(s, withAllFields);
956 return s;
957}
958
959template <class... Args>
960inline std::size_t
962{
963 v_.emplace_back(std::forward<Args>(args)...);
964 return v_.size() - 1;
965}
966
967inline int
969{
970 return v_.size();
971}
972
973inline const STBase&
974STObject::peekAtIndex(int offset) const
975{
976 return v_[offset].get();
977}
978
979inline STBase&
981{
982 return v_[offset].get();
983}
984
985inline const STBase*
986STObject::peekAtPIndex(int offset) const
987{
988 return &v_[offset].get();
989}
990
991inline STBase*
993{
994 return &v_[offset].get();
995}
996
997template <class T>
998typename T::value_type
1000{
1001 return at(f);
1002}
1003
1004template <class T>
1007{
1008 return at(of);
1009}
1010
1011template <class T>
1012inline auto
1014{
1015 return at(f);
1016}
1017
1018template <class T>
1019inline auto
1021{
1022 return at(of);
1023}
1024
1025template <class T>
1026typename T::value_type
1028{
1029 auto const b = peekAtPField(f);
1030 if (!b)
1031 // This is a free object (no constraints)
1032 // with no template
1033 Throw<STObject::FieldErr>("Missing field: " + f.getName());
1034
1035 if (auto const u = dynamic_cast<T const*>(b))
1036 return u->value();
1037
1038 XRPL_ASSERT(
1039 mType,
1040 "ripple::STObject::at(TypedField auto) : field template non-null");
1041 XRPL_ASSERT(
1042 b->getSType() == STI_NOTPRESENT,
1043 "ripple::STObject::at(TypedField auto) : type not present");
1044
1045 if (mType->style(f) == soeOPTIONAL)
1046 Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
1047
1048 XRPL_ASSERT(
1049 mType->style(f) == soeDEFAULT,
1050 "ripple::STObject::at(TypedField auto) : template style is default");
1051
1052 // Used to help handle the case where value_type is a const reference,
1053 // otherwise we would return the address of a temporary.
1054 static std::decay_t<typename T::value_type> const dv{};
1055 return dv;
1056}
1057
1058template <class T>
1061{
1062 auto const b = peekAtPField(*of.f);
1063 if (!b)
1064 return std::nullopt;
1065 auto const u = dynamic_cast<T const*>(b);
1066 if (!u)
1067 {
1068 XRPL_ASSERT(
1069 mType,
1070 "ripple::STObject::at(OptionaledField auto) : field template "
1071 "non-null");
1072 XRPL_ASSERT(
1073 b->getSType() == STI_NOTPRESENT,
1074 "ripple::STObject::at(OptionaledField auto) : type not present");
1075 if (mType->style(*of.f) == soeOPTIONAL)
1076 return std::nullopt;
1077 XRPL_ASSERT(
1078 mType->style(*of.f) == soeDEFAULT,
1079 "ripple::STObject::at(OptionaledField auto) : template style is "
1080 "default");
1081 return typename T::value_type{};
1082 }
1083 return u->value();
1084}
1085
1086template <class T>
1087inline auto
1089{
1090 return ValueProxy<T>(this, &f);
1091}
1092
1093template <class T>
1094inline auto
1096{
1097 return OptionalProxy<T>(this, of.f);
1098}
1099
1100template <class Tag>
1101void
1103{
1104 STBase* rf = getPField(field, true);
1105
1106 if (!rf)
1107 throwFieldNotFound(field);
1108
1109 if (rf->getSType() == STI_NOTPRESENT)
1110 rf = makeFieldPresent(field);
1111
1112 using Bits = STBitString<160>;
1113 if (auto cf = dynamic_cast<Bits*>(rf))
1114 cf->setValue(v);
1115 else
1116 Throw<std::runtime_error>("Wrong field type");
1117}
1118
1119inline bool
1121{
1122 return !(*this == o);
1123}
1124
1125template <typename T, typename V>
1126V
1128{
1129 const STBase* rf = peekAtPField(field);
1130
1131 if (!rf)
1132 throwFieldNotFound(field);
1133
1134 SerializedTypeID id = rf->getSType();
1135
1136 if (id == STI_NOTPRESENT)
1137 return V(); // optional field not present
1138
1139 const T* cf = dynamic_cast<const T*>(rf);
1140
1141 if (!cf)
1142 Throw<std::runtime_error>("Wrong field type");
1143
1144 return cf->value();
1145}
1146
1147// Implementations for getting (most) fields that return by const reference.
1148//
1149// If an absent optional field is deserialized we don't have anything
1150// obvious to return. So we insist on having the call provide an
1151// 'empty' value we return in that circumstance.
1152template <typename T, typename V>
1153V const&
1154STObject::getFieldByConstRef(SField const& field, V const& empty) const
1155{
1156 const STBase* rf = peekAtPField(field);
1157
1158 if (!rf)
1159 throwFieldNotFound(field);
1160
1161 SerializedTypeID id = rf->getSType();
1162
1163 if (id == STI_NOTPRESENT)
1164 return empty; // optional field not present
1165
1166 const T* cf = dynamic_cast<const T*>(rf);
1167
1168 if (!cf)
1169 Throw<std::runtime_error>("Wrong field type");
1170
1171 return *cf;
1172}
1173
1174// Implementation for setting most fields with a setValue() method.
1175template <typename T, typename V>
1176void
1178{
1179 static_assert(!std::is_lvalue_reference<V>::value, "");
1180
1181 STBase* rf = getPField(field, true);
1182
1183 if (!rf)
1184 throwFieldNotFound(field);
1185
1186 if (rf->getSType() == STI_NOTPRESENT)
1187 rf = makeFieldPresent(field);
1188
1189 T* cf = dynamic_cast<T*>(rf);
1190
1191 if (!cf)
1192 Throw<std::runtime_error>("Wrong field type");
1193
1194 cf->setValue(std::move(value));
1195}
1196
1197// Implementation for setting fields using assignment
1198template <typename T>
1199void
1200STObject::setFieldUsingAssignment(SField const& field, T const& value)
1201{
1202 STBase* rf = getPField(field, true);
1203
1204 if (!rf)
1205 throwFieldNotFound(field);
1206
1207 if (rf->getSType() == STI_NOTPRESENT)
1208 rf = makeFieldPresent(field);
1209
1210 T* cf = dynamic_cast<T*>(rf);
1211
1212 if (!cf)
1213 Throw<std::runtime_error>("Wrong field type");
1214
1215 (*cf) = value;
1216}
1217
1218// Implementation for peeking STObjects and STArrays
1219template <typename T>
1220T&
1222{
1223 STBase* rf = getPField(field, true);
1224
1225 if (!rf)
1226 throwFieldNotFound(field);
1227
1228 if (rf->getSType() == STI_NOTPRESENT)
1229 rf = makeFieldPresent(field);
1230
1231 T* cf = dynamic_cast<T*>(rf);
1232
1233 if (!cf)
1234 Throw<std::runtime_error>("Wrong field type");
1235
1236 return *cf;
1237}
1238
1239} // namespace ripple
1240
1241#endif
T begin(T... args)
Represents a JSON value.
Definition: json_value.h:148
Tracks the number of instances of an object.
Identifies fields.
Definition: SField.h:144
std::string const & getName() const
Definition: SField.h:207
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:114
SOEStyle style(SField const &sf) const
Definition: SOTemplate.h:167
A type which can be exported to a well known binary format.
Definition: STBase.h:126
virtual SerializedTypeID getSType() const
Definition: STBase.cpp:75
void setValue(base_uint< Bits, Tag > const &v)
Definition: STBitString.h:184
A serializable number.
Definition: STNumber.h:43
value_type operator*() const
Return the contained value.
Definition: STObject.h:797
friend bool operator!=(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:632
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:596
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:606
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:612
optional_type operator~() const
Explicit conversion to std::optional.
Definition: STObject.h:811
OptionalProxy(OptionalProxy const &)=default
value_type value_or(value_type val) const
Definition: STObject.h:892
friend bool operator!=(OptionalProxy const &lhs, std::nullopt_t) noexcept
Definition: STObject.h:620
friend bool operator!=(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:626
std::enable_if_t< std::is_assignable_v< T, U >, OptionalProxy & > operator=(U &&u)
typename T::value_type value_type
Definition: STObject.h:551
OptionalProxy & operator=(OptionalProxy const &)=delete
optional_type optional_value() const
Definition: STObject.h:883
std::optional< typename std::decay< value_type >::type > optional_type
Definition: STObject.h:553
friend bool operator!=(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:638
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:590
bool engaged() const noexcept
Definition: STObject.h:863
friend bool operator!=(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:644
void assign(U &&u)
Definition: STObject.h:730
typename T::value_type value_type
Definition: STObject.h:488
T const * find() const
Definition: STObject.h:722
Proxy(Proxy const &)=default
TypedField< T > const * f_
Definition: STObject.h:492
value_type value() const
Definition: STObject.h:703
ValueProxy & operator-=(U const &u)
typename T::value_type value_type
Definition: STObject.h:518
ValueProxy & operator+=(U const &u)
ValueProxy & operator=(ValueProxy const &)=delete
std::enable_if_t< std::is_assignable_v< T, U >, ValueProxy & > operator=(U &&u)
ValueProxy(ValueProxy const &)=default
STPathSet const & getFieldPathSet(SField const &field) const
Definition: STObject.cpp:672
unsigned char getFieldU8(SField const &field) const
Definition: STObject.cpp:603
uint192 getFieldH192(SField const &field) const
Definition: STObject.cpp:639
STBase * getPField(SField const &field, bool createOkay=false)
Definition: STObject.cpp:468
void setFieldIssue(SField const &field, STIssue const &)
Definition: STObject.cpp:801
SOTemplate const * mType
Definition: STObject.h:80
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:657
boost::transform_iterator< Transform, STObject::list_type::const_iterator > iterator
Definition: STObject.h:84
bool clearFlag(std::uint32_t)
Definition: STObject.cpp:519
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:651
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition: STObject.cpp:907
T & peekField(SField const &field)
Definition: STObject.h:1221
uint160 getFieldH160(SField const &field) const
Definition: STObject.cpp:633
void setFieldCurrency(SField const &field, STCurrency const &)
Definition: STObject.cpp:795
const STArray & getFieldArray(SField const &field) const
Definition: STObject.cpp:686
void setFieldArray(SField const &field, STArray const &v)
Definition: STObject.cpp:819
const STBase * peekAtPField(SField const &field) const
Definition: STObject.cpp:457
void setFieldPathSet(SField const &field, STPathSet const &)
Definition: STObject.cpp:813
iterator end() const
Definition: STObject.h:919
SField const & getFieldSType(int index) const
Definition: STObject.cpp:451
STObject(STObject const &)=default
bool isEquivalent(const STBase &t) const override
Definition: STObject.cpp:360
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:1027
bool isFlag(std::uint32_t) const
Definition: STObject.cpp:531
std::uint16_t getFieldU16(SField const &field) const
Definition: STObject.cpp:609
virtual ~STObject()=default
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:759
void setFieldNumber(SField const &field, STNumber const &)
Definition: STObject.cpp:807
bool setFlag(std::uint32_t)
Definition: STObject.cpp:507
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:615
const STVector256 & getFieldV256(SField const &field) const
Definition: STObject.cpp:679
STBase * copy(std::size_t n, void *buf) const override
Definition: STObject.cpp:117
void makeFieldAbsent(SField const &field)
Definition: STObject.cpp:570
const STBase & peekAtIndex(int offset) const
Definition: STObject.h:974
STObject & peekFieldObject(SField const &field)
Definition: STObject.cpp:495
int getCount() const
Definition: STObject.h:968
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:735
const STBase * peekAtPIndex(int offset) const
Definition: STObject.h:986
Serializer getSerializer() const
Definition: STObject.h:952
std::uint64_t getFieldU64(SField const &field) const
Definition: STObject.cpp:621
STBase * makeFieldPresent(SField const &field)
Definition: STObject.cpp:548
void setFieldU8(SField const &field, unsigned char)
Definition: STObject.cpp:729
bool operator==(const STObject &o) const
Definition: STObject.cpp:838
void add(Serializer &s) const override
Definition: STObject.cpp:141
STObject(SOTemplate const &type, SField const &name, F &&f)
Definition: STObject.h:90
void setFieldAmount(SField const &field, STAmount const &)
Definition: STObject.cpp:789
bool delField(SField const &field)
Definition: STObject.cpp:585
bool hasMatchingEntry(const STBase &)
Definition: STObject.cpp:299
STBase & getField(SField const &field)
Definition: STObject.cpp:440
V const & getFieldByConstRef(SField const &field, V const &empty) const
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:665
uint256 getSigningHash(HashPrefix prefix) const
Definition: STObject.cpp:404
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:999
uint256 getHash(HashPrefix prefix) const
Definition: STObject.cpp:395
void set(const SOTemplate &)
Definition: STObject.cpp:156
int getFieldIndex(SField const &field) const
Definition: STObject.cpp:413
STBase & getIndex(int offset)
Definition: STObject.h:980
ValueProxy< T > operator[](TypedField< T > const &f)
Get a modifiable field value.
bool isFree() const
Definition: STObject.h:937
void setFieldUsingAssignment(SField const &field, T const &value)
Definition: STObject.h:1200
list_type v_
Definition: STObject.h:79
bool empty() const
Definition: STObject.h:925
SerializedTypeID getSType() const override
Definition: STObject.cpp:129
std::string getFullText() const override
Definition: STObject.cpp:310
std::string getText() const override
Definition: STObject.cpp:341
iterator begin() const
Definition: STObject.h:913
const STBase & peekAtField(SField const &field) const
Definition: STObject.cpp:429
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:484
static STObject makeInnerObject(SField const &name)
Definition: STObject.cpp:95
const STCurrency & getFieldCurrency(SField const &field) const
Definition: STObject.cpp:693
void setAccountID(SField const &field, AccountID const &)
Definition: STObject.cpp:771
uint128 getFieldH128(SField const &field) const
Definition: STObject.cpp:627
void applyTemplateFromSField(SField const &)
Definition: STObject.cpp:226
OptionalProxy< T > at(OptionaledField< T > const &of)
Return a modifiable field value as std::optional.
ValueProxy< T > at(TypedField< T > const &f)
Get a modifiable field value.
void setFieldV256(SField const &field, STVector256 const &v)
Definition: STObject.cpp:765
void setFieldUsingSetValue(SField const &field, V value)
Definition: STObject.h:1177
void setFieldH128(SField const &field, uint128 const &)
Definition: STObject.cpp:753
void setFieldU64(SField const &field, std::uint64_t)
Definition: STObject.cpp:747
bool operator!=(const STObject &o) const
Definition: STObject.h:1120
Json::Value getJson(JsonOptions options) const override
Definition: STObject.cpp:825
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:741
V getFieldByValue(SField const &field) const
STBase * move(std::size_t n, void *buf) override
Definition: STObject.cpp:123
OptionalProxy< T > operator[](OptionaledField< T > const &of)
Return a modifiable field value as std::optional.
std::size_t emplace_back(Args &&... args)
Definition: STObject.h:961
STBase * getPIndex(int offset)
Definition: STObject.h:992
void applyTemplate(const SOTemplate &type)
Definition: STObject.cpp:172
STArray & peekFieldArray(SField const &field)
Definition: STObject.cpp:501
STNumber const & getFieldNumber(SField const &field) const
Definition: STObject.cpp:700
void reserve(std::size_t n)
Definition: STObject.h:931
STObject & operator=(STObject const &)=default
void addWithoutSigningFields(Serializer &s) const
Definition: STObject.h:943
void setFieldVL(SField const &field, Blob const &)
Definition: STObject.cpp:777
std::uint32_t getFlags() const
Definition: STObject.cpp:537
uint256 getFieldH256(SField const &field) const
Definition: STObject.cpp:645
void setFieldH160(SField const &field, base_uint< 160, Tag > const &v)
Definition: STObject.h:1102
bool isDefault() const override
Definition: STObject.cpp:135
An immutable linear range of bytes.
Definition: Slice.h:46
STBase & get()
Definition: STVar.h:94
T emplace_back(T... args)
T empty(T... args)
T end(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
SerializedTypeID
Definition: SField.h:108
HashPrefix
Prefix for hashing functions.
Definition: HashPrefix.h:55
SOEStyle
Kind of element in each entry of an SOTemplate.
Definition: SOTemplate.h:34
@ soeOPTIONAL
Definition: SOTemplate.h:37
@ soeREQUIRED
Definition: SOTemplate.h:36
@ soeDEFAULT
Definition: SOTemplate.h:38
@ soeINVALID
Definition: SOTemplate.h:35
void throwFieldNotFound(SField const &field)
Definition: STObject.h:51
STL namespace.
T reserve(T... args)
T runtime_error(T... args)
T size(T... args)
Note, should be treated as flags that can be | and &.
Definition: STBase.h:38
Indicate std::optional field semantics.
Definition: SField.h:325
TypedField< T > const * f
Definition: SField.h:326
STBase const & operator()(detail::STVar const &e) const
Definition: STObject.h:900
A field with a type known at compile time.
Definition: SField.h:315