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