rippled
Loading...
Searching...
No Matches
beast_PropertyStream.cpp
1#include <xrpl/beast/utility/PropertyStream.h>
2#include <xrpl/beast/utility/instrumentation.h>
3
4#include <algorithm>
5#include <iostream>
6#include <mutex>
7#include <string>
8#include <utility>
9
10namespace beast {
11
12//------------------------------------------------------------------------------
13//
14// Item
15//
16//------------------------------------------------------------------------------
17
18PropertyStream::Item::Item(Source* source) : m_source(source)
19{
20}
21
24{
25 return *m_source;
26}
27
30{
31 return &source();
32}
33
36{
37 return source();
38}
39
40//------------------------------------------------------------------------------
41//
42// Proxy
43//
44//------------------------------------------------------------------------------
45
46PropertyStream::Proxy::Proxy(Map const& map, std::string const& key) : m_map(&map), m_key(key)
47{
48}
49
50PropertyStream::Proxy::Proxy(Proxy const& other) : m_map(other.m_map), m_key(other.m_key)
51{
52}
53
55{
56 std::string const s(m_ostream.str());
57 if (!s.empty())
58 m_map->add(m_key, s);
59}
60
63{
64 return m_ostream << manip;
65}
66
67//------------------------------------------------------------------------------
68//
69// Map
70//
71//------------------------------------------------------------------------------
72
73PropertyStream::Map::Map(PropertyStream& stream) : m_stream(stream)
74{
75}
76
77PropertyStream::Map::Map(Set& parent) : m_stream(parent.stream())
78{
80}
81
82PropertyStream::Map::Map(std::string const& key, Map& map) : m_stream(map.stream())
83{
85}
86
87PropertyStream::Map::Map(std::string const& key, PropertyStream& stream) : m_stream(stream)
88{
90}
91
93{
94 m_stream.map_end();
95}
96
99{
100 return m_stream;
101}
102
103PropertyStream const&
105{
106 return m_stream;
107}
108
111{
112 return Proxy(*this, key);
113}
114
115//------------------------------------------------------------------------------
116//
117// Set
118//
119//------------------------------------------------------------------------------
120
121PropertyStream::Set::Set(std::string const& key, Map& map) : m_stream(map.stream())
122{
124}
125
126PropertyStream::Set::Set(std::string const& key, PropertyStream& stream) : m_stream(stream)
127{
129}
130
132{
133 m_stream.array_end();
134}
135
138{
139 return m_stream;
140}
141
142PropertyStream const&
144{
145 return m_stream;
146}
147
148//------------------------------------------------------------------------------
149//
150// Source
151//
152//------------------------------------------------------------------------------
153
155 : m_name(name), item_(this), parent_(nullptr)
156{
157}
158
160{
161 std::lock_guard _(lock_);
162 if (parent_ != nullptr)
163 parent_->remove(*this);
164 removeAll();
165}
166
167std::string const&
169{
170 return m_name;
171}
172
173void
175{
176 std::lock(lock_, source.lock_);
179
180 XRPL_ASSERT(
181 source.parent_ == nullptr, "beast::PropertyStream::Source::add : null source parent");
182 children_.push_back(source.item_);
183 source.parent_ = this;
184}
185
186void
188{
189 std::lock(lock_, child.lock_);
191 std::lock_guard lk2(child.lock_, std::adopt_lock);
192
193 XRPL_ASSERT(
194 child.parent_ == this, "beast::PropertyStream::Source::remove : child parent match");
195 children_.erase(children_.iterator_to(child.item_));
196 child.parent_ = nullptr;
197}
198
199void
201{
202 std::lock_guard _(lock_);
203 for (auto iter = children_.begin(); iter != children_.end();)
204 {
205 std::lock_guard _cl((*iter)->lock_);
206 remove(*(*iter));
207 }
208}
209
210//------------------------------------------------------------------------------
211
212void
214{
215 Map map(m_name, stream);
216 onWrite(map);
217}
218
219void
221{
222 Map map(m_name, stream);
223 onWrite(map);
224
225 std::lock_guard _(lock_);
226
227 for (auto& child : children_)
228 child.source().write(stream);
229}
230
231void
233{
234 std::pair<Source*, bool> result(find(path));
235
236 if (result.first == nullptr)
237 return;
238
239 if (result.second)
240 result.first->write(stream);
241 else
242 result.first->write_one(stream);
243}
244
247{
248 bool const deep(peel_trailing_slashstar(&path));
249 bool const rooted(peel_leading_slash(&path));
250 Source* source(this);
251 if (!path.empty())
252 {
253 if (!rooted)
254 {
255 std::string const name(peel_name(&path));
256 source = find_one_deep(name);
257 if (source == nullptr)
258 return std::make_pair(nullptr, deep);
259 }
260 source = source->find_path(path);
261 }
262 return std::make_pair(source, deep);
263}
264
265bool
267{
268 if (!path->empty() && path->front() == '/')
269 {
270 *path = std::string(path->begin() + 1, path->end());
271 return true;
272 }
273 return false;
274}
275
276bool
278{
279 bool found(false);
280 if (path->empty())
281 return false;
282 if (path->back() == '*')
283 {
284 found = true;
285 path->pop_back();
286 }
287 if (!path->empty() && path->back() == '/')
288 path->pop_back();
289 return found;
290}
291
294{
295 if (path->empty())
296 return "";
297
298 std::string::const_iterator first = (*path).begin();
299 std::string::const_iterator last = (*path).end();
300 std::string::const_iterator pos = std::find(first, last, '/');
301 std::string s(first, pos);
302
303 if (pos != last)
304 *path = std::string(pos + 1, last);
305 else
306 *path = std::string();
307
308 return s;
309}
310
311// Recursive search through the whole tree until name is found
314{
315 Source* found = find_one(name);
316 if (found != nullptr)
317 return found;
318
319 std::lock_guard _(lock_);
320 for (auto& s : children_)
321 {
322 found = s.source().find_one_deep(name);
323 if (found != nullptr)
324 return found;
325 }
326 return nullptr;
327}
328
331{
332 if (path.empty())
333 return this;
334 Source* source(this);
335 do
336 {
337 std::string const name(peel_name(&path));
338 if (name.empty())
339 break;
340 source = source->find_one(name);
341 } while (source != nullptr);
342 return source;
343}
344
345// This function only looks at immediate children
346// If no immediate children match, then return nullptr
349{
350 std::lock_guard _(lock_);
351 for (auto& s : children_)
352 {
353 if (s.source().m_name == name)
354 return &s.source();
355 }
356 return nullptr;
357}
358
359void
363
364//------------------------------------------------------------------------------
365//
366// PropertyStream
367//
368//------------------------------------------------------------------------------
369
370void
371PropertyStream::add(std::string const& key, bool value)
372{
373 if (value)
374 add(key, "true");
375 else
376 add(key, "false");
377}
378
379void
380PropertyStream::add(std::string const& key, char value)
381{
382 lexical_add(key, value);
383}
384
385void
386PropertyStream::add(std::string const& key, signed char value)
387{
388 lexical_add(key, value);
389}
390
391void
392PropertyStream::add(std::string const& key, unsigned char value)
393{
394 lexical_add(key, value);
395}
396
397void
398PropertyStream::add(std::string const& key, short value)
399{
400 lexical_add(key, value);
401}
402
403void
404PropertyStream::add(std::string const& key, unsigned short value)
405{
406 lexical_add(key, value);
407}
408
409void
410PropertyStream::add(std::string const& key, int value)
411{
412 lexical_add(key, value);
413}
414
415void
416PropertyStream::add(std::string const& key, unsigned int value)
417{
418 lexical_add(key, value);
419}
420
421void
422PropertyStream::add(std::string const& key, long value)
423{
424 lexical_add(key, value);
425}
426
427void
428PropertyStream::add(std::string const& key, unsigned long value)
429{
430 lexical_add(key, value);
431}
432
433void
434PropertyStream::add(std::string const& key, long long value)
435{
436 lexical_add(key, value);
437}
438
439void
440PropertyStream::add(std::string const& key, unsigned long long value)
441{
442 lexical_add(key, value);
443}
444
445void
446PropertyStream::add(std::string const& key, float value)
447{
448 lexical_add(key, value);
449}
450
451void
452PropertyStream::add(std::string const& key, double value)
453{
454 lexical_add(key, value);
455}
456
457void
458PropertyStream::add(std::string const& key, long double value)
459{
460 lexical_add(key, value);
461}
462
463void
465{
466 if (value)
467 add("true");
468 else
469 add("false");
470}
471
472void
474{
475 lexical_add(value);
476}
477
478void
479PropertyStream::add(signed char value)
480{
481 lexical_add(value);
482}
483
484void
485PropertyStream::add(unsigned char value)
486{
487 lexical_add(value);
488}
489
490void
492{
493 lexical_add(value);
494}
495
496void
497PropertyStream::add(unsigned short value)
498{
499 lexical_add(value);
500}
501
502void
504{
505 lexical_add(value);
506}
507
508void
509PropertyStream::add(unsigned int value)
510{
511 lexical_add(value);
512}
513
514void
516{
517 lexical_add(value);
518}
519
520void
521PropertyStream::add(unsigned long value)
522{
523 lexical_add(value);
524}
525
526void
527PropertyStream::add(long long value)
528{
529 lexical_add(value);
530}
531
532void
533PropertyStream::add(unsigned long long value)
534{
535 lexical_add(value);
536}
537
538void
540{
541 lexical_add(value);
542}
543
544void
546{
547 lexical_add(value);
548}
549
550void
551PropertyStream::add(long double value)
552{
553 lexical_add(value);
554}
555
556} // namespace beast
T back(T... args)
T begin(T... args)
Proxy operator[](std::string const &key)
Proxy(Map const &map, std::string const &key)
std::ostream & operator<<(std::ostream &manip(std::ostream &)) const
Set(std::string const &key, Map &map)
Subclasses can be called to write to a stream and have children.
static bool peel_leading_slash(std::string *path)
PropertyStream::Source * find_one(std::string const &name)
void removeAll()
Remove all child sources from this Source.
std::pair< Source *, bool > find(std::string path)
Parse the dot-delimited Source path and return the result.
void remove(Source &child)
Remove a child source from this Source.
std::string const & name() const
Returns the name of this source.
void add(Source &source)
Add a child source.
PropertyStream::Source * find_path(std::string path)
void write_one(PropertyStream &stream)
Write only this Source to the stream.
Source * find_one_deep(std::string const &name)
void write(PropertyStream &stream)
write this source and all its children recursively to the stream.
static std::string peel_name(std::string *path)
static bool peel_trailing_slashstar(std::string *path)
virtual void onWrite(Map &)
Subclass override.
Abstract stream with RAII containers that produce a property tree.
virtual void add(std::string const &key, std::string const &value)=0
virtual void map_begin()=0
virtual void array_begin()=0
void lexical_add(std::string const &key, Value value)
T empty(T... args)
T end(T... args)
T find(T... args)
T front(T... args)
T is_same_v
T lock(T... args)
T make_pair(T... args)
T pop_back(T... args)