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
47 : m_map(&map), m_key(key)
48{
49}
50
52 : m_map(other.m_map), m_key(other.m_key)
53{
54}
55
57{
58 std::string const s(m_ostream.str());
59 if (!s.empty())
60 m_map->add(m_key, s);
61}
62
65{
66 return m_ostream << manip;
67}
68
69//------------------------------------------------------------------------------
70//
71// Map
72//
73//------------------------------------------------------------------------------
74
75PropertyStream::Map::Map(PropertyStream& stream) : m_stream(stream)
76{
77}
78
79PropertyStream::Map::Map(Set& parent) : m_stream(parent.stream())
80{
82}
83
85 : m_stream(map.stream())
86{
88}
89
91 : m_stream(stream)
92{
94}
95
97{
98 m_stream.map_end();
99}
100
103{
104 return m_stream;
105}
106
107PropertyStream const&
109{
110 return m_stream;
111}
112
115{
116 return Proxy(*this, key);
117}
118
119//------------------------------------------------------------------------------
120//
121// Set
122//
123//------------------------------------------------------------------------------
124
126 : m_stream(map.stream())
127{
129}
130
132 : m_stream(stream)
133{
135}
136
138{
139 m_stream.array_end();
140}
141
144{
145 return m_stream;
146}
147
148PropertyStream const&
150{
151 return m_stream;
152}
153
154//------------------------------------------------------------------------------
155//
156// Source
157//
158//------------------------------------------------------------------------------
159
161 : m_name(name), item_(this), parent_(nullptr)
162{
163}
164
166{
167 std::lock_guard _(lock_);
168 if (parent_ != nullptr)
169 parent_->remove(*this);
170 removeAll();
171}
172
173std::string const&
175{
176 return m_name;
177}
178
179void
181{
182 std::lock(lock_, source.lock_);
185
186 XRPL_ASSERT(
187 source.parent_ == nullptr,
188 "beast::PropertyStream::Source::add : null source parent");
189 children_.push_back(source.item_);
190 source.parent_ = this;
191}
192
193void
195{
196 std::lock(lock_, child.lock_);
198 std::lock_guard lk2(child.lock_, std::adopt_lock);
199
200 XRPL_ASSERT(
201 child.parent_ == this,
202 "beast::PropertyStream::Source::remove : child parent match");
203 children_.erase(children_.iterator_to(child.item_));
204 child.parent_ = nullptr;
205}
206
207void
209{
210 std::lock_guard _(lock_);
211 for (auto iter = children_.begin(); iter != children_.end();)
212 {
213 std::lock_guard _cl((*iter)->lock_);
214 remove(*(*iter));
215 }
216}
217
218//------------------------------------------------------------------------------
219
220void
222{
223 Map map(m_name, stream);
224 onWrite(map);
225}
226
227void
229{
230 Map map(m_name, stream);
231 onWrite(map);
232
233 std::lock_guard _(lock_);
234
235 for (auto& child : children_)
236 child.source().write(stream);
237}
238
239void
241{
242 std::pair<Source*, bool> result(find(path));
243
244 if (result.first == nullptr)
245 return;
246
247 if (result.second)
248 result.first->write(stream);
249 else
250 result.first->write_one(stream);
251}
252
255{
256 bool const deep(peel_trailing_slashstar(&path));
257 bool const rooted(peel_leading_slash(&path));
258 Source* source(this);
259 if (!path.empty())
260 {
261 if (!rooted)
262 {
263 std::string const name(peel_name(&path));
264 source = find_one_deep(name);
265 if (source == nullptr)
266 return std::make_pair(nullptr, deep);
267 }
268 source = source->find_path(path);
269 }
270 return std::make_pair(source, deep);
271}
272
273bool
275{
276 if (!path->empty() && path->front() == '/')
277 {
278 *path = std::string(path->begin() + 1, path->end());
279 return true;
280 }
281 return false;
282}
283
284bool
286{
287 bool found(false);
288 if (path->empty())
289 return false;
290 if (path->back() == '*')
291 {
292 found = true;
293 path->pop_back();
294 }
295 if (!path->empty() && path->back() == '/')
296 path->pop_back();
297 return found;
298}
299
302{
303 if (path->empty())
304 return "";
305
306 std::string::const_iterator first = (*path).begin();
307 std::string::const_iterator last = (*path).end();
308 std::string::const_iterator pos = std::find(first, last, '/');
309 std::string s(first, pos);
310
311 if (pos != last)
312 *path = std::string(pos + 1, last);
313 else
314 *path = std::string();
315
316 return s;
317}
318
319// Recursive search through the whole tree until name is found
322{
323 Source* found = find_one(name);
324 if (found != nullptr)
325 return found;
326
327 std::lock_guard _(lock_);
328 for (auto& s : children_)
329 {
330 found = s.source().find_one_deep(name);
331 if (found != nullptr)
332 return found;
333 }
334 return nullptr;
335}
336
339{
340 if (path.empty())
341 return this;
342 Source* source(this);
343 do
344 {
345 std::string const name(peel_name(&path));
346 if (name.empty())
347 break;
348 source = source->find_one(name);
349 } while (source != nullptr);
350 return source;
351}
352
353// This function only looks at immediate children
354// If no immediate children match, then return nullptr
357{
358 std::lock_guard _(lock_);
359 for (auto& s : children_)
360 {
361 if (s.source().m_name == name)
362 return &s.source();
363 }
364 return nullptr;
365}
366
367void
371
372//------------------------------------------------------------------------------
373//
374// PropertyStream
375//
376//------------------------------------------------------------------------------
377
378void
379PropertyStream::add(std::string const& key, bool value)
380{
381 if (value)
382 add(key, "true");
383 else
384 add(key, "false");
385}
386
387void
388PropertyStream::add(std::string const& key, char value)
389{
390 lexical_add(key, value);
391}
392
393void
394PropertyStream::add(std::string const& key, signed char value)
395{
396 lexical_add(key, value);
397}
398
399void
400PropertyStream::add(std::string const& key, unsigned char value)
401{
402 lexical_add(key, value);
403}
404
405void
406PropertyStream::add(std::string const& key, short value)
407{
408 lexical_add(key, value);
409}
410
411void
412PropertyStream::add(std::string const& key, unsigned short value)
413{
414 lexical_add(key, value);
415}
416
417void
418PropertyStream::add(std::string const& key, int value)
419{
420 lexical_add(key, value);
421}
422
423void
424PropertyStream::add(std::string const& key, unsigned int value)
425{
426 lexical_add(key, value);
427}
428
429void
430PropertyStream::add(std::string const& key, long value)
431{
432 lexical_add(key, value);
433}
434
435void
436PropertyStream::add(std::string const& key, unsigned long value)
437{
438 lexical_add(key, value);
439}
440
441void
442PropertyStream::add(std::string const& key, long long value)
443{
444 lexical_add(key, value);
445}
446
447void
448PropertyStream::add(std::string const& key, unsigned long long value)
449{
450 lexical_add(key, value);
451}
452
453void
454PropertyStream::add(std::string const& key, float value)
455{
456 lexical_add(key, value);
457}
458
459void
460PropertyStream::add(std::string const& key, double value)
461{
462 lexical_add(key, value);
463}
464
465void
466PropertyStream::add(std::string const& key, long double value)
467{
468 lexical_add(key, value);
469}
470
471void
473{
474 if (value)
475 add("true");
476 else
477 add("false");
478}
479
480void
482{
483 lexical_add(value);
484}
485
486void
487PropertyStream::add(signed char value)
488{
489 lexical_add(value);
490}
491
492void
493PropertyStream::add(unsigned char value)
494{
495 lexical_add(value);
496}
497
498void
500{
501 lexical_add(value);
502}
503
504void
505PropertyStream::add(unsigned short value)
506{
507 lexical_add(value);
508}
509
510void
512{
513 lexical_add(value);
514}
515
516void
517PropertyStream::add(unsigned int value)
518{
519 lexical_add(value);
520}
521
522void
524{
525 lexical_add(value);
526}
527
528void
529PropertyStream::add(unsigned long value)
530{
531 lexical_add(value);
532}
533
534void
535PropertyStream::add(long long value)
536{
537 lexical_add(value);
538}
539
540void
541PropertyStream::add(unsigned long long value)
542{
543 lexical_add(value);
544}
545
546void
548{
549 lexical_add(value);
550}
551
552void
554{
555 lexical_add(value);
556}
557
558void
559PropertyStream::add(long double value)
560{
561 lexical_add(value);
562}
563
564} // namespace beast
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 find(T... args)
T is_same_v
T lock(T... args)
T make_pair(T... args)