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