rippled
Loading...
Searching...
No Matches
KnownFormats.h
1#pragma once
2
3#include <xrpl/basics/contract.h>
4#include <xrpl/beast/type_name.h>
5#include <xrpl/protocol/SOTemplate.h>
6
7#include <boost/container/flat_map.hpp>
8
9#include <algorithm>
10#include <forward_list>
11
12namespace xrpl {
13
21template <class KeyType, class Derived>
23{
24public:
27 class Item
28 {
29 public:
31 char const* name,
32 KeyType type,
35 : soTemplate_(uniqueFields, commonFields), name_(name), type_(type)
36 {
37 // Verify that KeyType is appropriate.
38 static_assert(
40 "KnownFormats KeyType must be integral or enum.");
41 }
42
45 std::string const&
46 getName() const
47 {
48 return name_;
49 }
50
54 getType() const
55 {
56 return type_;
57 }
58
59 SOTemplate const&
61 {
62 return soTemplate_;
63 }
64
65 private:
69 };
70
75 KnownFormats() : name_(beast::type_name<Derived>())
76 {
77 }
78
83 virtual ~KnownFormats() = default;
84 KnownFormats(KnownFormats const&) = delete;
86 operator=(KnownFormats const&) = delete;
87
96 findTypeByName(std::string const& name) const
97 {
98 if (auto const result = findByName(name))
99 return result->getType();
100 Throw<std::runtime_error>(
101 name_ + ": Unknown format name '" + name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
102 }
103
106 Item const*
107 findByType(KeyType type) const
108 {
109 auto const itr = types_.find(type);
110 if (itr == types_.end())
111 return nullptr;
112 return itr->second;
113 }
114
115 // begin() and end() are provided for testing purposes.
117 begin() const
118 {
119 return formats_.begin();
120 }
121
123 end() const
124 {
125 return formats_.end();
126 }
127
128protected:
131 Item const*
132 findByName(std::string const& name) const
133 {
134 auto const itr = names_.find(name);
135 if (itr == names_.end())
136 return nullptr;
137 return itr->second;
138 }
139
149 Item const&
150 add(char const* name,
151 KeyType type,
153 std::initializer_list<SOElement> commonFields = {})
154 {
155 if (auto const item = findByType(type))
156 {
157 LogicError(std::string("Duplicate key for item '") + name + "': already maps to " + item->getName());
158 }
159
160 formats_.emplace_front(name, type, uniqueFields, commonFields);
161 Item const& item{formats_.front()};
162
163 names_[name] = &item;
164 types_[type] = &item;
165
166 return item;
167 }
168
169private:
171
172 // One of the situations where a std::forward_list is useful. We want to
173 // store each Item in a place where its address won't change. So a node-
174 // based container is appropriate. But we don't need searchability.
176
177 boost::container::flat_map<std::string, Item const*> names_;
178 boost::container::flat_map<KeyType, Item const*> types_;
179};
180
181} // namespace xrpl
KeyType getType() const
Retrieve the transaction type this format represents.
SOTemplate const & getSOTemplate() const
std::string const name_
std::string const & getName() const
Retrieve the name of the format.
Item(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields)
Manages a list of known formats.
virtual ~KnownFormats()=default
Destroy the known formats object.
KnownFormats()
Create the known formats object.
Item const & add(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields={})
Add a new format.
KnownFormats & operator=(KnownFormats const &)=delete
std::forward_list< Item >::const_iterator end() const
KnownFormats(KnownFormats const &)=delete
std::forward_list< Item > 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.
std::forward_list< Item >::const_iterator begin() const
boost::container::flat_map< KeyType, Item const * > types_
boost::container::flat_map< std::string, Item const * > names_
KeyType findTypeByName(std::string const &name) const
Retrieve the type for a format specified by name.
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:88
T min(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
KeyType
Definition KeyType.h:8
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
T size(T... args)
T substr(T... args)