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