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#include <boost/iterator/transform_iterator.hpp>
39#include <optional>
40#include <stdexcept>
41#include <type_traits>
42#include <utility>
43
44namespace ripple {
45
46class STArray;
47
48inline void
50{
51 Throw<std::runtime_error>("Field not found: " + field.getName());
52}
53
54class STObject : public STBase, public CountedObject<STObject>
55{
56 // Proxy value for a STBase derived class
57 template <class T>
58 class Proxy;
59 template <class T>
60 class ValueProxy;
61 template <class T>
62 class OptionalProxy;
63
64 struct Transform
65 {
66 explicit Transform() = default;
67
70
71 STBase const&
72 operator()(detail::STVar const& e) const;
73 };
74
76
79
80public:
81 using iterator = boost::
82 transform_iterator<Transform, STObject::list_type::const_iterator>;
83
84 virtual ~STObject() = default;
85 STObject(STObject const&) = default;
86
87 template <typename F>
88 STObject(SOTemplate const& type, SField const& name, F&& f)
89 : STObject(type, name)
90 {
91 f(*this);
92 }
93
95 operator=(STObject const&) = default;
98 operator=(STObject&& other);
99
100 STObject(const SOTemplate& type, SField const& name);
101 STObject(const SOTemplate& type, SerialIter& sit, SField const& name);
102 STObject(SerialIter& sit, SField const& name, int depth = 0);
103 STObject(SerialIter&& sit, SField const& name);
104 explicit STObject(SField const& name);
105
106 static STObject
107 makeInnerObject(SField const& name);
108
110 begin() const;
111
113 end() const;
114
115 bool
116 empty() const;
117
118 void
120
121 void
122 applyTemplate(const SOTemplate& type);
123
124 void
126
127 bool
128 isFree() const;
129
130 void
131 set(const SOTemplate&);
132
133 bool
134 set(SerialIter& u, int depth = 0);
135
137 getSType() const override;
138
139 bool
140 isEquivalent(const STBase& t) const override;
141
142 bool
143 isDefault() const override;
144
145 void
146 add(Serializer& s) const override;
147
149 getFullText() const override;
150
152 getText() const override;
153
154 // TODO(tom): options should be an enum.
156 getJson(JsonOptions options) const override;
157
158 void
160
162 getSerializer() const;
163
164 template <class... Args>
166 emplace_back(Args&&... args);
167
168 int
169 getCount() const;
170
173 bool isFlag(std::uint32_t) const;
174
176 getFlags() const;
177
178 uint256
179 getHash(HashPrefix prefix) const;
180
181 uint256
182 getSigningHash(HashPrefix prefix) const;
183
184 const STBase&
185 peekAtIndex(int offset) const;
186
187 STBase&
188 getIndex(int offset);
189
190 const STBase*
191 peekAtPIndex(int offset) const;
192
193 STBase*
194 getPIndex(int offset);
195
196 int
197 getFieldIndex(SField const& field) const;
198
199 SField const&
200 getFieldSType(int index) const;
201
202 const STBase&
203 peekAtField(SField const& field) const;
204
205 STBase&
206 getField(SField const& field);
207
208 const STBase*
209 peekAtPField(SField const& field) const;
210
211 STBase*
212 getPField(SField const& field, bool createOkay = false);
213
214 // these throw if the field type doesn't match, or return default values
215 // if the field is optional but not present
216 unsigned char
217 getFieldU8(SField const& field) const;
219 getFieldU16(SField const& field) const;
221 getFieldU32(SField const& field) const;
223 getFieldU64(SField const& field) const;
224 uint128
225 getFieldH128(SField const& field) const;
226
227 uint160
228 getFieldH160(SField const& field) const;
229 uint192
230 getFieldH192(SField const& field) const;
231 uint256
232 getFieldH256(SField const& field) const;
234 getAccountID(SField const& field) const;
235
236 Blob
237 getFieldVL(SField const& field) const;
238 STAmount const&
239 getFieldAmount(SField const& field) const;
240 STPathSet const&
241 getFieldPathSet(SField const& field) const;
242 const STVector256&
243 getFieldV256(SField const& field) const;
244 const STArray&
245 getFieldArray(SField const& field) const;
246 const STCurrency&
247 getFieldCurrency(SField const& field) const;
248 STNumber const&
249 getFieldNumber(SField const& field) const;
250
258 template <class T>
259 typename T::value_type
260 operator[](TypedField<T> const& f) const;
261
270 template <class T>
272 operator[](OptionaledField<T> const& of) const;
273
281 template <class T>
284
294 template <class T>
297
305 template <class T>
306 typename T::value_type
307 at(TypedField<T> const& f) const;
308
317 template <class T>
319 at(OptionaledField<T> const& of) const;
320
328 template <class T>
330 at(TypedField<T> const& f);
331
341 template <class T>
344
348 void
350
351 void
352 set(STBase&& v);
353
354 void
355 setFieldU8(SField const& field, unsigned char);
356 void
357 setFieldU16(SField const& field, std::uint16_t);
358 void
359 setFieldU32(SField const& field, std::uint32_t);
360 void
361 setFieldU64(SField const& field, std::uint64_t);
362 void
363 setFieldH128(SField const& field, uint128 const&);
364 void
365 setFieldH256(SField const& field, uint256 const&);
366 void
367 setFieldVL(SField const& field, Blob const&);
368 void
369 setFieldVL(SField const& field, Slice const&);
370
371 void
372 setAccountID(SField const& field, AccountID const&);
373
374 void
375 setFieldAmount(SField const& field, STAmount const&);
376 void
377 setFieldIssue(SField const& field, STIssue const&);
378 void
379 setFieldCurrency(SField const& field, STCurrency const&);
380 void
381 setFieldNumber(SField const& field, STNumber const&);
382 void
383 setFieldPathSet(SField const& field, STPathSet const&);
384 void
385 setFieldV256(SField const& field, STVector256 const& v);
386 void
387 setFieldArray(SField const& field, STArray const& v);
388
389 template <class Tag>
390 void
391 setFieldH160(SField const& field, base_uint<160, Tag> const& v);
392
393 STObject&
394 peekFieldObject(SField const& field);
395 STArray&
396 peekFieldArray(SField const& field);
397
398 bool
399 isFieldPresent(SField const& field) const;
400 STBase*
401 makeFieldPresent(SField const& field);
402 void
403 makeFieldAbsent(SField const& field);
404 bool
405 delField(SField const& field);
406 void
407 delField(int index);
408
409 bool
410 hasMatchingEntry(const STBase&);
411
412 bool
413 operator==(const STObject& o) const;
414 bool
415 operator!=(const STObject& o) const;
416
417 class FieldErr;
418
419private:
420 enum WhichFields : bool {
421 // These values are carefully chosen to do the right thing if passed
422 // to SField::shouldInclude (bool)
424 withAllFields = true
425 };
426
427 void
428 add(Serializer& s, WhichFields whichFields) const;
429
430 // Sort the entries in an STObject into the order that they will be
431 // serialized. Note: they are not sorted into pointer value order, they
432 // are sorted by SField::fieldCode.
434 getSortedFields(STObject const& objToSort, WhichFields whichFields);
435
436 // Implementation for getting (most) fields that return by value.
437 //
438 // The remove_cv and remove_reference are necessitated by the STBitString
439 // types. Their value() returns by const ref. We return those types
440 // by value.
441 template <
442 typename T,
443 typename V = typename std::remove_cv<typename std::remove_reference<
444 decltype(std::declval<T>().value())>::type>::type>
445 V
446 getFieldByValue(SField const& field) const;
447
448 // Implementations for getting (most) fields that return by const reference.
449 //
450 // If an absent optional field is deserialized we don't have anything
451 // obvious to return. So we insist on having the call provide an
452 // 'empty' value we return in that circumstance.
453 template <typename T, typename V>
454 V const&
455 getFieldByConstRef(SField const& field, V const& empty) const;
456
457 // Implementation for setting most fields with a setValue() method.
458 template <typename T, typename V>
459 void
460 setFieldUsingSetValue(SField const& field, V value);
461
462 // Implementation for setting fields using assignment
463 template <typename T>
464 void
465 setFieldUsingAssignment(SField const& field, T const& value);
466
467 // Implementation for peeking STObjects and STArrays
468 template <typename T>
469 T&
470 peekField(SField const& field);
471
472 STBase*
473 copy(std::size_t n, void* buf) const override;
474 STBase*
475 move(std::size_t n, void* buf) override;
476
477 friend class detail::STVar;
478};
479
480//------------------------------------------------------------------------------
481
482template <class T>
484{
485protected:
486 using value_type = typename T::value_type;
487
491
492 Proxy(Proxy const&) = default;
493
494 Proxy(STObject* st, TypedField<T> const* f);
495
497 value() const;
498
499 T const*
500 find() const;
501
502 template <class U>
503 void
504 assign(U&& u);
505};
506
507// Constraint += and -= ValueProxy operators
508// to value types that support arithmetic operations
509template <typename U>
510concept IsArithmetic = std::is_arithmetic_v<U> || std::is_same_v<U, STAmount>;
511
512template <class T>
514{
515private:
516 using value_type = typename T::value_type;
517
518public:
519 ValueProxy(ValueProxy const&) = default;
521 operator=(ValueProxy const&) = delete;
522
523 template <class U>
525 operator=(U&& u);
526
527 // Convenience operators for value types supporting
528 // arithmetic operations
529 template <IsArithmetic U>
531 operator+=(U const& u);
532
533 template <IsArithmetic U>
535 operator-=(U const& u);
536
537 operator value_type() const;
538
539private:
540 friend class STObject;
541
542 ValueProxy(STObject* st, TypedField<T> const* f);
543};
544
545template <class T>
547{
548private:
549 using value_type = typename T::value_type;
550
552
553public:
554 OptionalProxy(OptionalProxy const&) = default;
556 operator=(OptionalProxy const&) = delete;
557
563 explicit
564 operator bool() const noexcept;
565
573 operator*() const;
574
575 operator optional_type() const;
576
579 operator~() const;
580
581 friend bool
582 operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
583 {
584 return !lhs.engaged();
585 }
586
587 friend bool
589 {
590 return rhs == std::nullopt;
591 }
592
593 friend bool
594 operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
595 {
596 if (!lhs.engaged())
597 return !rhs;
598 if (!rhs)
599 return false;
600 return *lhs == *rhs;
601 }
602
603 friend bool
604 operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
605 {
606 return rhs == lhs;
607 }
608
609 friend bool
610 operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
611 {
612 if (lhs.engaged() != rhs.engaged())
613 return false;
614 return !lhs.engaged() || *lhs == *rhs;
615 }
616
617 friend bool
619 {
620 return !(lhs == std::nullopt);
621 }
622
623 friend bool
625 {
626 return !(rhs == std::nullopt);
627 }
628
629 friend bool
630 operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
631 {
632 return !(lhs == rhs);
633 }
634
635 friend bool
636 operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
637 {
638 return !(lhs == rhs);
639 }
640
641 friend bool
642 operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
643 {
644 return !(lhs == rhs);
645 }
646
647 // Emulate std::optional::value_or
649 value_or(value_type val) const;
650
656 operator=(optional_type const& v);
657
658 template <class U>
660 operator=(U&& u);
661
662private:
663 friend class STObject;
664
665 OptionalProxy(STObject* st, TypedField<T> const* f);
666
667 bool
668 engaged() const noexcept;
669
670 void
671 disengage();
672
674 optional_value() const;
675};
676
677class STObject::FieldErr : public std::runtime_error
678{
680};
681
682template <class T>
684{
685 if (st_->mType)
686 {
687 // STObject has associated template
688 if (!st_->peekAtPField(*f_))
689 Throw<STObject::FieldErr>(
690 "Template field error '" + this->f_->getName() + "'");
691 style_ = st_->mType->style(*f_);
692 }
693 else
694 {
696 }
697}
698
699template <class T>
700auto
702{
703 auto const t = find();
704 if (t)
705 return t->value();
706 if (style_ == soeINVALID)
707 {
708 Throw<STObject::FieldErr>("Value requested from invalid STObject.");
709 }
710 if (style_ != soeDEFAULT)
711 {
712 Throw<STObject::FieldErr>(
713 "Missing field '" + this->f_->getName() + "'");
714 }
715 return value_type{};
716}
717
718template <class T>
719inline T const*
721{
722 return dynamic_cast<T const*>(st_->peekAtPField(*f_));
723}
724
725template <class T>
726template <class U>
727void
729{
730 if (style_ == soeDEFAULT && u == value_type{})
731 {
732 st_->makeFieldAbsent(*f_);
733 return;
734 }
735 T* t;
736 if (style_ == soeINVALID)
737 t = dynamic_cast<T*>(st_->getPField(*f_, true));
738 else
739 t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
740 XRPL_ASSERT(t, "ripple::STObject::Proxy::assign : type cast succeeded");
741 *t = std::forward<U>(u);
742}
743
744//------------------------------------------------------------------------------
745
746template <class T>
747template <class U>
750{
751 this->assign(std::forward<U>(u));
752 return *this;
753}
754
755template <typename T>
756template <IsArithmetic U>
759{
760 this->assign(this->value() + u);
761 return *this;
762}
763
764template <class T>
765template <IsArithmetic U>
768{
769 this->assign(this->value() - u);
770 return *this;
771}
772
773template <class T>
775{
776 return this->value();
777}
778
779template <class T>
781 : Proxy<T>(st, f)
782{
783}
784
785//------------------------------------------------------------------------------
786
787template <class T>
789{
790 return engaged();
791}
792
793template <class T>
794auto
796{
797 return this->value();
798}
799
800template <class T>
802 T>::optional_type() const
803{
804 return optional_value();
805}
806
807template <class T>
810{
811 return optional_value();
812}
813
814template <class T>
815auto
817{
818 disengage();
819 return *this;
820}
821
822template <class T>
823auto
825{
826 if (v)
827 this->assign(std::move(*v));
828 else
829 disengage();
830 return *this;
831}
832
833template <class T>
834auto
836{
837 if (v)
838 this->assign(*v);
839 else
840 disengage();
841 return *this;
842}
843
844template <class T>
845template <class U>
848{
849 this->assign(std::forward<U>(u));
850 return *this;
851}
852
853template <class T>
855 : Proxy<T>(st, f)
856{
857}
858
859template <class T>
860bool
862{
863 return this->style_ == soeDEFAULT || this->find() != nullptr;
864}
865
866template <class T>
867void
869{
870 if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
871 Throw<STObject::FieldErr>(
872 "Template field error '" + this->f_->getName() + "'");
873 if (this->style_ == soeINVALID)
874 this->st_->delField(*this->f_);
875 else
876 this->st_->makeFieldAbsent(*this->f_);
877}
878
879template <class T>
880auto
882{
883 if (!engaged())
884 return std::nullopt;
885 return this->value();
886}
887
888template <class T>
891{
892 return engaged() ? this->value() : val;
893}
894
895//------------------------------------------------------------------------------
896
897inline STBase const&
899{
900 return e.get();
901}
902
903//------------------------------------------------------------------------------
904
905inline STObject::STObject(SerialIter&& sit, SField const& name)
906 : STObject(sit, name)
907{
908}
909
912{
913 return iterator(v_.begin());
914}
915
918{
919 return iterator(v_.end());
920}
921
922inline bool
924{
925 return v_.empty();
926}
927
928inline void
930{
931 v_.reserve(n);
932}
933
934inline bool
936{
937 return mType == nullptr;
938}
939
940inline void
942{
944}
945
946// VFALCO NOTE does this return an expensive copy of an object with a
947// dynamic buffer?
948// VFALCO TODO Remove this function and fix the few callers.
949inline Serializer
951{
952 Serializer s;
953 add(s, withAllFields);
954 return s;
955}
956
957template <class... Args>
958inline std::size_t
960{
961 v_.emplace_back(std::forward<Args>(args)...);
962 return v_.size() - 1;
963}
964
965inline int
967{
968 return v_.size();
969}
970
971inline const STBase&
972STObject::peekAtIndex(int offset) const
973{
974 return v_[offset].get();
975}
976
977inline STBase&
979{
980 return v_[offset].get();
981}
982
983inline const STBase*
984STObject::peekAtPIndex(int offset) const
985{
986 return &v_[offset].get();
987}
988
989inline STBase*
991{
992 return &v_[offset].get();
993}
994
995template <class T>
996typename T::value_type
998{
999 return at(f);
1000}
1001
1002template <class T>
1005{
1006 return at(of);
1007}
1008
1009template <class T>
1010inline auto
1012{
1013 return at(f);
1014}
1015
1016template <class T>
1017inline auto
1019{
1020 return at(of);
1021}
1022
1023template <class T>
1024typename T::value_type
1026{
1027 auto const b = peekAtPField(f);
1028 if (!b)
1029 // This is a free object (no constraints)
1030 // with no template
1031 Throw<STObject::FieldErr>("Missing field: " + f.getName());
1032
1033 if (auto const u = dynamic_cast<T const*>(b))
1034 return u->value();
1035
1036 XRPL_ASSERT(
1037 mType,
1038 "ripple::STObject::at(TypedField auto) : field template non-null");
1039 XRPL_ASSERT(
1040 b->getSType() == STI_NOTPRESENT,
1041 "ripple::STObject::at(TypedField auto) : type not present");
1042
1043 if (mType->style(f) == soeOPTIONAL)
1044 Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
1045
1046 XRPL_ASSERT(
1047 mType->style(f) == soeDEFAULT,
1048 "ripple::STObject::at(TypedField auto) : template style is default");
1049
1050 // Used to help handle the case where value_type is a const reference,
1051 // otherwise we would return the address of a temporary.
1052 static std::decay_t<typename T::value_type> const dv{};
1053 return dv;
1054}
1055
1056template <class T>
1059{
1060 auto const b = peekAtPField(*of.f);
1061 if (!b)
1062 return std::nullopt;
1063 auto const u = dynamic_cast<T const*>(b);
1064 if (!u)
1065 {
1066 XRPL_ASSERT(
1067 mType,
1068 "ripple::STObject::at(OptionaledField auto) : field template "
1069 "non-null");
1070 XRPL_ASSERT(
1071 b->getSType() == STI_NOTPRESENT,
1072 "ripple::STObject::at(OptionaledField auto) : type not present");
1073 if (mType->style(*of.f) == soeOPTIONAL)
1074 return std::nullopt;
1075 XRPL_ASSERT(
1076 mType->style(*of.f) == soeDEFAULT,
1077 "ripple::STObject::at(OptionaledField auto) : template style is "
1078 "default");
1079 return typename T::value_type{};
1080 }
1081 return u->value();
1082}
1083
1084template <class T>
1085inline auto
1087{
1088 return ValueProxy<T>(this, &f);
1089}
1090
1091template <class T>
1092inline auto
1094{
1095 return OptionalProxy<T>(this, of.f);
1096}
1097
1098template <class Tag>
1099void
1101{
1102 STBase* rf = getPField(field, true);
1103
1104 if (!rf)
1105 throwFieldNotFound(field);
1106
1107 if (rf->getSType() == STI_NOTPRESENT)
1108 rf = makeFieldPresent(field);
1109
1110 using Bits = STBitString<160>;
1111 if (auto cf = dynamic_cast<Bits*>(rf))
1112 cf->setValue(v);
1113 else
1114 Throw<std::runtime_error>("Wrong field type");
1115}
1116
1117inline bool
1119{
1120 return !(*this == o);
1121}
1122
1123template <typename T, typename V>
1124V
1126{
1127 const STBase* rf = peekAtPField(field);
1128
1129 if (!rf)
1130 throwFieldNotFound(field);
1131
1132 SerializedTypeID id = rf->getSType();
1133
1134 if (id == STI_NOTPRESENT)
1135 return V(); // optional field not present
1136
1137 const T* cf = dynamic_cast<const T*>(rf);
1138
1139 if (!cf)
1140 Throw<std::runtime_error>("Wrong field type");
1141
1142 return cf->value();
1143}
1144
1145// Implementations for getting (most) fields that return by const reference.
1146//
1147// If an absent optional field is deserialized we don't have anything
1148// obvious to return. So we insist on having the call provide an
1149// 'empty' value we return in that circumstance.
1150template <typename T, typename V>
1151V const&
1152STObject::getFieldByConstRef(SField const& field, V const& empty) const
1153{
1154 const STBase* rf = peekAtPField(field);
1155
1156 if (!rf)
1157 throwFieldNotFound(field);
1158
1159 SerializedTypeID id = rf->getSType();
1160
1161 if (id == STI_NOTPRESENT)
1162 return empty; // optional field not present
1163
1164 const T* cf = dynamic_cast<const T*>(rf);
1165
1166 if (!cf)
1167 Throw<std::runtime_error>("Wrong field type");
1168
1169 return *cf;
1170}
1171
1172// Implementation for setting most fields with a setValue() method.
1173template <typename T, typename V>
1174void
1176{
1177 static_assert(!std::is_lvalue_reference<V>::value, "");
1178
1179 STBase* rf = getPField(field, true);
1180
1181 if (!rf)
1182 throwFieldNotFound(field);
1183
1184 if (rf->getSType() == STI_NOTPRESENT)
1185 rf = makeFieldPresent(field);
1186
1187 T* cf = dynamic_cast<T*>(rf);
1188
1189 if (!cf)
1190 Throw<std::runtime_error>("Wrong field type");
1191
1192 cf->setValue(std::move(value));
1193}
1194
1195// Implementation for setting fields using assignment
1196template <typename T>
1197void
1198STObject::setFieldUsingAssignment(SField const& field, T const& value)
1199{
1200 STBase* rf = getPField(field, true);
1201
1202 if (!rf)
1203 throwFieldNotFound(field);
1204
1205 if (rf->getSType() == STI_NOTPRESENT)
1206 rf = makeFieldPresent(field);
1207
1208 T* cf = dynamic_cast<T*>(rf);
1209
1210 if (!cf)
1211 Throw<std::runtime_error>("Wrong field type");
1212
1213 (*cf) = value;
1214}
1215
1216// Implementation for peeking STObjects and STArrays
1217template <typename T>
1218T&
1220{
1221 STBase* rf = getPField(field, true);
1222
1223 if (!rf)
1224 throwFieldNotFound(field);
1225
1226 if (rf->getSType() == STI_NOTPRESENT)
1227 rf = makeFieldPresent(field);
1228
1229 T* cf = dynamic_cast<T*>(rf);
1230
1231 if (!cf)
1232 Throw<std::runtime_error>("Wrong field type");
1233
1234 return *cf;
1235}
1236
1237} // namespace ripple
1238
1239#endif
T begin(T... args)
Represents a JSON value.
Definition: json_value.h:147
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: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:124
virtual SerializedTypeID getSType() const
Definition: STBase.cpp:68
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:795
friend bool operator!=(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:630
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:594
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:604
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:610
optional_type operator~() const
Explicit conversion to std::optional.
Definition: STObject.h:809
OptionalProxy(OptionalProxy const &)=default
value_type value_or(value_type val) const
Definition: STObject.h:890
friend bool operator!=(OptionalProxy const &lhs, std::nullopt_t) noexcept
Definition: STObject.h:618
friend bool operator!=(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:624
std::enable_if_t< std::is_assignable_v< T, U >, OptionalProxy & > operator=(U &&u)
typename T::value_type value_type
Definition: STObject.h:549
OptionalProxy & operator=(OptionalProxy const &)=delete
optional_type optional_value() const
Definition: STObject.h:881
std::optional< typename std::decay< value_type >::type > optional_type
Definition: STObject.h:551
friend bool operator!=(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:636
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:588
bool engaged() const noexcept
Definition: STObject.h:861
friend bool operator!=(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:642
void assign(U &&u)
Definition: STObject.h:728
typename T::value_type value_type
Definition: STObject.h:486
T const * find() const
Definition: STObject.h:720
Proxy(Proxy const &)=default
TypedField< T > const * f_
Definition: STObject.h:490
value_type value() const
Definition: STObject.h:701
ValueProxy & operator-=(U const &u)
typename T::value_type value_type
Definition: STObject.h:516
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:642
unsigned char getFieldU8(SField const &field) const
Definition: STObject.cpp:573
uint192 getFieldH192(SField const &field) const
Definition: STObject.cpp:609
STBase * getPField(SField const &field, bool createOkay=false)
Definition: STObject.cpp:438
void setFieldIssue(SField const &field, STIssue const &)
Definition: STObject.cpp:771
SOTemplate const * mType
Definition: STObject.h:78
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:627
boost::transform_iterator< Transform, STObject::list_type::const_iterator > iterator
Definition: STObject.h:82
bool clearFlag(std::uint32_t)
Definition: STObject.cpp:489
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:621
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition: STObject.cpp:877
T & peekField(SField const &field)
Definition: STObject.h:1219
uint160 getFieldH160(SField const &field) const
Definition: STObject.cpp:603
void setFieldCurrency(SField const &field, STCurrency const &)
Definition: STObject.cpp:765
const STArray & getFieldArray(SField const &field) const
Definition: STObject.cpp:656
void setFieldArray(SField const &field, STArray const &v)
Definition: STObject.cpp:789
const STBase * peekAtPField(SField const &field) const
Definition: STObject.cpp:427
void setFieldPathSet(SField const &field, STPathSet const &)
Definition: STObject.cpp:783
iterator end() const
Definition: STObject.h:917
SField const & getFieldSType(int index) const
Definition: STObject.cpp:421
STObject(STObject const &)=default
bool isEquivalent(const STBase &t) const override
Definition: STObject.cpp:330
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:1025
bool isFlag(std::uint32_t) const
Definition: STObject.cpp:501
std::uint16_t getFieldU16(SField const &field) const
Definition: STObject.cpp:579
virtual ~STObject()=default
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:729
void setFieldNumber(SField const &field, STNumber const &)
Definition: STObject.cpp:777
bool setFlag(std::uint32_t)
Definition: STObject.cpp:477
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:585
const STVector256 & getFieldV256(SField const &field) const
Definition: STObject.cpp:649
STBase * copy(std::size_t n, void *buf) const override
Definition: STObject.cpp:87
void makeFieldAbsent(SField const &field)
Definition: STObject.cpp:540
const STBase & peekAtIndex(int offset) const
Definition: STObject.h:972
STObject & peekFieldObject(SField const &field)
Definition: STObject.cpp:465
int getCount() const
Definition: STObject.h:966
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:705
const STBase * peekAtPIndex(int offset) const
Definition: STObject.h:984
Serializer getSerializer() const
Definition: STObject.h:950
std::uint64_t getFieldU64(SField const &field) const
Definition: STObject.cpp:591
STBase * makeFieldPresent(SField const &field)
Definition: STObject.cpp:518
void setFieldU8(SField const &field, unsigned char)
Definition: STObject.cpp:699
bool operator==(const STObject &o) const
Definition: STObject.cpp:808
void add(Serializer &s) const override
Definition: STObject.cpp:111
STObject(SOTemplate const &type, SField const &name, F &&f)
Definition: STObject.h:88
void setFieldAmount(SField const &field, STAmount const &)
Definition: STObject.cpp:759
bool delField(SField const &field)
Definition: STObject.cpp:555
bool hasMatchingEntry(const STBase &)
Definition: STObject.cpp:269
STBase & getField(SField const &field)
Definition: STObject.cpp:410
V const & getFieldByConstRef(SField const &field, V const &empty) const
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:635
uint256 getSigningHash(HashPrefix prefix) const
Definition: STObject.cpp:374
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:997
uint256 getHash(HashPrefix prefix) const
Definition: STObject.cpp:365
void set(const SOTemplate &)
Definition: STObject.cpp:126
int getFieldIndex(SField const &field) const
Definition: STObject.cpp:383
STBase & getIndex(int offset)
Definition: STObject.h:978
ValueProxy< T > operator[](TypedField< T > const &f)
Get a modifiable field value.
bool isFree() const
Definition: STObject.h:935
void setFieldUsingAssignment(SField const &field, T const &value)
Definition: STObject.h:1198
list_type v_
Definition: STObject.h:77
bool empty() const
Definition: STObject.h:923
SerializedTypeID getSType() const override
Definition: STObject.cpp:99
std::string getFullText() const override
Definition: STObject.cpp:280
std::string getText() const override
Definition: STObject.cpp:311
iterator begin() const
Definition: STObject.h:911
const STBase & peekAtField(SField const &field) const
Definition: STObject.cpp:399
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:454
static STObject makeInnerObject(SField const &name)
Definition: STObject.cpp:65
const STCurrency & getFieldCurrency(SField const &field) const
Definition: STObject.cpp:663
void setAccountID(SField const &field, AccountID const &)
Definition: STObject.cpp:741
uint128 getFieldH128(SField const &field) const
Definition: STObject.cpp:597
void applyTemplateFromSField(SField const &)
Definition: STObject.cpp:196
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:735
void setFieldUsingSetValue(SField const &field, V value)
Definition: STObject.h:1175
void setFieldH128(SField const &field, uint128 const &)
Definition: STObject.cpp:723
void setFieldU64(SField const &field, std::uint64_t)
Definition: STObject.cpp:717
bool operator!=(const STObject &o) const
Definition: STObject.h:1118
Json::Value getJson(JsonOptions options) const override
Definition: STObject.cpp:795
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:711
V getFieldByValue(SField const &field) const
STBase * move(std::size_t n, void *buf) override
Definition: STObject.cpp:93
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:959
STBase * getPIndex(int offset)
Definition: STObject.h:990
void applyTemplate(const SOTemplate &type)
Definition: STObject.cpp:142
STArray & peekFieldArray(SField const &field)
Definition: STObject.cpp:471
STNumber const & getFieldNumber(SField const &field) const
Definition: STObject.cpp:670
void reserve(std::size_t n)
Definition: STObject.h:929
STObject & operator=(STObject const &)=default
void addWithoutSigningFields(Serializer &s) const
Definition: STObject.h:941
void setFieldVL(SField const &field, Blob const &)
Definition: STObject.cpp:747
std::uint32_t getFlags() const
Definition: STObject.cpp:507
uint256 getFieldH256(SField const &field) const
Definition: STObject.cpp:615
void setFieldH160(SField const &field, base_uint< 160, Tag > const &v)
Definition: STObject.h:1100
bool isDefault() const override
Definition: STObject.cpp:105
An immutable linear range of bytes.
Definition: Slice.h:45
STBase & get()
Definition: STVar.h:97
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:54
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:49
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:36
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:898
A field with a type known at compile time.
Definition: SField.h:315