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#include <boost/container/flat_map.hpp>
27#include <algorithm>
28#include <forward_list>
29
30namespace ripple {
31
39template <class KeyType, class Derived>
41{
42public:
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
73 getType() const
74 {
75 return type_;
76 }
77
78 SOTemplate const&
80 {
81 return soTemplate_;
82 }
83
84 private:
88 };
89
94 KnownFormats() : name_(beast::type_name<Derived>())
95 {
96 }
97
102 virtual ~KnownFormats() = default;
103 KnownFormats(KnownFormats const&) = delete;
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
148protected:
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 {
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
191private:
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
KeyType getType() const
Retrieve the transaction type this format represents.
Definition: KnownFormats.h:73
SOTemplate const & getSOTemplate() const
Definition: KnownFormats.h:79
Item(char const *name, KeyType type, std::initializer_list< SOElement > uniqueFields, std::initializer_list< SOElement > commonFields)
Definition: KnownFormats.h:48
std::string const & getName() const
Retrieve the name of the format.
Definition: KnownFormats.h:65
std::string const name_
Definition: KnownFormats.h:86
Manages a list of known formats.
Definition: KnownFormats.h:41
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
Definition: KnownFormats.h:127
Item const * findByName(std::string const &name) const
Retrieve a format based on its name.
Definition: KnownFormats.h:152
virtual ~KnownFormats()=default
Destroy the known formats object.
std::forward_list< Item >::const_iterator end() const
Definition: KnownFormats.h:143
std::forward_list< Item >::const_iterator begin() const
Definition: KnownFormats.h:137
KnownFormats & operator=(KnownFormats const &)=delete
KnownFormats()
Create the known formats object.
Definition: KnownFormats.h:94
std::forward_list< Item > formats_
Definition: KnownFormats.h:197
KnownFormats(KnownFormats const &)=delete
boost::container::flat_map< std::string, Item const * > names_
Definition: KnownFormats.h:199
boost::container::flat_map< KeyType, Item const * > types_
Definition: KnownFormats.h:200
KeyType findTypeByName(std::string const &name) const
Retrieve the type for a format specified by name.
Definition: KnownFormats.h:115
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
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:113
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:48
T size(T... args)
T substr(T... args)