rippled
KnownFormats.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_KNOWNFORMATS_H_INCLUDED
21 #define RIPPLE_PROTOCOL_KNOWNFORMATS_H_INCLUDED
22 
23 #include <ripple/basics/contract.h>
24 #include <ripple/beast/type_name.h>
25 #include <ripple/protocol/SOTemplate.h>
26 #include <boost/container/flat_map.hpp>
27 #include <algorithm>
28 #include <forward_list>
29 
30 namespace ripple {
31 
39 template <class KeyType, class Derived>
41 {
42 public:
45  class Item
46  {
47  public:
49  char const* name,
50  KeyType type,
53  : soTemplate_(uniqueFields, commonFields), name_(name), type_(type)
54  {
55  // Verify that KeyType is appropriate.
56  static_assert(
59  "KnownFormats KeyType must be integral or enum.");
60  }
61 
64  std::string const&
65  getName() const
66  {
67  return name_;
68  }
69 
72  KeyType
73  getType() const
74  {
75  return type_;
76  }
77 
78  SOTemplate const&
79  getSOTemplate() const
80  {
81  return soTemplate_;
82  }
83 
84  private:
87  KeyType const type_;
88  };
89 
94  KnownFormats() : name_(beast::type_name<Derived>())
95  {
96  }
97 
102  virtual ~KnownFormats() = default;
103  KnownFormats(KnownFormats const&) = delete;
104  KnownFormats&
105  operator=(KnownFormats const&) = delete;
106 
114  KeyType
115  findTypeByName(std::string const& name) const
116  {
117  if (auto const result = findByName(name))
118  return result->getType();
119  Throw<std::runtime_error>(
120  name_ + ": Unknown format name '" +
121  name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
122  }
123 
126  Item const*
127  findByType(KeyType type) const
128  {
129  auto const itr = types_.find(type);
130  if (itr == types_.end())
131  return nullptr;
132  return itr->second;
133  }
134 
135  // begin() and end() are provided for testing purposes.
137  begin() const
138  {
139  return formats_.begin();
140  }
141 
143  end() const
144  {
145  return formats_.end();
146  }
147 
148 protected:
151  Item const*
152  findByName(std::string const& name) const
153  {
154  auto const itr = names_.find(name);
155  if (itr == names_.end())
156  return nullptr;
157  return itr->second;
158  }
159 
169  Item const&
170  add(char const* name,
171  KeyType type,
173  std::initializer_list<SOElement> commonFields = {})
174  {
175  if (auto const item = findByType(type))
176  {
177  LogicError(
178  std::string("Duplicate key for item '") + name +
179  "': already maps to " + item->getName());
180  }
181 
182  formats_.emplace_front(name, type, uniqueFields, commonFields);
183  Item const& item{formats_.front()};
184 
185  names_[name] = &item;
186  types_[type] = &item;
187 
188  return item;
189  }
190 
191 private:
193 
194  // One of the situations where a std::forward_list is useful. We want to
195  // store each Item in a place where its address won't change. So a node-
196  // based container is appropriate. But we don't need searchability.
198 
199  boost::container::flat_map<std::string, Item const*> names_;
200  boost::container::flat_map<KeyType, Item const*> types_;
201 };
202 
203 } // namespace ripple
204 
205 #endif
ripple::KnownFormats::name_
std::string name_
Definition: KnownFormats.h:192
ripple::KnownFormats::types_
boost::container::flat_map< KeyType, Item const * > types_
Definition: KnownFormats.h:200
std::string
STL class.
ripple::KnownFormats::operator=
KnownFormats & operator=(KnownFormats const &)=delete
std::string::size
T size(T... args)
ripple::KnownFormats::findByName
Item const * findByName(std::string const &name) const
Retrieve a format based on its name.
Definition: KnownFormats.h:152
ripple::KnownFormats::Item::name_
const std::string name_
Definition: KnownFormats.h:86
ripple::KnownFormats::Item::getName
std::string const & getName() const
Retrieve the name of the format.
Definition: KnownFormats.h:65
ripple::KnownFormats::end
std::forward_list< Item >::const_iterator end() const
Definition: KnownFormats.h:143
algorithm
ripple::KnownFormats::begin
std::forward_list< Item >::const_iterator begin() const
Definition: KnownFormats.h:137
ripple::KnownFormats::Item
A known format.
Definition: KnownFormats.h:45
forward_list
std::is_enum
ripple::SOTemplate
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:82
ripple::KnownFormats
Manages a list of known formats.
Definition: KnownFormats.h:40
ripple::KnownFormats::Item::soTemplate_
SOTemplate soTemplate_
Definition: KnownFormats.h:85
ripple::KnownFormats::Item::getType
KeyType getType() const
Retrieve the transaction type this format represents.
Definition: KnownFormats.h:73
std::is_integral
ripple::KnownFormats::~KnownFormats
virtual ~KnownFormats()=default
Destroy the known formats object.
ripple::KeyType
KeyType
Definition: KeyType.h:28
std::min
T min(T... args)
std::string::substr
T substr(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::KnownFormats::findTypeByName
KeyType findTypeByName(std::string const &name) const
Retrieve the type for a format specified by name.
Definition: KnownFormats.h:115
ripple::KnownFormats::Item::Item
Item(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields)
Definition: KnownFormats.h:48
ripple::LogicError
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:48
std::size_t
ripple::KnownFormats::KnownFormats
KnownFormats()
Create the known formats object.
Definition: KnownFormats.h:94
ripple::KnownFormats::Item::type_
const KeyType type_
Definition: KnownFormats.h:87
ripple::KnownFormats::formats_
std::forward_list< Item > formats_
Definition: KnownFormats.h:197
ripple::KnownFormats::findByType
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
Definition: KnownFormats.h:127
ripple::KnownFormats::add
Item const & add(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields={})
Add a new format.
Definition: KnownFormats.h:170
ripple::KnownFormats::Item::getSOTemplate
SOTemplate const & getSOTemplate() const
Definition: KnownFormats.h:79
std::initializer_list
ripple::KnownFormats::names_
boost::container::flat_map< std::string, Item const * > names_
Definition: KnownFormats.h:199
beast
Definition: base_uint.h:641