From fb6ecebbd193aff13f00213c64cd7deefb4810b8 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Mon, 7 Oct 2013 13:26:56 -0700 Subject: [PATCH] Add PropertyStream for server state introspection --- Builds/VisualStudio2012/RippleD.vcxproj | 8 +- .../VisualStudio2012/RippleD.vcxproj.filters | 7 +- src/beast/beast/utility/PropertyStream.h | 309 ++++++------ .../beast/utility/impl/PropertyStream.cpp | 440 ++++++++++-------- src/ripple/json/api/JsonPropertyStreamSink.h | 97 ---- src/ripple/json/ripple_json.cpp | 18 +- src/ripple/json/ripple_json.h | 5 +- src/ripple/peerfinder/impl/Manager.cpp | 24 +- src/ripple/types/api/JsonPropertyStream.h | 55 +++ src/ripple/types/impl/JsonPropertyStream.cpp | 107 +++++ src/ripple/types/ripple_types.cpp | 1 + src/ripple/types/ripple_types.h | 4 +- src/ripple/validators/impl/Manager.cpp | 36 +- src/ripple/validators/ripple_validators.cpp | 1 + src/ripple_app/main/Application.cpp | 2 +- src/ripple_app/peers/Peers.cpp | 2 +- src/ripple_app/rpc/RPCHandler.cpp | 14 +- 17 files changed, 650 insertions(+), 480 deletions(-) delete mode 100644 src/ripple/json/api/JsonPropertyStreamSink.h create mode 100644 src/ripple/types/api/JsonPropertyStream.h create mode 100644 src/ripple/types/impl/JsonPropertyStream.cpp diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 65a2a23c1..9b4c8d5e9 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -179,6 +179,12 @@ true true + + true + true + true + true + true true @@ -1621,7 +1627,6 @@ - @@ -1683,6 +1688,7 @@ + diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 0f34552a5..4b895c075 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -1089,6 +1089,9 @@ [1] Ripple\peerfinder\impl + + [1] Ripple\types\impl + @@ -2214,8 +2217,8 @@ [1] Ripple\peerfinder\impl - - [1] Ripple\json\api + + [1] Ripple\types\api diff --git a/src/beast/beast/utility/PropertyStream.h b/src/beast/beast/utility/PropertyStream.h index d5181ff2b..6e4619891 100644 --- a/src/beast/beast/utility/PropertyStream.h +++ b/src/beast/beast/utility/PropertyStream.h @@ -26,182 +26,184 @@ #include "../threads/SharedData.h" #include +#include 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 ::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 - 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 - 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 - void write (std::string const& key, Value value) const - { - m_sink->write (key, value); - } - - template - 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 - 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 - void append (Value value) const - { m_sink->write (value); } - - template - 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 ::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 - Proxy& operator= (Value value) - { m_stream.write (m_key, value); return *this; } + Proxy& operator= (Value value); }; //------------------------------------------------------------------------------ +// +// Map +// -template -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 + void add (std::string const& key, Value value) const + { + m_stream.add (key, value); + } + + template + 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 + Proxy operator[] (Key key) const + { + std::stringstream ss; + ss << key; + return Proxy (*this, ss.str()); + } +}; + +//-------------------------------------------------------------------------- + +template +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 + 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 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 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 find (std::string const& path); + + //-------------------------------------------------------------------------- + + /** Subclass override. + The default version does nothing. + */ + virtual void onWrite (Map&); }; -//------------------------------------------------------------------------------ - } #endif diff --git a/src/beast/beast/utility/impl/PropertyStream.cpp b/src/beast/beast/utility/impl/PropertyStream.cpp index b1f5b5863..239ba4f67 100644 --- a/src/beast/beast/utility/impl/PropertyStream.cpp +++ b/src/beast/beast/utility/impl/PropertyStream.cpp @@ -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 ::max() && - value >= std::numeric_limits ::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 ::max() && - value >= std::numeric_limits ::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 ::max() && - value >= std::numeric_limits ::min()) - { - write (int32(value)); - } - else - { - lexical_write (value); - } -} - -void PropertyStream::Sink::write (uint64 value) -{ - if (value <= std::numeric_limits ::max() && - value >= std::numeric_limits ::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 ::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 ::iterator iter (state->children.begin()); + iter != state->children.end(); ++iter) { - SharedState::Access state (m_state); - for (List ::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 ::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 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::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 ::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 ::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 ::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 ::max() && + value >= std::numeric_limits ::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 ::max() && + value >= std::numeric_limits ::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 ::max() && + value >= std::numeric_limits ::min()) + { + add (int32(value)); + } + else + { + lexical_add (value); + } +} + +void PropertyStream::add (uint64 value) +{ + if (value <= std::numeric_limits ::max() && + value >= std::numeric_limits ::min()) + { + add (uint32(value)); + } + else + { + lexical_add (value); + } +} + + } diff --git a/src/ripple/json/api/JsonPropertyStreamSink.h b/src/ripple/json/api/JsonPropertyStreamSink.h deleted file mode 100644 index c0a79bf3b..000000000 --- a/src/ripple/json/api/JsonPropertyStreamSink.h +++ /dev/null @@ -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 m_stack; -}; - -} - -#endif - diff --git a/src/ripple/json/ripple_json.cpp b/src/ripple/json/ripple_json.cpp index e0abdb08f..e937453ca 100644 --- a/src/ripple/json/ripple_json.cpp +++ b/src/ripple/json/ripple_json.cpp @@ -20,15 +20,6 @@ #include "BeastConfig.h" -#include "beast/modules/beast_core/beast_core.h" - -#include "ripple_json.h" - -#include -#include -#include -#include - // 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 +#include +#include +#include + #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 ); diff --git a/src/ripple/json/ripple_json.h b/src/ripple/json/ripple_json.h index 3e32f9c40..d31e72716 100644 --- a/src/ripple/json/ripple_json.h +++ b/src/ripple/json/ripple_json.h @@ -22,6 +22,9 @@ #include "beast/beast/Config.h" +#include "beast/beast/strings/String.h" +#include "beast/beast/utility/PropertyStream.h" + #include #include #include @@ -45,6 +48,4 @@ #include "api/json_reader.h" #include "api/json_writer.h" -#include "api/JsonPropertyStreamSink.h" - #endif diff --git a/src/ripple/peerfinder/impl/Manager.cpp b/src/ripple/peerfinder/impl/Manager.cpp index 93947ea0a..b0bb36959 100644 --- a/src/ripple/peerfinder/impl/Manager.cpp +++ b/src/ripple/peerfinder/impl/Manager.cpp @@ -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()); } //-------------------------------------------------------------------------- diff --git a/src/ripple/types/api/JsonPropertyStream.h b/src/ripple/types/api/JsonPropertyStream.h new file mode 100644 index 000000000..8f420f024 --- /dev/null +++ b/src/ripple/types/api/JsonPropertyStream.h @@ -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 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 + diff --git a/src/ripple/types/impl/JsonPropertyStream.cpp b/src/ripple/types/impl/JsonPropertyStream.cpp new file mode 100644 index 000000000..c25f6fe61 --- /dev/null +++ b/src/ripple/types/impl/JsonPropertyStream.cpp @@ -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); +} + +} + diff --git a/src/ripple/types/ripple_types.cpp b/src/ripple/types/ripple_types.cpp index 703c5f9f6..b1aafc7a9 100644 --- a/src/ripple/types/ripple_types.cpp +++ b/src/ripple/types/ripple_types.cpp @@ -39,3 +39,4 @@ #include "impl/UInt160.cpp" #include "impl/UInt256.cpp" #include "impl/RippleIdentifierTests.cpp" +#include "impl/JsonPropertyStream.cpp" diff --git a/src/ripple/types/ripple_types.h b/src/ripple/types/ripple_types.h index a05bca346..d5b20f506 100644 --- a/src/ripple/types/ripple_types.h +++ b/src/ripple/types/ripple_types.h @@ -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 diff --git a/src/ripple/validators/impl/Manager.cpp b/src/ripple/validators/impl/Manager.cpp index 73095259d..8d39b62ba 100644 --- a/src/ripple/validators/impl/Manager.cpp +++ b/src/ripple/validators/impl/Manager.cpp @@ -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) + { + } + } } //-------------------------------------------------------------------------- diff --git a/src/ripple/validators/ripple_validators.cpp b/src/ripple/validators/ripple_validators.cpp index ba2a104d9..d9f49799f 100644 --- a/src/ripple/validators/ripple_validators.cpp +++ b/src/ripple/validators/ripple_validators.cpp @@ -31,6 +31,7 @@ #include +#include "beast/beast/threads/ScopedWrapperContext.h" #include "beast/modules/beast_asio/beast_asio.h" #include "beast/modules/beast_sqdb/beast_sqdb.h" diff --git a/src/ripple_app/main/Application.cpp b/src/ripple_app/main/Application.cpp index 7d45772ae..8ef799823 100644 --- a/src/ripple_app/main/Application.cpp +++ b/src/ripple_app/main/Application.cpp @@ -673,7 +673,7 @@ public: // PropertyStream // - void onWrite (PropertyStream stream) + void onWrite (PropertyStream& stream) { } diff --git a/src/ripple_app/peers/Peers.cpp b/src/ripple_app/peers/Peers.cpp index 8581729d4..509fadaf3 100644 --- a/src/ripple_app/peers/Peers.cpp +++ b/src/ripple_app/peers/Peers.cpp @@ -228,7 +228,7 @@ public: // PropertyStream // - void onWrite (PropertyStream stream) + void onWrite (PropertyStream& stream) { } diff --git a/src/ripple_app/rpc/RPCHandler.cpp b/src/ripple_app/rpc/RPCHandler.cpp index 54215dbdb..7552f63aa 100644 --- a/src/ripple_app/rpc/RPCHandler.cpp +++ b/src/ripple_app/rpc/RPCHandler.cpp @@ -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 [submit]