rippled
Loading...
Searching...
No Matches
KnownFormats.h
1#ifndef XRPL_PROTOCOL_KNOWNFORMATS_H_INCLUDED
2#define XRPL_PROTOCOL_KNOWNFORMATS_H_INCLUDED
3
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/type_name.h>
6#include <xrpl/protocol/SOTemplate.h>
7
8#include <boost/container/flat_map.hpp>
9
10#include <algorithm>
11#include <forward_list>
12
13namespace ripple {
14
22template <class KeyType, class Derived>
24{
25public:
28 class Item
29 {
30 public:
32 char const* name,
33 KeyType type,
36 : soTemplate_(uniqueFields, commonFields), name_(name), type_(type)
37 {
38 // Verify that KeyType is appropriate.
39 static_assert(
42 "KnownFormats KeyType must be integral or enum.");
43 }
44
47 std::string const&
48 getName() const
49 {
50 return name_;
51 }
52
56 getType() const
57 {
58 return type_;
59 }
60
61 SOTemplate const&
63 {
64 return soTemplate_;
65 }
66
67 private:
71 };
72
77 KnownFormats() : name_(beast::type_name<Derived>())
78 {
79 }
80
85 virtual ~KnownFormats() = default;
86 KnownFormats(KnownFormats const&) = delete;
88 operator=(KnownFormats const&) = delete;
89
98 findTypeByName(std::string const& name) const
99 {
100 if (auto const result = findByName(name))
101 return result->getType();
102 Throw<std::runtime_error>(
103 name_ + ": Unknown format name '" +
104 name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
105 }
106
109 Item const*
110 findByType(KeyType type) const
111 {
112 auto const itr = types_.find(type);
113 if (itr == types_.end())
114 return nullptr;
115 return itr->second;
116 }
117
118 // begin() and end() are provided for testing purposes.
120 begin() const
121 {
122 return formats_.begin();
123 }
124
126 end() const
127 {
128 return formats_.end();
129 }
130
131protected:
134 Item const*
135 findByName(std::string const& name) const
136 {
137 auto const itr = names_.find(name);
138 if (itr == names_.end())
139 return nullptr;
140 return itr->second;
141 }
142
152 Item const&
153 add(char const* name,
154 KeyType type,
156 std::initializer_list<SOElement> commonFields = {})
157 {
158 if (auto const item = findByType(type))
159 {
161 std::string("Duplicate key for item '") + name +
162 "': already maps to " + item->getName());
163 }
164
165 formats_.emplace_front(name, type, uniqueFields, commonFields);
166 Item const& item{formats_.front()};
167
168 names_[name] = &item;
169 types_[type] = &item;
170
171 return item;
172 }
173
174private:
176
177 // One of the situations where a std::forward_list is useful. We want to
178 // store each Item in a place where its address won't change. So a node-
179 // based container is appropriate. But we don't need searchability.
181
182 boost::container::flat_map<std::string, Item const*> names_;
183 boost::container::flat_map<KeyType, Item const*> types_;
184};
185
186} // namespace ripple
187
188#endif
KeyType getType() const
Retrieve the transaction type this format represents.
SOTemplate const & getSOTemplate() const
Item(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields)
std::string const & getName() const
Retrieve the name of the format.
std::string const name_
Manages a list of known formats.
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
Item const * findByName(std::string const &name) const
Retrieve a format based on its name.
virtual ~KnownFormats()=default
Destroy the known formats object.
std::forward_list< Item >::const_iterator end() const
std::forward_list< Item >::const_iterator begin() const
KnownFormats & operator=(KnownFormats const &)=delete
KnownFormats()
Create the known formats object.
std::forward_list< Item > formats_
KnownFormats(KnownFormats const &)=delete
boost::container::flat_map< std::string, Item const * > names_
boost::container::flat_map< KeyType, Item const * > types_
KeyType findTypeByName(std::string const &name) const
Retrieve the type for a format specified by name.
Item const & add(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields={})
Add a new format.
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:94
T min(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
KeyType
Definition KeyType.h:9
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
T size(T... args)
T substr(T... args)