diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index 65a2a23c15..9b4c8d5e90 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 0f34552a5b..4b895c0753 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 d5181ff2ba..6e46198917 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 b1f5b5863a..239ba4f67f 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 c0a79bf3bd..0000000000
--- 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 e0abdb08f9..e937453cac 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 3e32f9c402..d31e727169 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 93947ea0a8..b0bb369593 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 0000000000..8f420f0247
--- /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 0000000000..c25f6fe61e
--- /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 703c5f9f62..b1aafc7a9c 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 a05bca3460..d5b20f506c 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 73095259df..8d39b62ba8 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 ba2a104d98..d9f49799f9 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 7d45772aea..8ef799823b 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 8581729d47..509fadaf34 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 54215dbdb7..7552f63aad 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]