xrpld
Loading...
Searching...
No Matches
beast_PropertyStream.cpp
1#include <xrpl/beast/core/List.h>
2#include <xrpl/beast/utility/PropertyStream.h>
3#include <xrpl/beast/utility/instrumentation.h>
4
5#include <algorithm>
6#include <iostream>
7#include <mutex>
8#include <string>
9#include <utility>
10
11namespace beast {
12
13//------------------------------------------------------------------------------
14//
15// Item
16//
17//------------------------------------------------------------------------------
18
22
25{
26 return *source_;
27}
28
31{
32 return &source();
33}
34
37{
38 return source();
39}
40
41//------------------------------------------------------------------------------
42//
43// Proxy
44//
45//------------------------------------------------------------------------------
46
47PropertyStream::Proxy::Proxy(Map const& map, std::string key) : map_(&map), key_(std::move(key))
48{
49}
50
51PropertyStream::Proxy::Proxy(Proxy const& other) : map_(other.map_), key_(other.key_)
52{
53}
54
56{
57 std::string const s(ostream_.str());
58 if (!s.empty())
59 map_->add(key_, s);
60}
61
67
68//------------------------------------------------------------------------------
69//
70// Map
71//
72//------------------------------------------------------------------------------
73
77
79{
80 stream_.mapBegin();
81}
82
84{
85 stream_.mapBegin(key);
86}
87
92
94{
95 stream_.mapEnd();
96}
97
100{
101 return stream_;
102}
103
104PropertyStream const&
106{
107 return stream_;
108}
109
112{
113 return Proxy(*this, key);
114}
115
116//------------------------------------------------------------------------------
117//
118// Set
119//
120//------------------------------------------------------------------------------
121
123{
124 stream_.arrayBegin(key);
125}
126
128{
129 stream_.arrayBegin(key);
130}
131
133{
134 stream_.arrayEnd();
135}
136
139{
140 return stream_;
141}
142
143PropertyStream const&
145{
146 return stream_;
147}
148
149//------------------------------------------------------------------------------
150//
151// Source
152//
153//------------------------------------------------------------------------------
154
158
160{
161 std::scoped_lock const _(lock_);
162 if (parent_ != nullptr)
163 parent_->remove(*this);
164 removeAll();
165}
166
167std::string const&
169{
170 return name_;
171}
172
173void
175{
176 std::scoped_lock const lock(lock_, source.lock_);
177
178 XRPL_ASSERT(
179 source.parent_ == nullptr, "beast::PropertyStream::Source::add : null source parent");
180 children_.pushBack(source.item_);
181 source.parent_ = this;
182}
183
184void
186{
187 std::scoped_lock const lock(lock_, child.lock_);
188
189 XRPL_ASSERT(
190 child.parent_ == this, "beast::PropertyStream::Source::remove : child parent match");
191 children_.erase(children_.iteratorTo(child.item_));
192 child.parent_ = nullptr;
193}
194
195void
197{
198 std::scoped_lock const _(lock_);
199 for (auto iter = children_.begin(); iter != children_.end();)
200 {
201 std::scoped_lock const cl((*iter)->lock_);
202 remove(*(*iter));
203 }
204}
205
206//------------------------------------------------------------------------------
207
208void
210{
211 Map map(name_, stream);
212 onWrite(map);
213}
214
215void
217{
218 Map map(name_, stream);
219 onWrite(map);
220
221 std::scoped_lock const _(lock_);
222
223 for (auto& child : children_)
224 child.source().write(stream);
225}
226
227void
229{
230 std::pair<Source*, bool> result(find(path));
231
232 if (result.first == nullptr)
233 return;
234
235 if (result.second)
236 {
237 result.first->write(stream);
238 }
239 else
240 {
241 result.first->writeOne(stream);
242 }
243}
244
247{
248 bool const deep(peelTrailingSlashstar(&path));
249 bool const rooted(peelLeadingSlash(&path));
250 Source* source(this);
251 if (!path.empty())
252 {
253 if (!rooted)
254 {
255 std::string const name(peelName(&path));
256 source = findOneDeep(name);
257 if (source == nullptr)
258 return std::make_pair(nullptr, deep);
259 }
260 source = source->findPath(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 const first = (*path).begin();
299 std::string::const_iterator const last = (*path).end();
300 std::string::const_iterator const pos = std::find(first, last, '/');
301 std::string s(first, pos);
302
303 if (pos != last)
304 {
305 *path = std::string(pos + 1, last);
306 }
307 else
308 {
309 *path = std::string();
310 }
311
312 return s;
313}
314
315// Recursive search through the whole tree until name is found
318{
319 Source* found = findOne(name); // NOLINT TODO
320 if (found != nullptr)
321 return found;
322
323 std::scoped_lock const _(lock_);
324 for (auto& s : children_)
325 {
326 found = s.source().findOneDeep(name);
327 if (found != nullptr)
328 return found;
329 }
330 return nullptr;
331}
332
335{
336 if (path.empty())
337 return this;
338 Source* source(this);
339 do
340 {
341 std::string const name(peelName(&path));
342 if (name.empty())
343 break;
344 source = source->findOne(name);
345 } while (source != nullptr);
346 return source;
347}
348
349// This function only looks at immediate children
350// If no immediate children match, then return nullptr
353{
354 std::scoped_lock const _(lock_);
355 for (auto& s : children_)
356 {
357 if (s.source().name_ == name)
358 return &s.source();
359 }
360 return nullptr;
361}
362
363void
367
368//------------------------------------------------------------------------------
369//
370// PropertyStream
371//
372//------------------------------------------------------------------------------
373
374void
375PropertyStream::add(std::string const& key, bool value)
376{
377 if (value)
378 {
379 add(key, "true");
380 }
381 else
382 {
383 add(key, "false");
384 }
385}
386
387void
388PropertyStream::add(std::string const& key, char value)
389{
390 lexicalAdd(key, value);
391}
392
393void
394PropertyStream::add(std::string const& key, signed char value)
395{
396 lexicalAdd(key, value);
397}
398
399void
400PropertyStream::add(std::string const& key, unsigned char value)
401{
402 lexicalAdd(key, value);
403}
404
405void
406PropertyStream::add(std::string const& key, short value)
407{
408 lexicalAdd(key, value);
409}
410
411void
412PropertyStream::add(std::string const& key, unsigned short value)
413{
414 lexicalAdd(key, value);
415}
416
417void
418PropertyStream::add(std::string const& key, int value)
419{
420 lexicalAdd(key, value);
421}
422
423void
424PropertyStream::add(std::string const& key, unsigned int value)
425{
426 lexicalAdd(key, value);
427}
428
429void
430PropertyStream::add(std::string const& key, long value)
431{
432 lexicalAdd(key, value);
433}
434
435void
436PropertyStream::add(std::string const& key, unsigned long value)
437{
438 lexicalAdd(key, value);
439}
440
441void
442PropertyStream::add(std::string const& key, long long value)
443{
444 lexicalAdd(key, value);
445}
446
447void
448PropertyStream::add(std::string const& key, unsigned long long value)
449{
450 lexicalAdd(key, value);
451}
452
453void
454PropertyStream::add(std::string const& key, float value)
455{
456 lexicalAdd(key, value);
457}
458
459void
460PropertyStream::add(std::string const& key, double value)
461{
462 lexicalAdd(key, value);
463}
464
465void
466PropertyStream::add(std::string const& key, long double value)
467{
468 lexicalAdd(key, value);
469}
470
471void
473{
474 if (value)
475 {
476 add("true");
477 }
478 else
479 {
480 add("false");
481 }
482}
483
484void
486{
487 lexicalAdd(value);
488}
489
490void
491PropertyStream::add(signed char value)
492{
493 lexicalAdd(value);
494}
495
496void
497PropertyStream::add(unsigned char value)
498{
499 lexicalAdd(value);
500}
501
502void
504{
505 lexicalAdd(value);
506}
507
508void
509PropertyStream::add(unsigned short value)
510{
511 lexicalAdd(value);
512}
513
514void
516{
517 lexicalAdd(value);
518}
519
520void
521PropertyStream::add(unsigned int value)
522{
523 lexicalAdd(value);
524}
525
526void
528{
529 lexicalAdd(value);
530}
531
532void
533PropertyStream::add(unsigned long value)
534{
535 lexicalAdd(value);
536}
537
538void
539PropertyStream::add(long long value)
540{
541 lexicalAdd(value);
542}
543
544void
545PropertyStream::add(unsigned long long value)
546{
547 lexicalAdd(value);
548}
549
550void
552{
553 lexicalAdd(value);
554}
555
556void
558{
559 lexicalAdd(value);
560}
561
562void
563PropertyStream::add(long double value)
564{
565 lexicalAdd(value);
566}
567
568} // namespace beast
T back(T... args)
T begin(T... args)
Proxy operator[](std::string const &key)
Proxy(Map const &map, std::string 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.
void removeAll()
Remove all child sources from this Source.
static bool peelTrailingSlashstar(std::string *path)
static std::string peelName(std::string *path)
std::pair< Source *, bool > find(std::string path)
Parse the dot-delimited Source path and return the result.
PropertyStream::Source * findOne(std::string const &name)
PropertyStream::Source * findPath(std::string path)
void remove(Source &child)
Remove a child source from this Source.
std::string const & name() const
Returns the name of this source.
Source * findOneDeep(std::string const &name)
void add(Source &source)
Add a child source.
static bool peelLeadingSlash(std::string *path)
void writeOne(PropertyStream &stream)
Write only this Source to the stream.
void write(PropertyStream &stream)
write this source and all its children recursively to the stream.
virtual void onWrite(Map &)
Subclass override.
virtual void add(std::string const &key, std::string const &value)=0
void lexicalAdd(std::string const &key, Value value)
T empty(T... args)
T end(T... args)
T find(T... args)
T front(T... args)
T make_pair(T... args)
STL namespace.
T pop_back(T... args)