rippled
Loading...
Searching...
No Matches
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 <xrpl/basics/contract.h>
24#include <xrpl/beast/type_name.h>
25#include <xrpl/protocol/SOTemplate.h>
26
27#include <boost/container/flat_map.hpp>
28
29#include <algorithm>
30#include <forward_list>
31
32namespace ripple {
33
41template <class KeyType, class Derived>
43{
44public:
47 class Item
48 {
49 public:
51 char const* name,
52 KeyType type,
55 : soTemplate_(uniqueFields, commonFields), name_(name), type_(type)
56 {
57 // Verify that KeyType is appropriate.
58 static_assert(
61 "KnownFormats KeyType must be integral or enum.");
62 }
63
66 std::string const&
67 getName() const
68 {
69 return name_;
70 }
71
75 getType() const
76 {
77 return type_;
78 }
79
80 SOTemplate const&
82 {
83 return soTemplate_;
84 }
85
86 private:
90 };
91
96 KnownFormats() : name_(beast::type_name<Derived>())
97 {
98 }
99
104 virtual ~KnownFormats() = default;
105 KnownFormats(KnownFormats const&) = delete;
107 operator=(KnownFormats const&) = delete;
108
116 KeyType
117 findTypeByName(std::string const& name) const
118 {
119 if (auto const result = findByName(name))
120 return result->getType();
121 Throw<std::runtime_error>(
122 name_ + ": Unknown format name '" +
123 name.substr(0, std::min(name.size(), std::size_t(32))) + "'");
124 }
125
128 Item const*
129 findByType(KeyType type) const
130 {
131 auto const itr = types_.find(type);
132 if (itr == types_.end())
133 return nullptr;
134 return itr->second;
135 }
136
137 // begin() and end() are provided for testing purposes.
139 begin() const
140 {
141 return formats_.begin();
142 }
143
145 end() const
146 {
147 return formats_.end();
148 }
149
150protected:
153 Item const*
154 findByName(std::string const& name) const
155 {
156 auto const itr = names_.find(name);
157 if (itr == names_.end())
158 return nullptr;
159 return itr->second;
160 }
161
171 Item const&
172 add(char const* name,
173 KeyType type,
175 std::initializer_list<SOElement> commonFields = {})
176 {
177 if (auto const item = findByType(type))
178 {
180 std::string("Duplicate key for item '") + name +
181 "': already maps to " + item->getName());
182 }
183
184 formats_.emplace_front(name, type, uniqueFields, commonFields);
185 Item const& item{formats_.front()};
186
187 names_[name] = &item;
188 types_[type] = &item;
189
190 return item;
191 }
192
193private:
195
196 // One of the situations where a std::forward_list is useful. We want to
197 // store each Item in a place where its address won't change. So a node-
198 // based container is appropriate. But we don't need searchability.
200
201 boost::container::flat_map<std::string, Item const*> names_;
202 boost::container::flat_map<KeyType, Item const*> types_;
203};
204
205} // namespace ripple
206
207#endif
KeyType getType() const
Retrieve the transaction type this format represents.
Definition: KnownFormats.h:75
SOTemplate const & getSOTemplate() const
Definition: KnownFormats.h:81
Item(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields)
Definition: KnownFormats.h:50
std::string const & getName() const
Retrieve the name of the format.
Definition: KnownFormats.h:67
std::string const name_
Definition: KnownFormats.h:88
Manages a list of known formats.
Definition: KnownFormats.h:43
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
Definition: KnownFormats.h:129
Item const * findByName(std::string const &name) const
Retrieve a format based on its name.
Definition: KnownFormats.h:154
virtual ~KnownFormats()=default
Destroy the known formats object.
std::forward_list< Item >::const_iterator end() const
Definition: KnownFormats.h:145
std::forward_list< Item >::const_iterator begin() const
Definition: KnownFormats.h:139
KnownFormats & operator=(KnownFormats const &)=delete
KnownFormats()
Create the known formats object.
Definition: KnownFormats.h:96
std::forward_list< Item > formats_
Definition: KnownFormats.h:199
KnownFormats(KnownFormats const &)=delete
boost::container::flat_map< std::string, Item const * > names_
Definition: KnownFormats.h:201
boost::container::flat_map< KeyType, Item const * > types_
Definition: KnownFormats.h:202
KeyType findTypeByName(std::string const &name) const
Retrieve the type for a format specified by name.
Definition: KnownFormats.h:117
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:172
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:114
T min(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
KeyType
Definition: KeyType.h:28
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:37
T size(T... args)
T substr(T... args)