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