Add PropertyStream for server state introspection

This commit is contained in:
Vinnie Falco
2013-10-07 13:26:56 -07:00
parent 0b69378a03
commit fb6ecebbd1
17 changed files with 650 additions and 480 deletions

View File

@@ -179,6 +179,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\JsonPropertyStream.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\RandomNumbers.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -1621,7 +1627,6 @@
<ClInclude Include="..\..\src\ripple\http\impl\ServerImpl.h" />
<ClInclude Include="..\..\src\ripple\http\impl\Types.h" />
<ClInclude Include="..\..\src\ripple\http\ripple_http.h" />
<ClInclude Include="..\..\src\ripple\json\api\JsonPropertyStreamSink.h" />
<ClInclude Include="..\..\src\ripple\json\api\json_config.h" />
<ClInclude Include="..\..\src\ripple\json\api\json_features.h" />
<ClInclude Include="..\..\src\ripple\json\api\json_forwards.h" />
@@ -1683,6 +1688,7 @@
<ClInclude Include="..\..\src\ripple\types\api\IdentifierStorage.h" />
<ClInclude Include="..\..\src\ripple\types\api\IdentifierType.h" />
<ClInclude Include="..\..\src\ripple\types\api\HashMaps.h" />
<ClInclude Include="..\..\src\ripple\types\api\JsonPropertyStream.h" />
<ClInclude Include="..\..\src\ripple\types\api\RandomNumbers.h" />
<ClInclude Include="..\..\src\ripple\types\api\RippleAccountID.h" />
<ClInclude Include="..\..\src\ripple\types\api\RippleAccountPrivateKey.h" />

View File

@@ -1089,6 +1089,9 @@
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Cache.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\types\impl\JsonPropertyStream.cpp">
<Filter>[1] Ripple\types\impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
@@ -2214,8 +2217,8 @@
<ClInclude Include="..\..\src\ripple\peerfinder\impl\CachedEndpoint.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\json\api\JsonPropertyStreamSink.h">
<Filter>[1] Ripple\json\api</Filter>
<ClInclude Include="..\..\src\ripple\types\api\JsonPropertyStream.h">
<Filter>[1] Ripple\types\api</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -1,97 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_JSONPROPERTYSTREAMSINK_H_INCLUDED
#define RIPPLE_JSONPROPERTYSTREAMSINK_H_INCLUDED
#include "beast/beast/utility/PropertyStream.h"
//#include "json_value.h" // ??
namespace ripple {
using namespace beast;
/** A PropertyStream::Sink which produces a Json::Value. */
class JsonPropertyStreamSink : public PropertyStream::Sink
{
public:
explicit JsonPropertyStreamSink (Json::Value& root)
{
m_stack.push_back (&root);
}
void begin_object (std::string const& key)
{
m_stack.push_back (&((*m_stack.back())[key] = Json::objectValue));
}
void end_object ()
{
m_stack.pop_back ();
}
void write (std::string const& key, int32 v)
{
(*m_stack.back())[key] = v;
}
void write (std::string const& key, uint32 v)
{
(*m_stack.back())[key] = v;
}
void write (std::string const& key, std::string const& v)
{
(*m_stack.back())[key] = v;
}
void begin_array (std::string const& key)
{
m_stack.push_back (&((*m_stack.back())[key] = Json::arrayValue));
}
void end_array ()
{
m_stack.pop_back ();
}
void write (int32 v)
{
m_stack.back()->append (v);
}
void write (uint32 v)
{
m_stack.back()->append (v);
}
void write (std::string const& v)
{
m_stack.back()->append (v);
}
private:
Json::Value m_value;
std::vector <Json::Value*> m_stack;
};
}
#endif

View File

@@ -20,15 +20,6 @@
#include "BeastConfig.h"
#include "beast/modules/beast_core/beast_core.h"
#include "ripple_json.h"
#include <cassert>
#include <iomanip>
#include <sstream>
#include <string>
// For json/
//
#ifdef JSON_USE_CPPTL
@@ -38,6 +29,15 @@
#include "impl/json_batchallocator.h"
#endif
#include "beast/modules/beast_core/beast_core.h"
#include "ripple_json.h"
#include <cassert>
#include <iomanip>
#include <sstream>
#include <string>
#define JSON_ASSERT_UNREACHABLE assert( false )
#define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
#define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message );

View File

@@ -22,6 +22,9 @@
#include "beast/beast/Config.h"
#include "beast/beast/strings/String.h"
#include "beast/beast/utility/PropertyStream.h"
#include <deque>
#include <stack>
#include <vector>
@@ -45,6 +48,4 @@
#include "api/json_reader.h"
#include "api/json_writer.h"
#include "api/JsonPropertyStreamSink.h"
#endif

View File

@@ -317,22 +317,20 @@ public:
// PropertyStream
//
void onWrite (PropertyStream stream)
void onWrite (PropertyStream::Map& map)
{
SerializedContext::Scope scope (m_context);
// VFALCO NOTE this is not thread safe (yet)
stream ["peers"] = m_logic.m_slots.peerCount;
stream ["in"] = m_logic.m_slots.inboundCount;
stream ["out"] = m_logic.m_slots.outboundCount;
stream ["out_desired"] = m_logic.m_slots.outDesired;
stream ["in_avail"] = m_logic.m_slots.inboundSlots;
stream ["in_max"] = m_logic.m_slots.inboundSlotsMaximum;
stream ["minutes"] = m_logic.m_slots.uptimeMinutes();
stream ["round"] = m_logic.m_slots.roundUpwards();
stream ["cache"] = uint32(m_logic.m_cache.size());
stream ["legacy"] = uint32(m_logic.m_legacyCache.size());
map ["peers"] = m_logic.m_slots.peerCount;
map ["in"] = m_logic.m_slots.inboundCount;
map ["out"] = m_logic.m_slots.outboundCount;
map ["out_desired"] = m_logic.m_slots.outDesired;
map ["in_avail"] = m_logic.m_slots.inboundSlots;
map ["in_max"] = m_logic.m_slots.inboundSlotsMaximum;
map ["minutes"] = m_logic.m_slots.uptimeMinutes();
map ["round"] = m_logic.m_slots.roundUpwards();
map ["cache"] = uint32(m_logic.m_cache.size());
map ["legacy"] = uint32(m_logic.m_legacyCache.size());
}
//--------------------------------------------------------------------------

View File

@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_JSONPROPERTYSTREAM_H_INCLUDED
#define RIPPLE_JSONPROPERTYSTREAM_H_INCLUDED
namespace ripple {
/** A PropertyStream::Sink which produces a Json::Value. */
class JsonPropertyStream : public PropertyStream
{
public:
Json::Value m_top;
std::vector <Json::Value*> m_stack;
public:
JsonPropertyStream ();
Json::Value const& top() const;
protected:
void map_begin ();
void map_begin (std::string const& key);
void map_end ();
void add (std::string const& key, int32 v);
void add (std::string const& key, uint32 v);
void add (std::string const& key, std::string const& v);
void array_begin ();
void array_begin (std::string const& key);
void array_end ();
void add (int32 v);
void add (uint32 v);
void add (std::string const& v);
};
}
#endif

View File

@@ -0,0 +1,107 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace ripple {
JsonPropertyStream::JsonPropertyStream ()
: m_top (Json::objectValue)
{
m_stack.reserve (64);
m_stack.push_back (&m_top);
}
Json::Value const& JsonPropertyStream::top() const
{
return m_top;
}
void JsonPropertyStream::map_begin ()
{
// top is array
Json::Value& top (*m_stack.back());
Json::Value& map (top.append (Json::objectValue));
m_stack.push_back (&map);
}
void JsonPropertyStream::map_begin (std::string const& key)
{
// top is a map
Json::Value& top (*m_stack.back());
Json::Value& map (top [key] = Json::objectValue);
m_stack.push_back (&map);
}
void JsonPropertyStream::map_end ()
{
m_stack.pop_back ();
}
void JsonPropertyStream::add (std::string const& key, int32 v)
{
(*m_stack.back())[key] = v;
}
void JsonPropertyStream::add (std::string const& key, uint32 v)
{
(*m_stack.back())[key] = v;
}
void JsonPropertyStream::add (std::string const& key, std::string const& v)
{
(*m_stack.back())[key] = v;
}
void JsonPropertyStream::array_begin ()
{
// top is array
Json::Value& top (*m_stack.back());
Json::Value& vec (top.append (Json::arrayValue));
m_stack.push_back (&vec);
}
void JsonPropertyStream::array_begin (std::string const& key)
{
// top is a map
Json::Value& top (*m_stack.back());
Json::Value& vec (top [key] = Json::arrayValue);
m_stack.push_back (&vec);
}
void JsonPropertyStream::array_end ()
{
m_stack.pop_back ();
}
void JsonPropertyStream::add (int32 v)
{
m_stack.back()->append (v);
}
void JsonPropertyStream::add (uint32 v)
{
m_stack.back()->append (v);
}
void JsonPropertyStream::add (std::string const& v)
{
m_stack.back()->append (v);
}
}

View File

@@ -39,3 +39,4 @@
#include "impl/UInt160.cpp"
#include "impl/UInt256.cpp"
#include "impl/RippleIdentifierTests.cpp"
#include "impl/JsonPropertyStream.cpp"

View File

@@ -17,10 +17,11 @@
*/
//==============================================================================
#ifndef RIPPLE_TYPES_H_INCLUDED
#define RIPPLE_TYPES_H_INCLUDED
#include "../json/ripple_json.h"
#include "beast/modules/beast_core/beast_core.h"
#include "beast/modules/beast_crypto/beast_crypto.h" // for UnsignedInteger, Remove ASAP!
@@ -66,5 +67,6 @@ using namespace beast;
# include "api/SimpleIdentifier.h"
#include "api/RippleLedgerHash.h"
#include "api/RipplePublicKeyHash.h"
#include "api/JsonPropertyStream.h"
#endif

View File

@@ -139,6 +139,11 @@ public:
DeadlineTimer m_checkTimer;
ServiceQueue m_queue;
typedef ScopedWrapperContext <
RecursiveMutex, RecursiveMutex::ScopedLockType> Context;
Context m_context;
// True if we should call check on idle.
// This gets set to false once we make it through the whole list.
//
@@ -289,25 +294,28 @@ public:
// PropertyStream
//
void writeSources (PropertyStream stream)
void onWrite (PropertyStream::Map& map)
{
PropertyStream::ScopedArray sources ("sources", stream);
Context::Scope scope (m_context);
map ["trusted"] = uint32 (
m_logic.m_chosenList ?
m_logic.m_chosenList->size() : 0);
for (Logic::SourceTable::const_iterator iter (m_logic.m_sources.begin());
iter != m_logic.m_sources.end(); ++iter)
{
stream.append (iter->source->name().toStdString());
PropertyStream::Set items ("sources", map);
for (Logic::SourceTable::const_iterator iter (m_logic.m_sources.begin());
iter != m_logic.m_sources.end(); ++iter)
items.add (iter->source->name().toStdString());
}
}
void onWrite (PropertyStream stream)
{
// VFALCO NOTE this is not thread safe (yet)
stream ["trusted"] = uint32 (
m_logic.m_chosenList ? m_logic.m_chosenList->size() : 0);
writeSources (stream);
{
PropertyStream::Set items ("validators", map);
for (Logic::ValidatorTable::iterator iter (m_logic.m_validators.begin());
iter != m_logic.m_validators.end(); ++iter)
{
}
}
}
//--------------------------------------------------------------------------

View File

@@ -31,6 +31,7 @@
#include <set>
#include "beast/beast/threads/ScopedWrapperContext.h"
#include "beast/modules/beast_asio/beast_asio.h"
#include "beast/modules/beast_sqdb/beast_sqdb.h"

View File

@@ -673,7 +673,7 @@ public:
// PropertyStream
//
void onWrite (PropertyStream stream)
void onWrite (PropertyStream& stream)
{
}

View File

@@ -228,7 +228,7 @@ public:
// PropertyStream
//
void onWrite (PropertyStream stream)
void onWrite (PropertyStream& stream)
{
}

View File

@@ -17,7 +17,6 @@
*/
//==============================================================================
//
// Carries out the RPC.
//
@@ -814,18 +813,13 @@ Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Applica
{
masterLockHolder.unlock ();
Json::Value result (Json::objectValue);
JsonPropertyStreamSink sink (result);
JsonPropertyStream stream;
if (params.isObject() && params["params"].isArray() && params["params"][0u].isString ())
{
getApp().write (params["params"][0u].asString(), sink);
}
getApp().write (stream, params["params"][0u].asString());
else
{
getApp().write (sink, true);
}
getApp().write (stream);
return result;
return stream.top();
}
// profile offers <pass_a> <account_a> <currency_offer_a> <account_b> <currency_offer_b> <count> [submit]