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