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/HashPrefix.h>
29#include <xrpl/protocol/SOTemplate.h>
30#include <xrpl/protocol/STAmount.h>
31#include <xrpl/protocol/STBase.h>
32#include <xrpl/protocol/STCurrency.h>
33#include <xrpl/protocol/STIssue.h>
34#include <xrpl/protocol/STPathSet.h>
35#include <xrpl/protocol/STVector256.h>
36#include <xrpl/protocol/Units.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(SOTemplate const& type, SField const& name);
103 STObject(SOTemplate const& 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(SOTemplate const& type);
125
126 void
128
129 bool
130 isFree() const;
131
132 void
133 set(SOTemplate const&);
134
135 bool
136 set(SerialIter& u, int depth = 0);
137
139 getSType() const override;
140
141 bool
142 isEquivalent(STBase const& 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
159 void
161
163 getSerializer() const;
164
165 template <class... Args>
167 emplace_back(Args&&... args);
168
169 int
170 getCount() const;
171
174 bool isFlag(std::uint32_t) const;
175
177 getFlags() const;
178
179 uint256
180 getHash(HashPrefix prefix) const;
181
182 uint256
183 getSigningHash(HashPrefix prefix) const;
184
185 STBase const&
186 peekAtIndex(int offset) const;
187
188 STBase&
189 getIndex(int offset);
190
191 STBase const*
192 peekAtPIndex(int offset) const;
193
194 STBase*
195 getPIndex(int offset);
196
197 int
198 getFieldIndex(SField const& field) const;
199
200 SField const&
201 getFieldSType(int index) const;
202
203 STBase const&
204 peekAtField(SField const& field) const;
205
206 STBase&
207 getField(SField const& field);
208
209 STBase const*
210 peekAtPField(SField const& field) const;
211
212 STBase*
213 getPField(SField const& field, bool createOkay = false);
214
215 // these throw if the field type doesn't match, or return default values
216 // if the field is optional but not present
217 unsigned char
218 getFieldU8(SField const& field) const;
220 getFieldU16(SField const& field) const;
222 getFieldU32(SField const& field) const;
224 getFieldU64(SField const& field) const;
225 uint128
226 getFieldH128(SField const& field) const;
227
228 uint160
229 getFieldH160(SField const& field) const;
230 uint192
231 getFieldH192(SField const& field) const;
232 uint256
233 getFieldH256(SField const& field) const;
235 getFieldI32(SField const& field) const;
237 getAccountID(SField const& field) const;
238
239 Blob
240 getFieldVL(SField const& field) const;
241 STAmount const&
242 getFieldAmount(SField const& field) const;
243 STPathSet const&
244 getFieldPathSet(SField const& field) const;
245 STVector256 const&
246 getFieldV256(SField const& field) const;
247 // If not found, returns an object constructed with the given field
249 getFieldObject(SField const& field) const;
250 STArray const&
251 getFieldArray(SField const& field) const;
252 STCurrency const&
253 getFieldCurrency(SField const& field) const;
254 STNumber const&
255 getFieldNumber(SField const& field) const;
256
264 template <class T>
265 typename T::value_type
266 operator[](TypedField<T> const& f) const;
267
276 template <class T>
278 operator[](OptionaledField<T> const& of) const;
279
287 template <class T>
290
300 template <class T>
303
311 template <class T>
312 typename T::value_type
313 at(TypedField<T> const& f) const;
314
323 template <class T>
325 at(OptionaledField<T> const& of) const;
326
334 template <class T>
336 at(TypedField<T> const& f);
337
347 template <class T>
350
354 void
356
357 void
358 set(STBase&& v);
359
360 void
361 setFieldU8(SField const& field, unsigned char);
362 void
363 setFieldU16(SField const& field, std::uint16_t);
364 void
365 setFieldU32(SField const& field, std::uint32_t);
366 void
367 setFieldU64(SField const& field, std::uint64_t);
368 void
369 setFieldH128(SField const& field, uint128 const&);
370 void
371 setFieldH256(SField const& field, uint256 const&);
372 void
373 setFieldI32(SField const& field, std::int32_t);
374 void
375 setFieldVL(SField const& field, Blob const&);
376 void
377 setFieldVL(SField const& field, Slice const&);
378
379 void
380 setAccountID(SField const& field, AccountID const&);
381
382 void
383 setFieldAmount(SField const& field, STAmount const&);
384 void
385 setFieldIssue(SField const& field, STIssue const&);
386 void
387 setFieldCurrency(SField const& field, STCurrency const&);
388 void
389 setFieldNumber(SField const& field, STNumber const&);
390 void
391 setFieldPathSet(SField const& field, STPathSet const&);
392 void
393 setFieldV256(SField const& field, STVector256 const& v);
394 void
395 setFieldArray(SField const& field, STArray const& v);
396 void
397 setFieldObject(SField const& field, STObject const& v);
398
399 template <class Tag>
400 void
401 setFieldH160(SField const& field, base_uint<160, Tag> const& v);
402
403 STObject&
404 peekFieldObject(SField const& field);
405 STArray&
406 peekFieldArray(SField const& field);
407
408 bool
409 isFieldPresent(SField const& field) const;
410 STBase*
411 makeFieldPresent(SField const& field);
412 void
413 makeFieldAbsent(SField const& field);
414 bool
415 delField(SField const& field);
416 void
417 delField(int index);
418
419 bool
420 hasMatchingEntry(STBase const&);
421
422 bool
423 operator==(STObject const& o) const;
424 bool
425 operator!=(STObject const& o) const;
426
427 class FieldErr;
428
429private:
430 enum WhichFields : bool {
431 // These values are carefully chosen to do the right thing if passed
432 // to SField::shouldInclude (bool)
434 withAllFields = true
435 };
436
437 void
438 add(Serializer& s, WhichFields whichFields) const;
439
440 // Sort the entries in an STObject into the order that they will be
441 // serialized. Note: they are not sorted into pointer value order, they
442 // are sorted by SField::fieldCode.
444 getSortedFields(STObject const& objToSort, WhichFields whichFields);
445
446 // Implementation for getting (most) fields that return by value.
447 //
448 // The remove_cv and remove_reference are necessitated by the STBitString
449 // types. Their value() returns by const ref. We return those types
450 // by value.
451 template <
452 typename T,
453 typename V = typename std::remove_cv<typename std::remove_reference<
454 decltype(std::declval<T>().value())>::type>::type>
455 V
456 getFieldByValue(SField const& field) const;
457
458 // Implementations for getting (most) fields that return by const reference.
459 //
460 // If an absent optional field is deserialized we don't have anything
461 // obvious to return. So we insist on having the call provide an
462 // 'empty' value we return in that circumstance.
463 template <typename T, typename V>
464 V const&
465 getFieldByConstRef(SField const& field, V const& empty) const;
466
467 // Implementation for setting most fields with a setValue() method.
468 template <typename T, typename V>
469 void
470 setFieldUsingSetValue(SField const& field, V value);
471
472 // Implementation for setting fields using assignment
473 template <typename T>
474 void
475 setFieldUsingAssignment(SField const& field, T const& value);
476
477 // Implementation for peeking STObjects and STArrays
478 template <typename T>
479 T&
480 peekField(SField const& field);
481
482 STBase*
483 copy(std::size_t n, void* buf) const override;
484 STBase*
485 move(std::size_t n, void* buf) override;
486
487 friend class detail::STVar;
488};
489
490//------------------------------------------------------------------------------
491
492template <class T>
494{
495public:
496 using value_type = typename T::value_type;
497
499 value() const;
500
502 operator*() const;
503
504 T const*
505 operator->() const;
506
507protected:
511
512 Proxy(Proxy const&) = default;
513
514 Proxy(STObject* st, TypedField<T> const* f);
515
516 T const*
517 find() const;
518
519 template <class U>
520 void
521 assign(U&& u);
522};
523
524// Constraint += and -= ValueProxy operators
525// to value types that support arithmetic operations
526template <typename U>
528
529template <class T>
531{
532private:
533 using value_type = typename T::value_type;
534
535public:
536 ValueProxy(ValueProxy const&) = default;
538 operator=(ValueProxy const&) = delete;
539
540 template <class U>
542 operator=(U&& u);
543
544 // Convenience operators for value types supporting
545 // arithmetic operations
546 template <IsArithmetic U>
548 operator+=(U const& u);
549
550 template <IsArithmetic U>
552 operator-=(U const& u);
553
554 operator value_type() const;
555
556 template <typename U>
557 friend bool
558 operator==(U const& lhs, STObject::ValueProxy<T> const& rhs)
559 {
560 return rhs.value() == lhs;
561 }
562
563private:
564 friend class STObject;
565
566 ValueProxy(STObject* st, TypedField<T> const* f);
567};
568
569template <class T>
571{
572private:
573 using value_type = typename T::value_type;
574
576
577public:
578 OptionalProxy(OptionalProxy const&) = default;
580 operator=(OptionalProxy const&) = delete;
581
587 explicit
588 operator bool() const noexcept;
589
590 operator optional_type() const;
591
594 operator~() const;
595
596 friend bool
597 operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
598 {
599 return !lhs.engaged();
600 }
601
602 friend bool
604 {
605 return rhs == std::nullopt;
606 }
607
608 friend bool
609 operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
610 {
611 if (!lhs.engaged())
612 return !rhs;
613 if (!rhs)
614 return false;
615 return *lhs == *rhs;
616 }
617
618 friend bool
619 operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
620 {
621 return rhs == lhs;
622 }
623
624 friend bool
625 operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
626 {
627 if (lhs.engaged() != rhs.engaged())
628 return false;
629 return !lhs.engaged() || *lhs == *rhs;
630 }
631
632 friend bool
634 {
635 return !(lhs == std::nullopt);
636 }
637
638 friend bool
640 {
641 return !(rhs == std::nullopt);
642 }
643
644 friend bool
645 operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
646 {
647 return !(lhs == rhs);
648 }
649
650 friend bool
651 operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
652 {
653 return !(lhs == rhs);
654 }
655
656 friend bool
657 operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
658 {
659 return !(lhs == rhs);
660 }
661
662 // Emulate std::optional::value_or
664 value_or(value_type val) const;
665
671 operator=(optional_type const& v);
672
673 template <class U>
675 operator=(U&& u);
676
677private:
678 friend class STObject;
679
680 OptionalProxy(STObject* st, TypedField<T> const* f);
681
682 bool
683 engaged() const noexcept;
684
685 void
686 disengage();
687
689 optional_value() const;
690};
691
692class STObject::FieldErr : public std::runtime_error
693{
695};
696
697template <class T>
699{
700 if (st_->mType)
701 {
702 // STObject has associated template
703 if (!st_->peekAtPField(*f_))
704 Throw<STObject::FieldErr>(
705 "Template field error '" + this->f_->getName() + "'");
706 style_ = st_->mType->style(*f_);
707 }
708 else
709 {
711 }
712}
713
714template <class T>
715auto
717{
718 auto const t = find();
719 if (t)
720 return t->value();
721 if (style_ == soeINVALID)
722 {
723 Throw<STObject::FieldErr>("Value requested from invalid STObject.");
724 }
725 if (style_ != soeDEFAULT)
726 {
727 Throw<STObject::FieldErr>(
728 "Missing field '" + this->f_->getName() + "'");
729 }
730 return value_type{};
731}
732
733template <class T>
734auto
736{
737 return this->value();
738}
739
740template <class T>
741T const*
743{
744 return this->find();
745}
746
747template <class T>
748inline T const*
750{
751 return dynamic_cast<T const*>(st_->peekAtPField(*f_));
752}
753
754template <class T>
755template <class U>
756void
758{
759 if (style_ == soeDEFAULT && u == value_type{})
760 {
761 st_->makeFieldAbsent(*f_);
762 return;
763 }
764 T* t;
765 if (style_ == soeINVALID)
766 t = dynamic_cast<T*>(st_->getPField(*f_, true));
767 else
768 t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
769 XRPL_ASSERT(t, "ripple::STObject::Proxy::assign : type cast succeeded");
770 *t = std::forward<U>(u);
771}
772
773//------------------------------------------------------------------------------
774
775template <class T>
776template <class U>
779{
780 this->assign(std::forward<U>(u));
781 return *this;
782}
783
784template <typename T>
785template <IsArithmetic U>
788{
789 this->assign(this->value() + u);
790 return *this;
791}
792
793template <class T>
794template <IsArithmetic U>
797{
798 this->assign(this->value() - u);
799 return *this;
800}
801
802template <class T>
804{
805 return this->value();
806}
807
808template <class T>
810 : Proxy<T>(st, f)
811{
812}
813
814//------------------------------------------------------------------------------
815
816template <class T>
818{
819 return engaged();
820}
821
822template <class T>
824 T>::optional_type() const
825{
826 return optional_value();
827}
828
829template <class T>
832{
833 return optional_value();
834}
835
836template <class T>
837auto
839{
840 disengage();
841 return *this;
842}
843
844template <class T>
845auto
847{
848 if (v)
849 this->assign(std::move(*v));
850 else
851 disengage();
852 return *this;
853}
854
855template <class T>
856auto
858{
859 if (v)
860 this->assign(*v);
861 else
862 disengage();
863 return *this;
864}
865
866template <class T>
867template <class U>
870{
871 this->assign(std::forward<U>(u));
872 return *this;
873}
874
875template <class T>
880
881template <class T>
882bool
884{
885 return this->style_ == soeDEFAULT || this->find() != nullptr;
886}
887
888template <class T>
889void
891{
892 if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
893 Throw<STObject::FieldErr>(
894 "Template field error '" + this->f_->getName() + "'");
895 if (this->style_ == soeINVALID)
896 this->st_->delField(*this->f_);
897 else
898 this->st_->makeFieldAbsent(*this->f_);
899}
900
901template <class T>
902auto
904{
905 if (!engaged())
906 return std::nullopt;
907 return this->value();
908}
909
910template <class T>
913{
914 return engaged() ? this->value() : val;
915}
916
917//------------------------------------------------------------------------------
918
919inline STBase const&
921{
922 return e.get();
923}
924
925//------------------------------------------------------------------------------
926
927inline STObject::STObject(SerialIter&& sit, SField const& name)
928 : STObject(sit, name)
929{
930}
931
934{
935 return iterator(v_.begin());
936}
937
940{
941 return iterator(v_.end());
942}
943
944inline bool
946{
947 return v_.empty();
948}
949
950inline void
955
956inline bool
958{
959 return mType == nullptr;
960}
961
962inline void
967
968// VFALCO NOTE does this return an expensive copy of an object with a
969// dynamic buffer?
970// VFALCO TODO Remove this function and fix the few callers.
971inline Serializer
973{
974 Serializer s;
975 add(s, withAllFields);
976 return s;
977}
978
979template <class... Args>
980inline std::size_t
982{
984 return v_.size() - 1;
985}
986
987inline int
989{
990 return v_.size();
991}
992
993inline STBase const&
994STObject::peekAtIndex(int offset) const
995{
996 return v_[offset].get();
997}
998
999inline STBase&
1001{
1002 return v_[offset].get();
1003}
1004
1005inline STBase const*
1006STObject::peekAtPIndex(int offset) const
1007{
1008 return &v_[offset].get();
1009}
1010
1011inline STBase*
1013{
1014 return &v_[offset].get();
1015}
1016
1017template <class T>
1018typename T::value_type
1020{
1021 return at(f);
1022}
1023
1024template <class T>
1027{
1028 return at(of);
1029}
1030
1031template <class T>
1032inline auto
1034{
1035 return at(f);
1036}
1037
1038template <class T>
1039inline auto
1041{
1042 return at(of);
1043}
1044
1045template <class T>
1046typename T::value_type
1048{
1049 auto const b = peekAtPField(f);
1050 if (!b)
1051 // This is a free object (no constraints)
1052 // with no template
1053 Throw<STObject::FieldErr>("Missing field: " + f.getName());
1054
1055 if (auto const u = dynamic_cast<T const*>(b))
1056 return u->value();
1057
1058 XRPL_ASSERT(
1059 mType,
1060 "ripple::STObject::at(TypedField auto) : field template non-null");
1061 XRPL_ASSERT(
1062 b->getSType() == STI_NOTPRESENT,
1063 "ripple::STObject::at(TypedField auto) : type not present");
1064
1065 if (mType->style(f) == soeOPTIONAL)
1066 Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
1067
1068 XRPL_ASSERT(
1069 mType->style(f) == soeDEFAULT,
1070 "ripple::STObject::at(TypedField auto) : template style is default");
1071
1072 // Used to help handle the case where value_type is a const reference,
1073 // otherwise we would return the address of a temporary.
1074 static std::decay_t<typename T::value_type> const dv{};
1075 return dv;
1076}
1077
1078template <class T>
1081{
1082 auto const b = peekAtPField(*of.f);
1083 if (!b)
1084 return std::nullopt;
1085 auto const u = dynamic_cast<T const*>(b);
1086 if (!u)
1087 {
1088 XRPL_ASSERT(
1089 mType,
1090 "ripple::STObject::at(OptionaledField auto) : field template "
1091 "non-null");
1092 XRPL_ASSERT(
1093 b->getSType() == STI_NOTPRESENT,
1094 "ripple::STObject::at(OptionaledField auto) : type not present");
1095 if (mType->style(*of.f) == soeOPTIONAL)
1096 return std::nullopt;
1097 XRPL_ASSERT(
1098 mType->style(*of.f) == soeDEFAULT,
1099 "ripple::STObject::at(OptionaledField auto) : template style is "
1100 "default");
1101 return typename T::value_type{};
1102 }
1103 return u->value();
1104}
1105
1106template <class T>
1107inline auto
1109{
1110 return ValueProxy<T>(this, &f);
1111}
1112
1113template <class T>
1114inline auto
1116{
1117 return OptionalProxy<T>(this, of.f);
1118}
1119
1120template <class Tag>
1121void
1123{
1124 STBase* rf = getPField(field, true);
1125
1126 if (!rf)
1127 throwFieldNotFound(field);
1128
1129 if (rf->getSType() == STI_NOTPRESENT)
1130 rf = makeFieldPresent(field);
1131
1132 using Bits = STBitString<160>;
1133 if (auto cf = dynamic_cast<Bits*>(rf))
1134 cf->setValue(v);
1135 else
1136 Throw<std::runtime_error>("Wrong field type");
1137}
1138
1139inline bool
1141{
1142 return !(*this == o);
1143}
1144
1145template <typename T, typename V>
1146V
1148{
1149 STBase const* rf = peekAtPField(field);
1150
1151 if (!rf)
1152 throwFieldNotFound(field);
1153
1154 SerializedTypeID id = rf->getSType();
1155
1156 if (id == STI_NOTPRESENT)
1157 return V(); // optional field not present
1158
1159 T const* cf = dynamic_cast<T const*>(rf);
1160
1161 if (!cf)
1162 Throw<std::runtime_error>("Wrong field type");
1163
1164 return cf->value();
1165}
1166
1167// Implementations for getting (most) fields that return by const reference.
1168//
1169// If an absent optional field is deserialized we don't have anything
1170// obvious to return. So we insist on having the call provide an
1171// 'empty' value we return in that circumstance.
1172template <typename T, typename V>
1173V const&
1174STObject::getFieldByConstRef(SField const& field, V const& empty) const
1175{
1176 STBase const* rf = peekAtPField(field);
1177
1178 if (!rf)
1179 throwFieldNotFound(field);
1180
1181 SerializedTypeID id = rf->getSType();
1182
1183 if (id == STI_NOTPRESENT)
1184 return empty; // optional field not present
1185
1186 T const* cf = dynamic_cast<T const*>(rf);
1187
1188 if (!cf)
1189 Throw<std::runtime_error>("Wrong field type");
1190
1191 return *cf;
1192}
1193
1194// Implementation for setting most fields with a setValue() method.
1195template <typename T, typename V>
1196void
1198{
1199 static_assert(!std::is_lvalue_reference<V>::value, "");
1200
1201 STBase* rf = getPField(field, true);
1202
1203 if (!rf)
1204 throwFieldNotFound(field);
1205
1206 if (rf->getSType() == STI_NOTPRESENT)
1207 rf = makeFieldPresent(field);
1208
1209 T* cf = dynamic_cast<T*>(rf);
1210
1211 if (!cf)
1212 Throw<std::runtime_error>("Wrong field type");
1213
1214 cf->setValue(std::move(value));
1215}
1216
1217// Implementation for setting fields using assignment
1218template <typename T>
1219void
1220STObject::setFieldUsingAssignment(SField const& field, T const& value)
1221{
1222 STBase* rf = getPField(field, true);
1223
1224 if (!rf)
1225 throwFieldNotFound(field);
1226
1227 if (rf->getSType() == STI_NOTPRESENT)
1228 rf = makeFieldPresent(field);
1229
1230 T* cf = dynamic_cast<T*>(rf);
1231
1232 if (!cf)
1233 Throw<std::runtime_error>("Wrong field type");
1234
1235 (*cf) = value;
1236}
1237
1238// Implementation for peeking STObjects and STArrays
1239template <typename T>
1240T&
1242{
1243 STBase* rf = getPField(field, true);
1244
1245 if (!rf)
1246 throwFieldNotFound(field);
1247
1248 if (rf->getSType() == STI_NOTPRESENT)
1249 rf = makeFieldPresent(field);
1250
1251 T* cf = dynamic_cast<T*>(rf);
1252
1253 if (!cf)
1254 Throw<std::runtime_error>("Wrong field type");
1255
1256 return *cf;
1257}
1258
1259} // namespace ripple
1260
1261#endif
T begin(T... args)
Represents a JSON value.
Definition json_value.h:149
Tracks the number of instances of an object.
Identifies fields.
Definition SField.h:146
std::string const & getName() const
Definition SField.h:211
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:113
SOEStyle style(SField const &sf) const
Definition SOTemplate.h:166
A type which can be exported to a well known binary format.
Definition STBase.h:135
virtual SerializedTypeID getSType() const
Definition STBase.cpp:75
void setValue(base_uint< Bits, Tag > const &v)
A serializable number.
Definition STNumber.h:43
friend bool operator!=(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition STObject.h:645
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition STObject.h:609
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:619
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:625
optional_type operator~() const
Explicit conversion to std::optional.
Definition STObject.h:831
OptionalProxy(OptionalProxy const &)=default
value_type value_or(value_type val) const
Definition STObject.h:912
friend bool operator!=(OptionalProxy const &lhs, std::nullopt_t) noexcept
Definition STObject.h:633
friend bool operator!=(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition STObject.h:639
std::enable_if_t< std::is_assignable_v< T, U >, OptionalProxy & > operator=(U &&u)
typename T::value_type value_type
Definition STObject.h:573
OptionalProxy & operator=(OptionalProxy const &)=delete
optional_type optional_value() const
Definition STObject.h:903
std::optional< typename std::decay< value_type >::type > optional_type
Definition STObject.h:575
friend bool operator!=(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:651
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition STObject.h:603
bool engaged() const noexcept
Definition STObject.h:883
friend bool operator!=(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:657
typename T::value_type value_type
Definition STObject.h:496
T const * find() const
Definition STObject.h:749
Proxy(Proxy const &)=default
TypedField< T > const * f_
Definition STObject.h:510
value_type value() const
Definition STObject.h:716
value_type operator*() const
Definition STObject.h:735
T const * operator->() const
Definition STObject.h:742
ValueProxy & operator-=(U const &u)
typename T::value_type value_type
Definition STObject.h:533
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
friend bool operator==(U const &lhs, STObject::ValueProxy< T > const &rhs)
Definition STObject.h:558
STPathSet const & getFieldPathSet(SField const &field) const
Definition STObject.cpp:678
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:823
bool operator!=(STObject const &o) const
Definition STObject.h:1140
SOTemplate const * mType
Definition STObject.h:80
void applyTemplate(SOTemplate const &type)
Definition STObject.cpp:172
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:663
STObject getFieldObject(SField const &field) const
Definition STObject.cpp:692
boost::transform_iterator< Transform, STObject::list_type::const_iterator > iterator
Definition STObject.h:84
bool hasMatchingEntry(STBase const &)
Definition STObject.cpp:299
bool clearFlag(std::uint32_t)
Definition STObject.cpp:519
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:657
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition STObject.cpp:935
T & peekField(SField const &field)
Definition STObject.h:1241
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:702
uint160 getFieldH160(SField const &field) const
Definition STObject.cpp:633
void setFieldCurrency(SField const &field, STCurrency const &)
Definition STObject.cpp:817
STBase const * peekAtPField(SField const &field) const
Definition STObject.cpp:457
STBase const * peekAtPIndex(int offset) const
Definition STObject.h:1006
void setFieldArray(SField const &field, STArray const &v)
Definition STObject.cpp:841
void setFieldPathSet(SField const &field, STPathSet const &)
Definition STObject.cpp:835
iterator end() const
Definition STObject.h:939
SField const & getFieldSType(int index) const
Definition STObject.cpp:451
void setFieldObject(SField const &field, STObject const &v)
Definition STObject.cpp:847
STObject(STObject const &)=default
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1047
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:775
void setFieldNumber(SField const &field, STNumber const &)
Definition STObject.cpp:829
bool setFlag(std::uint32_t)
Definition STObject.cpp:507
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:615
void setFieldI32(SField const &field, std::int32_t)
Definition STObject.cpp:781
STBase * copy(std::size_t n, void *buf) const override
Definition STObject.cpp:117
void makeFieldAbsent(SField const &field)
Definition STObject.cpp:570
STObject & peekFieldObject(SField const &field)
Definition STObject.cpp:495
int getCount() const
Definition STObject.h:988
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:751
Serializer getSerializer() const
Definition STObject.h:972
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:745
void set(SOTemplate const &)
Definition STObject.cpp:156
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:811
bool delField(SField const &field)
Definition STObject.cpp:585
STBase const & peekAtIndex(int offset) const
Definition STObject.h:994
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:671
std::int32_t getFieldI32(SField const &field) const
Definition STObject.cpp:651
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:1019
uint256 getHash(HashPrefix prefix) const
Definition STObject.cpp:395
int getFieldIndex(SField const &field) const
Definition STObject.cpp:413
STBase & getIndex(int offset)
Definition STObject.h:1000
ValueProxy< T > operator[](TypedField< T > const &f)
Get a modifiable field value.
bool isFree() const
Definition STObject.h:957
void setFieldUsingAssignment(SField const &field, T const &value)
Definition STObject.h:1220
list_type v_
Definition STObject.h:79
bool empty() const
Definition STObject.h:945
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:933
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:484
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:95
STCurrency const & getFieldCurrency(SField const &field) const
Definition STObject.cpp:709
bool operator==(STObject const &o) const
Definition STObject.cpp:866
void setAccountID(SField const &field, AccountID const &)
Definition STObject.cpp:793
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:787
void setFieldUsingSetValue(SField const &field, V value)
Definition STObject.h:1197
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STObject.cpp:853
void setFieldH128(SField const &field, uint128 const &)
Definition STObject.cpp:769
void setFieldU64(SField const &field, std::uint64_t)
Definition STObject.cpp:763
bool isEquivalent(STBase const &t) const override
Definition STObject.cpp:360
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:757
STBase const & peekAtField(SField const &field) const
Definition STObject.cpp:429
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:981
STBase * getPIndex(int offset)
Definition STObject.h:1012
STArray & peekFieldArray(SField const &field)
Definition STObject.cpp:501
STNumber const & getFieldNumber(SField const &field) const
Definition STObject.cpp:716
void reserve(std::size_t n)
Definition STObject.h:951
STObject & operator=(STObject const &)=default
void addWithoutSigningFields(Serializer &s) const
Definition STObject.h:963
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:799
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:1122
STVector256 const & getFieldV256(SField const &field) const
Definition STObject.cpp:685
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)
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
SerializedTypeID
Definition SField.h:110
Number operator*(Number const &x, Number const &y)
Definition Number.h:308
HashPrefix
Prefix for hashing functions.
Definition HashPrefix.h:55
SOEStyle
Kind of element in each entry of an SOTemplate.
Definition SOTemplate.h:33
@ soeOPTIONAL
Definition SOTemplate.h:36
@ soeREQUIRED
Definition SOTemplate.h:35
@ soeDEFAULT
Definition SOTemplate.h:37
@ soeINVALID
Definition SOTemplate.h:34
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:37
Indicate std::optional field semantics.
Definition SField.h:330
TypedField< T > const * f
Definition SField.h:331
STBase const & operator()(detail::STVar const &e) const
Definition STObject.h:920
A field with a type known at compile time.
Definition SField.h:320