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
154PropertyStream::Source::Source(std::string const& name) : m_name(name), item_(this), parent_(nullptr)
155{
156}
157
159{
160 std::lock_guard _(lock_);
161 if (parent_ != nullptr)
162 parent_->remove(*this);
163 removeAll();
164}
165
166std::string const&
168{
169 return m_name;
170}
171
172void
174{
175 std::lock(lock_, source.lock_);
178
179 XRPL_ASSERT(source.parent_ == nullptr, "beast::PropertyStream::Source::add : null source parent");
180 children_.push_back(source.item_);
181 source.parent_ = this;
182}
183
184void
186{
187 std::lock(lock_, child.lock_);
189 std::lock_guard lk2(child.lock_, std::adopt_lock);
190
191 XRPL_ASSERT(child.parent_ == this, "beast::PropertyStream::Source::remove : child parent match");
192 children_.erase(children_.iterator_to(child.item_));
193 child.parent_ = nullptr;
194}
195
196void
198{
199 std::lock_guard _(lock_);
200 for (auto iter = children_.begin(); iter != children_.end();)
201 {
202 std::lock_guard _cl((*iter)->lock_);
203 remove(*(*iter));
204 }
205}
206
207//------------------------------------------------------------------------------
208
209void
211{
212 Map map(m_name, stream);
213 onWrite(map);
214}
215
216void
218{
219 Map map(m_name, stream);
220 onWrite(map);
221
222 std::lock_guard _(lock_);
223
224 for (auto& child : children_)
225 child.source().write(stream);
226}
227
228void
230{
231 std::pair<Source*, bool> result(find(path));
232
233 if (result.first == nullptr)
234 return;
235
236 if (result.second)
237 result.first->write(stream);
238 else
239 result.first->write_one(stream);
240}
241
244{
245 bool const deep(peel_trailing_slashstar(&path));
246 bool const rooted(peel_leading_slash(&path));
247 Source* source(this);
248 if (!path.empty())
249 {
250 if (!rooted)
251 {
252 std::string const name(peel_name(&path));
253 source = find_one_deep(name);
254 if (source == nullptr)
255 return std::make_pair(nullptr, deep);
256 }
257 source = source->find_path(path);
258 }
259 return std::make_pair(source, deep);
260}
261
262bool
264{
265 if (!path->empty() && path->front() == '/')
266 {
267 *path = std::string(path->begin() + 1, path->end());
268 return true;
269 }
270 return false;
271}
272
273bool
275{
276 bool found(false);
277 if (path->empty())
278 return false;
279 if (path->back() == '*')
280 {
281 found = true;
282 path->pop_back();
283 }
284 if (!path->empty() && path->back() == '/')
285 path->pop_back();
286 return found;
287}
288
291{
292 if (path->empty())
293 return "";
294
295 std::string::const_iterator first = (*path).begin();
296 std::string::const_iterator last = (*path).end();
297 std::string::const_iterator pos = std::find(first, last, '/');
298 std::string s(first, pos);
299
300 if (pos != last)
301 *path = std::string(pos + 1, last);
302 else
303 *path = std::string();
304
305 return s;
306}
307
308// Recursive search through the whole tree until name is found
311{
312 Source* found = find_one(name);
313 if (found != nullptr)
314 return found;
315
316 std::lock_guard _(lock_);
317 for (auto& s : children_)
318 {
319 found = s.source().find_one_deep(name);
320 if (found != nullptr)
321 return found;
322 }
323 return nullptr;
324}
325
328{
329 if (path.empty())
330 return this;
331 Source* source(this);
332 do
333 {
334 std::string const name(peel_name(&path));
335 if (name.empty())
336 break;
337 source = source->find_one(name);
338 } while (source != nullptr);
339 return source;
340}
341
342// This function only looks at immediate children
343// If no immediate children match, then return nullptr
346{
347 std::lock_guard _(lock_);
348 for (auto& s : children_)
349 {
350 if (s.source().m_name == name)
351 return &s.source();
352 }
353 return nullptr;
354}
355
356void
360
361//------------------------------------------------------------------------------
362//
363// PropertyStream
364//
365//------------------------------------------------------------------------------
366
367void
368PropertyStream::add(std::string const& key, bool value)
369{
370 if (value)
371 add(key, "true");
372 else
373 add(key, "false");
374}
375
376void
377PropertyStream::add(std::string const& key, char value)
378{
379 lexical_add(key, value);
380}
381
382void
383PropertyStream::add(std::string const& key, signed char value)
384{
385 lexical_add(key, value);
386}
387
388void
389PropertyStream::add(std::string const& key, unsigned char value)
390{
391 lexical_add(key, value);
392}
393
394void
395PropertyStream::add(std::string const& key, short value)
396{
397 lexical_add(key, value);
398}
399
400void
401PropertyStream::add(std::string const& key, unsigned short value)
402{
403 lexical_add(key, value);
404}
405
406void
407PropertyStream::add(std::string const& key, int value)
408{
409 lexical_add(key, value);
410}
411
412void
413PropertyStream::add(std::string const& key, unsigned int value)
414{
415 lexical_add(key, value);
416}
417
418void
419PropertyStream::add(std::string const& key, long value)
420{
421 lexical_add(key, value);
422}
423
424void
425PropertyStream::add(std::string const& key, unsigned long value)
426{
427 lexical_add(key, value);
428}
429
430void
431PropertyStream::add(std::string const& key, long long value)
432{
433 lexical_add(key, value);
434}
435
436void
437PropertyStream::add(std::string const& key, unsigned long long value)
438{
439 lexical_add(key, value);
440}
441
442void
443PropertyStream::add(std::string const& key, float value)
444{
445 lexical_add(key, value);
446}
447
448void
449PropertyStream::add(std::string const& key, double value)
450{
451 lexical_add(key, value);
452}
453
454void
455PropertyStream::add(std::string const& key, long double value)
456{
457 lexical_add(key, value);
458}
459
460void
462{
463 if (value)
464 add("true");
465 else
466 add("false");
467}
468
469void
471{
472 lexical_add(value);
473}
474
475void
476PropertyStream::add(signed char value)
477{
478 lexical_add(value);
479}
480
481void
482PropertyStream::add(unsigned char value)
483{
484 lexical_add(value);
485}
486
487void
489{
490 lexical_add(value);
491}
492
493void
494PropertyStream::add(unsigned short value)
495{
496 lexical_add(value);
497}
498
499void
501{
502 lexical_add(value);
503}
504
505void
506PropertyStream::add(unsigned int value)
507{
508 lexical_add(value);
509}
510
511void
513{
514 lexical_add(value);
515}
516
517void
518PropertyStream::add(unsigned long value)
519{
520 lexical_add(value);
521}
522
523void
524PropertyStream::add(long long value)
525{
526 lexical_add(value);
527}
528
529void
530PropertyStream::add(unsigned long long value)
531{
532 lexical_add(value);
533}
534
535void
537{
538 lexical_add(value);
539}
540
541void
543{
544 lexical_add(value);
545}
546
547void
548PropertyStream::add(long double value)
549{
550 lexical_add(value);
551}
552
553} // 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)