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(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 getAccountID(SField const& field) const;
236
237 Blob
238 getFieldVL(SField const& field) const;
239 STAmount const&
240 getFieldAmount(SField const& field) const;
241 STPathSet const&
242 getFieldPathSet(SField const& field) const;
243 STVector256 const&
244 getFieldV256(SField const& field) const;
245 STArray const&
246 getFieldArray(SField const& field) const;
247 STCurrency const&
248 getFieldCurrency(SField const& field) const;
249 STNumber const&
250 getFieldNumber(SField const& field) const;
251
259 template <class T>
260 typename T::value_type
261 operator[](TypedField<T> const& f) const;
262
271 template <class T>
273 operator[](OptionaledField<T> const& of) const;
274
282 template <class T>
285
295 template <class T>
298
306 template <class T>
307 typename T::value_type
308 at(TypedField<T> const& f) const;
309
318 template <class T>
320 at(OptionaledField<T> const& of) const;
321
329 template <class T>
331 at(TypedField<T> const& f);
332
342 template <class T>
345
349 void
351
352 void
353 set(STBase&& v);
354
355 void
356 setFieldU8(SField const& field, unsigned char);
357 void
358 setFieldU16(SField const& field, std::uint16_t);
359 void
360 setFieldU32(SField const& field, std::uint32_t);
361 void
362 setFieldU64(SField const& field, std::uint64_t);
363 void
364 setFieldH128(SField const& field, uint128 const&);
365 void
366 setFieldH256(SField const& field, uint256 const&);
367 void
368 setFieldVL(SField const& field, Blob const&);
369 void
370 setFieldVL(SField const& field, Slice const&);
371
372 void
373 setAccountID(SField const& field, AccountID const&);
374
375 void
376 setFieldAmount(SField const& field, STAmount const&);
377 void
378 setFieldIssue(SField const& field, STIssue const&);
379 void
380 setFieldCurrency(SField const& field, STCurrency const&);
381 void
382 setFieldNumber(SField const& field, STNumber const&);
383 void
384 setFieldPathSet(SField const& field, STPathSet const&);
385 void
386 setFieldV256(SField const& field, STVector256 const& v);
387 void
388 setFieldArray(SField const& field, STArray const& v);
389
390 template <class Tag>
391 void
392 setFieldH160(SField const& field, base_uint<160, Tag> const& v);
393
394 STObject&
395 peekFieldObject(SField const& field);
396 STArray&
397 peekFieldArray(SField const& field);
398
399 bool
400 isFieldPresent(SField const& field) const;
401 STBase*
402 makeFieldPresent(SField const& field);
403 void
404 makeFieldAbsent(SField const& field);
405 bool
406 delField(SField const& field);
407 void
408 delField(int index);
409
410 bool
411 hasMatchingEntry(STBase const&);
412
413 bool
414 operator==(STObject const& o) const;
415 bool
416 operator!=(STObject const& o) const;
417
418 class FieldErr;
419
420private:
421 enum WhichFields : bool {
422 // These values are carefully chosen to do the right thing if passed
423 // to SField::shouldInclude (bool)
425 withAllFields = true
426 };
427
428 void
429 add(Serializer& s, WhichFields whichFields) const;
430
431 // Sort the entries in an STObject into the order that they will be
432 // serialized. Note: they are not sorted into pointer value order, they
433 // are sorted by SField::fieldCode.
435 getSortedFields(STObject const& objToSort, WhichFields whichFields);
436
437 // Implementation for getting (most) fields that return by value.
438 //
439 // The remove_cv and remove_reference are necessitated by the STBitString
440 // types. Their value() returns by const ref. We return those types
441 // by value.
442 template <
443 typename T,
444 typename V = typename std::remove_cv<typename std::remove_reference<
445 decltype(std::declval<T>().value())>::type>::type>
446 V
447 getFieldByValue(SField const& field) const;
448
449 // Implementations for getting (most) fields that return by const reference.
450 //
451 // If an absent optional field is deserialized we don't have anything
452 // obvious to return. So we insist on having the call provide an
453 // 'empty' value we return in that circumstance.
454 template <typename T, typename V>
455 V const&
456 getFieldByConstRef(SField const& field, V const& empty) const;
457
458 // Implementation for setting most fields with a setValue() method.
459 template <typename T, typename V>
460 void
461 setFieldUsingSetValue(SField const& field, V value);
462
463 // Implementation for setting fields using assignment
464 template <typename T>
465 void
466 setFieldUsingAssignment(SField const& field, T const& value);
467
468 // Implementation for peeking STObjects and STArrays
469 template <typename T>
470 T&
471 peekField(SField const& field);
472
473 STBase*
474 copy(std::size_t n, void* buf) const override;
475 STBase*
476 move(std::size_t n, void* buf) override;
477
478 friend class detail::STVar;
479};
480
481//------------------------------------------------------------------------------
482
483template <class T>
485{
486public:
487 using value_type = typename T::value_type;
488
490 value() const;
491
493 operator*() const;
494
495 T const*
496 operator->() const;
497
498protected:
502
503 Proxy(Proxy const&) = default;
504
505 Proxy(STObject* st, TypedField<T> const* f);
506
507 T const*
508 find() const;
509
510 template <class U>
511 void
512 assign(U&& u);
513};
514
515// Constraint += and -= ValueProxy operators
516// to value types that support arithmetic operations
517template <typename U>
518concept IsArithmetic = std::is_arithmetic_v<U> || std::is_same_v<U, STAmount>;
519
520template <class T>
522{
523private:
524 using value_type = typename T::value_type;
525
526public:
527 ValueProxy(ValueProxy const&) = default;
529 operator=(ValueProxy const&) = delete;
530
531 template <class U>
533 operator=(U&& u);
534
535 // Convenience operators for value types supporting
536 // arithmetic operations
537 template <IsArithmetic U>
539 operator+=(U const& u);
540
541 template <IsArithmetic U>
543 operator-=(U const& u);
544
545 operator value_type() const;
546
547 template <typename U>
548 friend bool
549 operator==(U const& lhs, STObject::ValueProxy<T> const& rhs)
550 {
551 return rhs.value() == lhs;
552 }
553
554private:
555 friend class STObject;
556
557 ValueProxy(STObject* st, TypedField<T> const* f);
558};
559
560template <class T>
562{
563private:
564 using value_type = typename T::value_type;
565
567
568public:
569 OptionalProxy(OptionalProxy const&) = default;
571 operator=(OptionalProxy const&) = delete;
572
578 explicit
579 operator bool() const noexcept;
580
581 operator optional_type() const;
582
585 operator~() const;
586
587 friend bool
588 operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
589 {
590 return !lhs.engaged();
591 }
592
593 friend bool
595 {
596 return rhs == std::nullopt;
597 }
598
599 friend bool
600 operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
601 {
602 if (!lhs.engaged())
603 return !rhs;
604 if (!rhs)
605 return false;
606 return *lhs == *rhs;
607 }
608
609 friend bool
610 operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
611 {
612 return rhs == lhs;
613 }
614
615 friend bool
616 operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
617 {
618 if (lhs.engaged() != rhs.engaged())
619 return false;
620 return !lhs.engaged() || *lhs == *rhs;
621 }
622
623 friend bool
625 {
626 return !(lhs == std::nullopt);
627 }
628
629 friend bool
631 {
632 return !(rhs == std::nullopt);
633 }
634
635 friend bool
636 operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
637 {
638 return !(lhs == rhs);
639 }
640
641 friend bool
642 operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
643 {
644 return !(lhs == rhs);
645 }
646
647 friend bool
648 operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
649 {
650 return !(lhs == rhs);
651 }
652
653 // Emulate std::optional::value_or
655 value_or(value_type val) const;
656
662 operator=(optional_type const& v);
663
664 template <class U>
666 operator=(U&& u);
667
668private:
669 friend class STObject;
670
671 OptionalProxy(STObject* st, TypedField<T> const* f);
672
673 bool
674 engaged() const noexcept;
675
676 void
677 disengage();
678
680 optional_value() const;
681};
682
683class STObject::FieldErr : public std::runtime_error
684{
686};
687
688template <class T>
690{
691 if (st_->mType)
692 {
693 // STObject has associated template
694 if (!st_->peekAtPField(*f_))
695 Throw<STObject::FieldErr>(
696 "Template field error '" + this->f_->getName() + "'");
697 style_ = st_->mType->style(*f_);
698 }
699 else
700 {
702 }
703}
704
705template <class T>
706auto
708{
709 auto const t = find();
710 if (t)
711 return t->value();
712 if (style_ == soeINVALID)
713 {
714 Throw<STObject::FieldErr>("Value requested from invalid STObject.");
715 }
716 if (style_ != soeDEFAULT)
717 {
718 Throw<STObject::FieldErr>(
719 "Missing field '" + this->f_->getName() + "'");
720 }
721 return value_type{};
722}
723
724template <class T>
725auto
727{
728 return this->value();
729}
730
731template <class T>
732T const*
734{
735 return this->find();
736}
737
738template <class T>
739inline T const*
741{
742 return dynamic_cast<T const*>(st_->peekAtPField(*f_));
743}
744
745template <class T>
746template <class U>
747void
749{
750 if (style_ == soeDEFAULT && u == value_type{})
751 {
752 st_->makeFieldAbsent(*f_);
753 return;
754 }
755 T* t;
756 if (style_ == soeINVALID)
757 t = dynamic_cast<T*>(st_->getPField(*f_, true));
758 else
759 t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
760 XRPL_ASSERT(t, "ripple::STObject::Proxy::assign : type cast succeeded");
761 *t = std::forward<U>(u);
762}
763
764//------------------------------------------------------------------------------
765
766template <class T>
767template <class U>
770{
771 this->assign(std::forward<U>(u));
772 return *this;
773}
774
775template <typename T>
776template <IsArithmetic U>
779{
780 this->assign(this->value() + u);
781 return *this;
782}
783
784template <class T>
785template <IsArithmetic U>
788{
789 this->assign(this->value() - u);
790 return *this;
791}
792
793template <class T>
795{
796 return this->value();
797}
798
799template <class T>
801 : Proxy<T>(st, f)
802{
803}
804
805//------------------------------------------------------------------------------
806
807template <class T>
809{
810 return engaged();
811}
812
813template <class T>
815 T>::optional_type() const
816{
817 return optional_value();
818}
819
820template <class T>
823{
824 return optional_value();
825}
826
827template <class T>
828auto
830{
831 disengage();
832 return *this;
833}
834
835template <class T>
836auto
838{
839 if (v)
840 this->assign(std::move(*v));
841 else
842 disengage();
843 return *this;
844}
845
846template <class T>
847auto
849{
850 if (v)
851 this->assign(*v);
852 else
853 disengage();
854 return *this;
855}
856
857template <class T>
858template <class U>
861{
862 this->assign(std::forward<U>(u));
863 return *this;
864}
865
866template <class T>
868 : Proxy<T>(st, f)
869{
870}
871
872template <class T>
873bool
875{
876 return this->style_ == soeDEFAULT || this->find() != nullptr;
877}
878
879template <class T>
880void
882{
883 if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
884 Throw<STObject::FieldErr>(
885 "Template field error '" + this->f_->getName() + "'");
886 if (this->style_ == soeINVALID)
887 this->st_->delField(*this->f_);
888 else
889 this->st_->makeFieldAbsent(*this->f_);
890}
891
892template <class T>
893auto
895{
896 if (!engaged())
897 return std::nullopt;
898 return this->value();
899}
900
901template <class T>
904{
905 return engaged() ? this->value() : val;
906}
907
908//------------------------------------------------------------------------------
909
910inline STBase const&
912{
913 return e.get();
914}
915
916//------------------------------------------------------------------------------
917
918inline STObject::STObject(SerialIter&& sit, SField const& name)
919 : STObject(sit, name)
920{
921}
922
925{
926 return iterator(v_.begin());
927}
928
931{
932 return iterator(v_.end());
933}
934
935inline bool
937{
938 return v_.empty();
939}
940
941inline void
943{
944 v_.reserve(n);
945}
946
947inline bool
949{
950 return mType == nullptr;
951}
952
953inline void
955{
957}
958
959// VFALCO NOTE does this return an expensive copy of an object with a
960// dynamic buffer?
961// VFALCO TODO Remove this function and fix the few callers.
962inline Serializer
964{
965 Serializer s;
966 add(s, withAllFields);
967 return s;
968}
969
970template <class... Args>
971inline std::size_t
973{
974 v_.emplace_back(std::forward<Args>(args)...);
975 return v_.size() - 1;
976}
977
978inline int
980{
981 return v_.size();
982}
983
984inline STBase const&
985STObject::peekAtIndex(int offset) const
986{
987 return v_[offset].get();
988}
989
990inline STBase&
992{
993 return v_[offset].get();
994}
995
996inline STBase const*
997STObject::peekAtPIndex(int offset) const
998{
999 return &v_[offset].get();
1000}
1001
1002inline STBase*
1004{
1005 return &v_[offset].get();
1006}
1007
1008template <class T>
1009typename T::value_type
1011{
1012 return at(f);
1013}
1014
1015template <class T>
1018{
1019 return at(of);
1020}
1021
1022template <class T>
1023inline auto
1025{
1026 return at(f);
1027}
1028
1029template <class T>
1030inline auto
1032{
1033 return at(of);
1034}
1035
1036template <class T>
1037typename T::value_type
1039{
1040 auto const b = peekAtPField(f);
1041 if (!b)
1042 // This is a free object (no constraints)
1043 // with no template
1044 Throw<STObject::FieldErr>("Missing field: " + f.getName());
1045
1046 if (auto const u = dynamic_cast<T const*>(b))
1047 return u->value();
1048
1049 XRPL_ASSERT(
1050 mType,
1051 "ripple::STObject::at(TypedField auto) : field template non-null");
1052 XRPL_ASSERT(
1053 b->getSType() == STI_NOTPRESENT,
1054 "ripple::STObject::at(TypedField auto) : type not present");
1055
1056 if (mType->style(f) == soeOPTIONAL)
1057 Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
1058
1059 XRPL_ASSERT(
1060 mType->style(f) == soeDEFAULT,
1061 "ripple::STObject::at(TypedField auto) : template style is default");
1062
1063 // Used to help handle the case where value_type is a const reference,
1064 // otherwise we would return the address of a temporary.
1065 static std::decay_t<typename T::value_type> const dv{};
1066 return dv;
1067}
1068
1069template <class T>
1072{
1073 auto const b = peekAtPField(*of.f);
1074 if (!b)
1075 return std::nullopt;
1076 auto const u = dynamic_cast<T const*>(b);
1077 if (!u)
1078 {
1079 XRPL_ASSERT(
1080 mType,
1081 "ripple::STObject::at(OptionaledField auto) : field template "
1082 "non-null");
1083 XRPL_ASSERT(
1084 b->getSType() == STI_NOTPRESENT,
1085 "ripple::STObject::at(OptionaledField auto) : type not present");
1086 if (mType->style(*of.f) == soeOPTIONAL)
1087 return std::nullopt;
1088 XRPL_ASSERT(
1089 mType->style(*of.f) == soeDEFAULT,
1090 "ripple::STObject::at(OptionaledField auto) : template style is "
1091 "default");
1092 return typename T::value_type{};
1093 }
1094 return u->value();
1095}
1096
1097template <class T>
1098inline auto
1100{
1101 return ValueProxy<T>(this, &f);
1102}
1103
1104template <class T>
1105inline auto
1107{
1108 return OptionalProxy<T>(this, of.f);
1109}
1110
1111template <class Tag>
1112void
1114{
1115 STBase* rf = getPField(field, true);
1116
1117 if (!rf)
1118 throwFieldNotFound(field);
1119
1120 if (rf->getSType() == STI_NOTPRESENT)
1121 rf = makeFieldPresent(field);
1122
1123 using Bits = STBitString<160>;
1124 if (auto cf = dynamic_cast<Bits*>(rf))
1125 cf->setValue(v);
1126 else
1127 Throw<std::runtime_error>("Wrong field type");
1128}
1129
1130inline bool
1132{
1133 return !(*this == o);
1134}
1135
1136template <typename T, typename V>
1137V
1139{
1140 STBase const* rf = peekAtPField(field);
1141
1142 if (!rf)
1143 throwFieldNotFound(field);
1144
1145 SerializedTypeID id = rf->getSType();
1146
1147 if (id == STI_NOTPRESENT)
1148 return V(); // optional field not present
1149
1150 T const* cf = dynamic_cast<T const*>(rf);
1151
1152 if (!cf)
1153 Throw<std::runtime_error>("Wrong field type");
1154
1155 return cf->value();
1156}
1157
1158// Implementations for getting (most) fields that return by const reference.
1159//
1160// If an absent optional field is deserialized we don't have anything
1161// obvious to return. So we insist on having the call provide an
1162// 'empty' value we return in that circumstance.
1163template <typename T, typename V>
1164V const&
1165STObject::getFieldByConstRef(SField const& field, V const& empty) const
1166{
1167 STBase const* rf = peekAtPField(field);
1168
1169 if (!rf)
1170 throwFieldNotFound(field);
1171
1172 SerializedTypeID id = rf->getSType();
1173
1174 if (id == STI_NOTPRESENT)
1175 return empty; // optional field not present
1176
1177 T const* cf = dynamic_cast<T const*>(rf);
1178
1179 if (!cf)
1180 Throw<std::runtime_error>("Wrong field type");
1181
1182 return *cf;
1183}
1184
1185// Implementation for setting most fields with a setValue() method.
1186template <typename T, typename V>
1187void
1189{
1190 static_assert(!std::is_lvalue_reference<V>::value, "");
1191
1192 STBase* rf = getPField(field, true);
1193
1194 if (!rf)
1195 throwFieldNotFound(field);
1196
1197 if (rf->getSType() == STI_NOTPRESENT)
1198 rf = makeFieldPresent(field);
1199
1200 T* cf = dynamic_cast<T*>(rf);
1201
1202 if (!cf)
1203 Throw<std::runtime_error>("Wrong field type");
1204
1205 cf->setValue(std::move(value));
1206}
1207
1208// Implementation for setting fields using assignment
1209template <typename T>
1210void
1211STObject::setFieldUsingAssignment(SField const& field, T const& value)
1212{
1213 STBase* rf = getPField(field, true);
1214
1215 if (!rf)
1216 throwFieldNotFound(field);
1217
1218 if (rf->getSType() == STI_NOTPRESENT)
1219 rf = makeFieldPresent(field);
1220
1221 T* cf = dynamic_cast<T*>(rf);
1222
1223 if (!cf)
1224 Throw<std::runtime_error>("Wrong field type");
1225
1226 (*cf) = value;
1227}
1228
1229// Implementation for peeking STObjects and STArrays
1230template <typename T>
1231T&
1233{
1234 STBase* rf = getPField(field, true);
1235
1236 if (!rf)
1237 throwFieldNotFound(field);
1238
1239 if (rf->getSType() == STI_NOTPRESENT)
1240 rf = makeFieldPresent(field);
1241
1242 T* cf = dynamic_cast<T*>(rf);
1243
1244 if (!cf)
1245 Throw<std::runtime_error>("Wrong field type");
1246
1247 return *cf;
1248}
1249
1250} // namespace ripple
1251
1252#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:143
std::string const & getName() const
Definition: SField.h:206
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)
Definition: STBitString.h:184
A serializable number.
Definition: STNumber.h:43
friend bool operator!=(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:636
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:600
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:610
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:616
optional_type operator~() const
Explicit conversion to std::optional.
Definition: STObject.h:822
OptionalProxy(OptionalProxy const &)=default
value_type value_or(value_type val) const
Definition: STObject.h:903
friend bool operator!=(OptionalProxy const &lhs, std::nullopt_t) noexcept
Definition: STObject.h:624
friend bool operator!=(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:630
std::enable_if_t< std::is_assignable_v< T, U >, OptionalProxy & > operator=(U &&u)
typename T::value_type value_type
Definition: STObject.h:564
OptionalProxy & operator=(OptionalProxy const &)=delete
optional_type optional_value() const
Definition: STObject.h:894
std::optional< typename std::decay< value_type >::type > optional_type
Definition: STObject.h:566
friend bool operator!=(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:642
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:594
bool engaged() const noexcept
Definition: STObject.h:874
friend bool operator!=(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:648
void assign(U &&u)
Definition: STObject.h:748
typename T::value_type value_type
Definition: STObject.h:487
T const * find() const
Definition: STObject.h:740
Proxy(Proxy const &)=default
TypedField< T > const * f_
Definition: STObject.h:501
value_type value() const
Definition: STObject.h:707
value_type operator*() const
Definition: STObject.h:726
T const * operator->() const
Definition: STObject.h:733
ValueProxy & operator-=(U const &u)
typename T::value_type value_type
Definition: STObject.h:524
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:549
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
bool operator!=(STObject const &o) const
Definition: STObject.h:1131
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:657
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:651
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition: STObject.cpp:907
T & peekField(SField const &field)
Definition: STObject.h:1232
STArray const & getFieldArray(SField const &field) const
Definition: STObject.cpp:686
uint160 getFieldH160(SField const &field) const
Definition: STObject.cpp:633
void setFieldCurrency(SField const &field, STCurrency const &)
Definition: STObject.cpp:795
STBase const * peekAtPField(SField const &field) const
Definition: STObject.cpp:457
STBase const * peekAtPIndex(int offset) const
Definition: STObject.h:997
void setFieldArray(SField const &field, STArray const &v)
Definition: STObject.cpp:819
void setFieldPathSet(SField const &field, STPathSet const &)
Definition: STObject.cpp:813
iterator end() const
Definition: STObject.h:930
SField const & getFieldSType(int index) const
Definition: STObject.cpp:451
STObject(STObject const &)=default
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:1038
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
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:979
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:735
Serializer getSerializer() const
Definition: STObject.h:963
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
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:789
bool delField(SField const &field)
Definition: STObject.cpp:585
STBase const & peekAtIndex(int offset) const
Definition: STObject.h:985
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:1010
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:991
ValueProxy< T > operator[](TypedField< T > const &f)
Get a modifiable field value.
bool isFree() const
Definition: STObject.h:948
void setFieldUsingAssignment(SField const &field, T const &value)
Definition: STObject.h:1211
list_type v_
Definition: STObject.h:79
bool empty() const
Definition: STObject.h:936
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:924
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:693
bool operator==(STObject const &o) const
Definition: STObject.cpp:838
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:1188
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition: STObject.cpp:825
void setFieldH128(SField const &field, uint128 const &)
Definition: STObject.cpp:753
void setFieldU64(SField const &field, std::uint64_t)
Definition: STObject.cpp:747
bool isEquivalent(STBase const &t) const override
Definition: STObject.cpp:360
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:741
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:972
STBase * getPIndex(int offset)
Definition: STObject.h:1003
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:942
STObject & operator=(STObject const &)=default
void addWithoutSigningFields(Serializer &s) const
Definition: STObject.h:954
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:1113
STVector256 const & getFieldV256(SField const &field) const
Definition: STObject.cpp:679
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:25
SerializedTypeID
Definition: SField.h:107
Number operator*(Number const &x, Number const &y)
Definition: Number.h:290
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:324
TypedField< T > const * f
Definition: SField.h:325
STBase const & operator()(detail::STVar const &e) const
Definition: STObject.h:911
A field with a type known at compile time.
Definition: SField.h:314