mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Add PropertyStream for server state introspection
This commit is contained in:
@@ -26,182 +26,184 @@
|
||||
#include "../threads/SharedData.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** An output stream to procedurally generate an abstract property tree. */
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Abstract stream with RAII containers that produce a property tree. */
|
||||
class PropertyStream
|
||||
{
|
||||
private:
|
||||
class Proxy;
|
||||
|
||||
public:
|
||||
class ScopedArray;
|
||||
class ScopedObject;
|
||||
class Map;
|
||||
class Set;
|
||||
class Source;
|
||||
|
||||
private:
|
||||
class Item : public List <Item>::Node
|
||||
{
|
||||
public:
|
||||
explicit Item (Source* source);
|
||||
Source& source() const;
|
||||
Source* operator-> () const;
|
||||
Source& operator* () const;
|
||||
private:
|
||||
Source* m_source;
|
||||
};
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class Sink : Uncopyable
|
||||
{
|
||||
public:
|
||||
// Object output
|
||||
//
|
||||
// Default implementations convert to string
|
||||
// Json doesn't support 64 bit so we convert these to string
|
||||
// if they are outside the range of the corresponding 32 bit int
|
||||
virtual void begin_object (std::string const& key) = 0;
|
||||
virtual void end_object () = 0;
|
||||
template <typename Value>
|
||||
void lexical_write (std::string const &key, Value value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
write (key, ss.str());
|
||||
}
|
||||
virtual void write (std::string const& key, int32 value);
|
||||
virtual void write (std::string const& key, uint32 value);
|
||||
virtual void write (std::string const& key, int64 value);
|
||||
virtual void write (std::string const& key, uint64 value);
|
||||
virtual void write (std::string const& key, std::string const& value) = 0;
|
||||
|
||||
// Array output
|
||||
//
|
||||
virtual void begin_array (std::string const& key) = 0;
|
||||
virtual void end_array () = 0;
|
||||
template <typename Value>
|
||||
void lexical_write (Value value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
write (ss.str());
|
||||
}
|
||||
virtual void write ( int32 value);
|
||||
virtual void write (uint32 value);
|
||||
virtual void write ( int64 value);
|
||||
virtual void write (uint64 value);
|
||||
virtual void write (std::string const& value) = 0;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
PropertyStream ();
|
||||
PropertyStream (Sink& sink);
|
||||
PropertyStream (PropertyStream const& other);
|
||||
PropertyStream& operator= (PropertyStream const& other);
|
||||
virtual ~PropertyStream ();
|
||||
|
||||
/** Object output.
|
||||
*/
|
||||
/** @{ */
|
||||
void begin_object (std::string const& key) const;
|
||||
void end_object () const;
|
||||
protected:
|
||||
virtual void map_begin () = 0;
|
||||
virtual void map_begin (std::string const& key) = 0;
|
||||
virtual void map_end () = 0;
|
||||
|
||||
virtual void add (std::string const& key, std::string const& value) = 0;
|
||||
|
||||
template <typename Value>
|
||||
void write (std::string const& key, Value value) const
|
||||
{
|
||||
m_sink->write (key, value);
|
||||
}
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void write (Key key, Value value) const
|
||||
void lexical_add (std::string const &key, Value value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << key;
|
||||
write (ss.str(), value);
|
||||
ss << value;
|
||||
add (key, ss.str());
|
||||
}
|
||||
virtual void add (std::string const& key, int32 value);
|
||||
virtual void add (std::string const& key, uint32 value);
|
||||
virtual void add (std::string const& key, int64 value);
|
||||
virtual void add (std::string const& key, uint64 value);
|
||||
|
||||
Proxy operator[] (std::string const& key) const;
|
||||
virtual void array_begin () = 0;
|
||||
virtual void array_begin (std::string const& key) = 0;
|
||||
virtual void array_end () = 0;
|
||||
|
||||
template <typename Key>
|
||||
Proxy operator[] (Key key) const;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Array output.
|
||||
*/
|
||||
/** @{ */
|
||||
void begin_array (std::string const& key) const;
|
||||
void end_array () const;
|
||||
virtual void add (std::string const& value) = 0;
|
||||
|
||||
template <typename Value>
|
||||
void append (Value value) const
|
||||
{ m_sink->write (value); }
|
||||
|
||||
template <typename Value>
|
||||
PropertyStream const& operator<< (Value value) const
|
||||
{ append (value); return *this; }
|
||||
/** @} */
|
||||
void lexical_add (Value value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
add (ss.str());
|
||||
}
|
||||
virtual void add ( int32 value);
|
||||
virtual void add (uint32 value);
|
||||
virtual void add ( int64 value);
|
||||
virtual void add (uint64 value);
|
||||
|
||||
private:
|
||||
static Sink& nullSink();
|
||||
|
||||
Sink* m_sink;
|
||||
class Item;
|
||||
class Proxy;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Item
|
||||
//
|
||||
|
||||
class PropertyStream::Item : public List <Item>::Node
|
||||
{
|
||||
public:
|
||||
explicit Item (Source* source);
|
||||
Source& source() const;
|
||||
Source* operator-> () const;
|
||||
Source& operator* () const;
|
||||
private:
|
||||
Source* m_source;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Proxy
|
||||
//
|
||||
|
||||
class PropertyStream::Proxy
|
||||
{
|
||||
private:
|
||||
PropertyStream m_stream;
|
||||
Map* m_map;
|
||||
std::string m_key;
|
||||
|
||||
public:
|
||||
Proxy (PropertyStream stream, std::string const& key);
|
||||
Proxy (Map& map, std::string const& key);
|
||||
|
||||
template <typename Value>
|
||||
Proxy& operator= (Value value)
|
||||
{ m_stream.write (m_key, value); return *this; }
|
||||
Proxy& operator= (Value value);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Map
|
||||
//
|
||||
|
||||
template <typename Key>
|
||||
PropertyStream::Proxy PropertyStream::operator[] (Key key) const
|
||||
class PropertyStream::Map : public Uncopyable
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << key;
|
||||
return operator[] (ss.str());
|
||||
private:
|
||||
PropertyStream& m_stream;
|
||||
|
||||
public:
|
||||
explicit Map (PropertyStream& stream);
|
||||
explicit Map (Set& parent);
|
||||
Map (std::string const& key, Map& parent);
|
||||
Map (std::string const& key, PropertyStream& stream);
|
||||
~Map ();
|
||||
|
||||
PropertyStream& stream();
|
||||
PropertyStream const& stream() const;
|
||||
|
||||
template <typename Value>
|
||||
void add (std::string const& key, Value value) const
|
||||
{
|
||||
m_stream.add (key, value);
|
||||
}
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void add (Key key, Value value) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << key;
|
||||
add (ss.str(), value);
|
||||
}
|
||||
|
||||
Proxy operator[] (std::string const& key);
|
||||
|
||||
Proxy operator[] (char const* key)
|
||||
{ return Proxy (*this, key); }
|
||||
|
||||
template <typename Key>
|
||||
Proxy operator[] (Key key) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << key;
|
||||
return Proxy (*this, ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <typename Value>
|
||||
PropertyStream::Proxy& PropertyStream::Proxy::operator= (Value value)
|
||||
{
|
||||
m_map->add (m_key, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Set
|
||||
//
|
||||
|
||||
class PropertyStream::ScopedObject
|
||||
class PropertyStream::Set : public Uncopyable
|
||||
{
|
||||
private:
|
||||
PropertyStream m_stream;
|
||||
PropertyStream& m_stream;
|
||||
|
||||
public:
|
||||
ScopedObject (std::string const& key, PropertyStream stream);
|
||||
~ScopedObject ();
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class PropertyStream::ScopedArray
|
||||
{
|
||||
private:
|
||||
PropertyStream m_stream;
|
||||
|
||||
public:
|
||||
ScopedArray (std::string const& key, PropertyStream stream);
|
||||
~ScopedArray ();
|
||||
explicit Set (Set& set);
|
||||
Set (std::string const& key, Map& map);
|
||||
Set (std::string const& key, PropertyStream& stream);
|
||||
~Set ();
|
||||
|
||||
PropertyStream& stream();
|
||||
PropertyStream const& stream() const;
|
||||
|
||||
template <typename Value>
|
||||
void add (Value value) const
|
||||
{ m_stream.add (value); }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Source
|
||||
//
|
||||
|
||||
/** Subclasses can be called to write to a stream and have children. */
|
||||
class PropertyStream::Source : public Uncopyable
|
||||
@@ -213,6 +215,7 @@ private:
|
||||
: item (source)
|
||||
, parent (nullptr)
|
||||
{ }
|
||||
|
||||
Item item;
|
||||
Source* parent;
|
||||
List <Item> children;
|
||||
@@ -223,19 +226,27 @@ private:
|
||||
std::string const m_name;
|
||||
SharedState m_state;
|
||||
|
||||
void remove (SharedState::Access& state, SharedState::Access& childState);
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void remove (SharedState::Access& state,
|
||||
SharedState::Access& childState);
|
||||
|
||||
void removeAll (SharedState::Access& state);
|
||||
|
||||
void write (SharedState::Access& state, PropertyStream& stream);
|
||||
|
||||
public:
|
||||
explicit Source (std::string const& name);
|
||||
~Source ();
|
||||
|
||||
/** Returns the name of this source. */
|
||||
std::string const& name() const;
|
||||
|
||||
/** Add a child source. */
|
||||
void add (Source& source);
|
||||
|
||||
/** Add a child source by pointer.
|
||||
This returns the passed source so it can be conveniently chained
|
||||
in ctor-initializer lists.
|
||||
The source pointer is returned so it can be used in ctor-initializers.
|
||||
*/
|
||||
template <class Derived>
|
||||
Derived* add (Derived* child)
|
||||
@@ -244,20 +255,42 @@ public:
|
||||
return child;
|
||||
}
|
||||
|
||||
/** Remove a child source. */
|
||||
/** Remove a child source from this Source. */
|
||||
void remove (Source& child);
|
||||
|
||||
/** Remove all child sources. */
|
||||
/** Remove all child sources of this Source. */
|
||||
void removeAll ();
|
||||
|
||||
void write (PropertyStream stream, bool includeChildren);
|
||||
void write (std::string const& path, PropertyStream stream);
|
||||
/** Write only this Source to the stream. */
|
||||
void write_one (PropertyStream& stream);
|
||||
|
||||
virtual void onWrite (PropertyStream) { }
|
||||
/** write this source and all its children recursively to the stream. */
|
||||
void write (PropertyStream& stream);
|
||||
|
||||
/** Parse the path and write the corresponding Source and optional children.
|
||||
If the source is found, it is written. If the wildcard character '*'
|
||||
exists as the last character in the path, then all the children are
|
||||
written recursively.
|
||||
*/
|
||||
void write (PropertyStream& stream, std::string const& path);
|
||||
|
||||
/** Parse the dot-delimited Source path and return the result.
|
||||
The first value will be a pointer to the Source object corresponding
|
||||
to the given path. If no Source object exists, then the first value
|
||||
will be nullptr and the second value will be undefined.
|
||||
The second value is a boolean indicating whether or not the path string
|
||||
specifies the wildcard character '*' as the last character.
|
||||
*/
|
||||
std::pair <Source*, bool> find (std::string const& path);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Subclass override.
|
||||
The default version does nothing.
|
||||
*/
|
||||
virtual void onWrite (Map&);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Item
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::Item::Item (Source* source)
|
||||
: m_source (source)
|
||||
{
|
||||
@@ -44,113 +50,110 @@ PropertyStream::Source& PropertyStream::Item::operator* () const
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void PropertyStream::Sink::write (std::string const& key, int32 value)
|
||||
{
|
||||
lexical_write (key, value);
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (std::string const& key, uint32 value)
|
||||
{
|
||||
lexical_write (key, value);
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (std::string const& key, int64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <int32>::max() &&
|
||||
value >= std::numeric_limits <int32>::min())
|
||||
{
|
||||
write (key, int32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_write (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (std::string const& key, uint64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <uint32>::max() &&
|
||||
value >= std::numeric_limits <uint32>::min())
|
||||
{
|
||||
write (key, uint32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_write (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (int32 value)
|
||||
{
|
||||
lexical_write (value);
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (uint32 value)
|
||||
{
|
||||
lexical_write (value);
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (int64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <int32>::max() &&
|
||||
value >= std::numeric_limits <int32>::min())
|
||||
{
|
||||
write (int32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_write (value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::Sink::write (uint64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <uint32>::max() &&
|
||||
value >= std::numeric_limits <uint32>::min())
|
||||
{
|
||||
write (uint32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_write (value);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Proxy
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::Proxy::Proxy (PropertyStream stream, std::string const& key)
|
||||
: m_stream (stream)
|
||||
PropertyStream::Proxy::Proxy (
|
||||
Map& map, std::string const& key)
|
||||
: m_map (&map)
|
||||
, m_key (key)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Map
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::ScopedObject::ScopedObject (std::string const& key, PropertyStream stream)
|
||||
PropertyStream::Map::Map (PropertyStream& stream)
|
||||
: m_stream (stream)
|
||||
{
|
||||
m_stream.begin_object (key);
|
||||
}
|
||||
|
||||
PropertyStream::ScopedObject::~ScopedObject ()
|
||||
|
||||
PropertyStream::Map::Map (Set& parent)
|
||||
: m_stream (parent.stream())
|
||||
{
|
||||
m_stream.end_object ();
|
||||
m_stream.map_begin ();
|
||||
}
|
||||
|
||||
PropertyStream::Map::Map (std::string const& key, Map& map)
|
||||
: m_stream (map.stream())
|
||||
{
|
||||
m_stream.map_begin (key);
|
||||
}
|
||||
|
||||
PropertyStream::Map::Map (std::string const& key, PropertyStream& stream)
|
||||
: m_stream (stream)
|
||||
{
|
||||
m_stream.map_begin (key);
|
||||
}
|
||||
|
||||
PropertyStream::Map::~Map ()
|
||||
{
|
||||
m_stream.map_end ();
|
||||
}
|
||||
|
||||
PropertyStream& PropertyStream::Map::stream()
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
PropertyStream const& PropertyStream::Map::stream() const
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
PropertyStream::Proxy PropertyStream::Map::operator[] (std::string const& key)
|
||||
{
|
||||
return Proxy (*this, key);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Set
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::ScopedArray::ScopedArray (std::string const& key, PropertyStream stream)
|
||||
PropertyStream::Set::Set (Set& set)
|
||||
: m_stream (set.m_stream)
|
||||
{
|
||||
m_stream.array_begin ();
|
||||
}
|
||||
|
||||
PropertyStream::Set::Set (std::string const& key, Map& map)
|
||||
: m_stream (map.stream())
|
||||
{
|
||||
m_stream.array_begin (key);
|
||||
}
|
||||
|
||||
PropertyStream::Set::Set (std::string const& key, PropertyStream& stream)
|
||||
: m_stream (stream)
|
||||
{
|
||||
m_stream.begin_array (key);
|
||||
}
|
||||
|
||||
PropertyStream::ScopedArray::~ScopedArray ()
|
||||
{
|
||||
m_stream.end_array ();
|
||||
m_stream.array_begin (key);
|
||||
}
|
||||
|
||||
PropertyStream::Set::~Set ()
|
||||
{
|
||||
m_stream.array_end ();
|
||||
}
|
||||
|
||||
PropertyStream& PropertyStream::Set::stream()
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
PropertyStream const& PropertyStream::Set::stream() const
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Source
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::Source::Source (std::string const& name)
|
||||
@@ -167,24 +170,9 @@ PropertyStream::Source::~Source ()
|
||||
removeAll (state);
|
||||
}
|
||||
|
||||
void PropertyStream::Source::remove (
|
||||
SharedState::Access& state, SharedState::Access& childState)
|
||||
std::string const& PropertyStream::Source::name () const
|
||||
{
|
||||
bassert (childState->parent == this);
|
||||
state->children.erase (
|
||||
state->children.iterator_to (
|
||||
childState->item));
|
||||
childState->parent = nullptr;
|
||||
}
|
||||
|
||||
void PropertyStream::Source::removeAll (SharedState::Access& state)
|
||||
{
|
||||
for (List <Item>::iterator iter (state->children.begin());
|
||||
iter != state->children.end();)
|
||||
{
|
||||
SharedState::Access childState ((*iter)->m_state);
|
||||
remove (state, childState);
|
||||
}
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void PropertyStream::Source::add (Source& source)
|
||||
@@ -209,23 +197,57 @@ void PropertyStream::Source::removeAll ()
|
||||
removeAll (state);
|
||||
}
|
||||
|
||||
void PropertyStream::Source::write (PropertyStream stream, bool includeChildren)
|
||||
{
|
||||
ScopedObject child (m_name, stream);
|
||||
onWrite (stream);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
if (includeChildren)
|
||||
void PropertyStream::Source::write (
|
||||
SharedState::Access& state, PropertyStream &stream)
|
||||
{
|
||||
for (List <Item>::iterator iter (state->children.begin());
|
||||
iter != state->children.end(); ++iter)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
for (List <Item>::iterator iter (state->children.begin());
|
||||
iter != state->children.end(); ++iter)
|
||||
{
|
||||
(*iter)->write (stream, true);
|
||||
}
|
||||
Source& source (iter->source());
|
||||
Map map (source.name(), stream);
|
||||
source.write (stream);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::Source::write (std::string const& path, PropertyStream stream)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void PropertyStream::Source::write_one (PropertyStream& stream)
|
||||
{
|
||||
Map map (m_name, stream);
|
||||
//onWrite (map);
|
||||
}
|
||||
|
||||
void PropertyStream::Source::write (PropertyStream& stream)
|
||||
{
|
||||
Map map (m_name, stream);
|
||||
onWrite (map);
|
||||
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
for (List <Item>::iterator iter (state->children.begin());
|
||||
iter != state->children.end(); ++iter)
|
||||
{
|
||||
Source& source (iter->source());
|
||||
source.write (stream);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::Source::write (PropertyStream& stream, std::string const& path)
|
||||
{
|
||||
std::pair <Source*, bool> result (find (path));
|
||||
|
||||
if (result.first == nullptr)
|
||||
return;
|
||||
|
||||
if (result.second)
|
||||
result.first->write (stream);
|
||||
else
|
||||
result.first->write_one (stream);
|
||||
}
|
||||
|
||||
std::pair <PropertyStream::Source*, bool> PropertyStream::Source::find (std::string const& path)
|
||||
{
|
||||
struct Parser
|
||||
{
|
||||
@@ -251,114 +273,150 @@ void PropertyStream::Source::write (std::string const& path, PropertyStream stre
|
||||
std::string::const_iterator m_last;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
|
||||
if (path.empty ())
|
||||
{
|
||||
write (stream, true);
|
||||
return;
|
||||
}
|
||||
return std::make_pair (this, false);
|
||||
|
||||
Parser p (path);
|
||||
Source* source (this);
|
||||
if (p.next() != source->m_name)
|
||||
return;
|
||||
if (p.next() != this->m_name)
|
||||
return std::make_pair (nullptr, false);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
std::string const s (p.next());
|
||||
|
||||
if (s.empty())
|
||||
{
|
||||
source->write (stream, false);
|
||||
break;
|
||||
}
|
||||
else if (s == "*")
|
||||
{
|
||||
source->write (stream, true);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedState::Access state (source->m_state);
|
||||
for (List <Item>::iterator iter (state->children.begin());;)
|
||||
{
|
||||
if (iter->source().m_name == s)
|
||||
{
|
||||
source = &iter->source();
|
||||
break;
|
||||
}
|
||||
return std::make_pair (source, false);
|
||||
|
||||
if (++iter == state->children.end())
|
||||
return;
|
||||
if (s == "*")
|
||||
return std::make_pair (source, true);
|
||||
|
||||
SharedState::Access state (source->m_state);
|
||||
for (List <Item>::iterator iter (state->children.begin());;)
|
||||
{
|
||||
if (iter->source().m_name == s)
|
||||
{
|
||||
source = &iter->source();
|
||||
break;
|
||||
}
|
||||
|
||||
if (++iter == state->children.end())
|
||||
return std::make_pair (nullptr, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::Source::onWrite (Map&)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void PropertyStream::Source::remove (
|
||||
SharedState::Access& state, SharedState::Access& childState)
|
||||
{
|
||||
bassert (childState->parent == this);
|
||||
state->children.erase (
|
||||
state->children.iterator_to (
|
||||
childState->item));
|
||||
childState->parent = nullptr;
|
||||
}
|
||||
|
||||
void PropertyStream::Source::removeAll (SharedState::Access& state)
|
||||
{
|
||||
for (List <Item>::iterator iter (state->children.begin());
|
||||
iter != state->children.end();)
|
||||
{
|
||||
SharedState::Access childState ((*iter)->m_state);
|
||||
remove (state, childState);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// PropertyStream
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
PropertyStream::PropertyStream ()
|
||||
: m_sink (&nullSink())
|
||||
{
|
||||
}
|
||||
|
||||
PropertyStream::PropertyStream (Sink& sink)
|
||||
: m_sink (&sink)
|
||||
PropertyStream::~PropertyStream ()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyStream::PropertyStream (PropertyStream const& other)
|
||||
: m_sink (other.m_sink)
|
||||
void PropertyStream::add (std::string const& key, int32 value)
|
||||
{
|
||||
lexical_add (key, value);
|
||||
}
|
||||
|
||||
PropertyStream& PropertyStream::operator= (PropertyStream const& other)
|
||||
void PropertyStream::add (std::string const& key, uint32 value)
|
||||
{
|
||||
m_sink = other.m_sink;
|
||||
return *this;
|
||||
lexical_add (key, value);
|
||||
}
|
||||
|
||||
PropertyStream::Proxy PropertyStream::operator[] (std::string const& key) const
|
||||
void PropertyStream::add (std::string const& key, int64 value)
|
||||
{
|
||||
return Proxy (*this, key);
|
||||
}
|
||||
|
||||
void PropertyStream::begin_object (std::string const& key) const
|
||||
{
|
||||
m_sink->begin_object (key);
|
||||
}
|
||||
|
||||
void PropertyStream::end_object () const
|
||||
{
|
||||
m_sink->end_object ();
|
||||
}
|
||||
|
||||
void PropertyStream::begin_array (std::string const& key) const
|
||||
{
|
||||
m_sink->begin_array (key);
|
||||
}
|
||||
|
||||
void PropertyStream::end_array () const
|
||||
{
|
||||
m_sink->end_array ();
|
||||
}
|
||||
|
||||
PropertyStream::Sink& PropertyStream::nullSink()
|
||||
{
|
||||
struct NullSink : Sink
|
||||
if (value <= std::numeric_limits <int32>::max() &&
|
||||
value >= std::numeric_limits <int32>::min())
|
||||
{
|
||||
void begin_object (std::string const&) { }
|
||||
void end_object () { }
|
||||
void write (std::string const&, std::string const&) { }
|
||||
void begin_array (std::string const&) { }
|
||||
void end_array () { }
|
||||
void write (std::string const&) { }
|
||||
};
|
||||
|
||||
static NullSink sink;
|
||||
|
||||
return sink;
|
||||
add (key, int32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::add (std::string const& key, uint64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <uint32>::max() &&
|
||||
value >= std::numeric_limits <uint32>::min())
|
||||
{
|
||||
add (key, uint32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_add (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::add (int32 value)
|
||||
{
|
||||
lexical_add (value);
|
||||
}
|
||||
|
||||
void PropertyStream::add (uint32 value)
|
||||
{
|
||||
lexical_add (value);
|
||||
}
|
||||
|
||||
void PropertyStream::add (int64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <int32>::max() &&
|
||||
value >= std::numeric_limits <int32>::min())
|
||||
{
|
||||
add (int32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_add (value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyStream::add (uint64 value)
|
||||
{
|
||||
if (value <= std::numeric_limits <uint32>::max() &&
|
||||
value >= std::numeric_limits <uint32>::min())
|
||||
{
|
||||
add (uint32(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
lexical_add (value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user