rippled
STExchange.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_STEXCHANGE_H_INCLUDED
21 #define RIPPLE_PROTOCOL_STEXCHANGE_H_INCLUDED
22 
23 #include <ripple/basics/Buffer.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/basics/Slice.h>
26 #include <ripple/protocol/SField.h>
27 #include <ripple/protocol/STBlob.h>
28 #include <ripple/protocol/STInteger.h>
29 #include <ripple/protocol/STObject.h>
30 #include <ripple/basics/Blob.h>
31 #include <boost/optional.hpp>
32 #include <memory>
33 #include <stdexcept>
34 #include <type_traits>
35 #include <utility>
36 
37 namespace ripple {
38 
40 template <class U, class T>
41 struct STExchange;
42 
43 
44 template <class U, class T>
45 struct STExchange<STInteger<U>, T>
46 {
47  explicit STExchange() = default;
48 
49  using value_type = U;
50 
51  static
52  void
53  get (boost::optional<T>& t,
54  STInteger<U> const& u)
55  {
56  t = u.value();
57  }
58 
59  static
61  set (SField const& f, T const& t)
62  {
63  return std::make_unique<
64  STInteger<U>>(f, t);
65  }
66 };
67 
68 template <>
70 {
71  explicit STExchange() = default;
72 
73  using value_type = Slice;
74 
75  static
76  void
77  get (boost::optional<value_type>& t,
78  STBlob const& u)
79  {
80  t.emplace (u.data(), u.size());
81  }
82 
83  static
86  Slice const& t)
87  {
88  return std::make_unique<STBlob>(
89  f, t.data(), t.size());
90  }
91 };
92 
93 template <>
95 {
96  explicit STExchange() = default;
97 
98  using value_type = Buffer;
99 
100  static
101  void
102  get (boost::optional<Buffer>& t,
103  STBlob const& u)
104  {
105  t.emplace (
106  u.data(), u.size());
107  }
108 
109  static
112  Buffer const& t)
113  {
114  return std::make_unique<STBlob>(
115  f, t.data(), t.size());
116  }
117 
118  static
121  Buffer&& t)
122  {
123  return std::make_unique<STBlob>(
124  f, std::move(t));
125  }
126 };
127 
128 //------------------------------------------------------------------------------
129 
132 template <class T, class U>
133 boost::optional<T>
134 get (STObject const& st,
135  TypedField<U> const& f)
136 {
137  boost::optional<T> t;
138  STBase const* const b =
139  st.peekAtPField(f);
140  if (! b)
141  return t;
142  auto const id = b->getSType();
143  if (id == STI_NOTPRESENT)
144  return t;
145  auto const u =
146  dynamic_cast<U const*>(b);
147  // This should never happen
148  if (! u)
149  Throw<std::runtime_error> (
150  "Wrong field type");
151  STExchange<U, T>::get(t, *u);
152  return t;
153 }
154 
155 template <class U>
156 boost::optional<typename STExchange<
157  U, typename U::value_type>::value_type>
158 get (STObject const& st,
159  TypedField<U> const& f)
160 {
161  return get<typename U::value_type>(st, f);
162 }
166 template <class U, class T>
167 void
169  TypedField<U> const& f, T&& t)
170 {
171  st.set(STExchange<U,
172  typename std::decay<T>::type>::set(
173  f, std::forward<T>(t)));
174 }
175 
177 template <class Init>
178 void
180  TypedField<STBlob> const& f,
181  std::size_t size, Init&& init)
182 {
183  st.set(std::make_unique<STBlob>(
184  f, size, init));
185 }
186 
188 template <class = void>
189 void
191  TypedField<STBlob> const& f,
192  void const* data, std::size_t size)
193 {
194  st.set(std::make_unique<STBlob>(
195  f, data, size));
196 }
197 
199 template <class U>
200 void
202  TypedField<U> const& f)
203 {
204  st.makeFieldAbsent(f);
205 }
206 
207 } // ripple
208 
209 #endif
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:77
ripple::STBlob::data
std::uint8_t const * data() const
Definition: STBlob.h:83
ripple::STBase::getSType
virtual SerializedTypeID getSType() const
Definition: STBase.cpp:67
ripple::STObject::makeFieldAbsent
void makeFieldAbsent(SField const &field)
Definition: STObject.cpp:471
utility
ripple::TypedField
A field with a type known at compile time.
Definition: SField.h:260
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:43
std::make_unique
T make_unique(T... args)
ripple::STExchange< STBlob, Slice >::set
static std::unique_ptr< STBlob > set(TypedField< STBlob > const &f, Slice const &t)
Definition: STExchange.h:85
ripple::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:87
ripple::STExchange< STBlob, Buffer >::set
static std::unique_ptr< STBlob > set(TypedField< STBlob > const &f, Buffer const &t)
Definition: STExchange.h:111
ripple::Buffer
Like std::vector<char> but better.
Definition: Buffer.h:35
ripple::STExchange< STBlob, Slice >::get
static void get(boost::optional< value_type > &t, STBlob const &u)
Definition: STExchange.h:77
ripple::erase
void erase(STObject &st, TypedField< U > const &f)
Remove a field in an STObject.
Definition: STExchange.h:201
stdexcept
ripple::STExchange< STInteger< U >, T >::value_type
U value_type
Definition: STExchange.h:49
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:271
ripple::Buffer::size
std::size_t size() const noexcept
Returns the number of bytes in the buffer.
Definition: Buffer.h:130
ripple::STExchange
Convert between serialized type U and C++ type T.
Definition: STExchange.h:41
ripple::Buffer::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Buffer.h:154
ripple::STBlob::size
std::size_t size() const
Definition: STBlob.h:77
ripple::STExchange< STInteger< U >, T >::get
static void get(boost::optional< T > &t, STInteger< U > const &u)
Definition: STExchange.h:53
ripple::STExchange< STBlob, Buffer >::get
static void get(boost::optional< Buffer > &t, STBlob const &u)
Definition: STExchange.h:102
memory
ripple::STInteger
Definition: SField.h:49
std::decay
ripple::STObject
Definition: STObject.h:51
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STObject::peekAtPField
const STBase * peekAtPField(SField const &field) const
Definition: STObject.cpp:367
ripple::SField
Identifies fields.
Definition: SField.h:112
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:65
ripple::STExchange< STBlob, Buffer >::set
static std::unique_ptr< STBlob > set(TypedField< STBlob > const &f, Buffer &&t)
Definition: STExchange.h:120
ripple::STExchange< STInteger< U >, T >::set
static std::unique_ptr< STInteger< U > > set(SField const &f, T const &t)
Definition: STExchange.h:61
std::size_t
ripple::STInteger::value
value_type value() const noexcept
Definition: STInteger.h:80
std::unique_ptr
STL class.
ripple::STObject::set
void set(const SOTemplate &)
Definition: STObject.cpp:88
ripple::STBlob
Definition: STBlob.h:33
type_traits
ripple::get
T & get(EitherAmount &amt)
Definition: AmountSpec.h:124
ripple::STI_NOTPRESENT
@ STI_NOTPRESENT
Definition: SField.h:57