diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index 34e502c786..dc8eae323b 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -1405,6 +1405,10 @@
True
True
+
+ True
+ True
+
True
True
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index 61688028a0..2de94b1bac 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -2154,6 +2154,9 @@
ripple\app\ledger\impl
+
+ ripple\app\ledger\impl
+
ripple\app\ledger\impl
diff --git a/src/ripple/app/ledger/LedgerToJson.h b/src/ripple/app/ledger/LedgerToJson.h
index 74bbe9c91a..c42fde17a2 100644
--- a/src/ripple/app/ledger/LedgerToJson.h
+++ b/src/ripple/app/ledger/LedgerToJson.h
@@ -53,195 +53,11 @@ struct LedgerFill
RPC::YieldStrategy yieldStrategy;
};
-/** Given a Ledger, options, and a generic Object that has Json semantics,
- fill the Object with a description of the ledger.
-*/
-template
-void fillJson (Object&, LedgerFill const&);
-
/** Add Json to an existing generic Object. */
-template
-void addJson (Object&, LedgerFill const&);
+void addJson(Json::Object&, LedgerFill const&);
+void addJson(Json::Value&, LedgerFill const&);
-/** Return a new Json::Value representing the ledger with given options.*/
-Json::Value getJson (LedgerFill const&);
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-// Implementations.
-
-template
-void fillJson (Object& json, LedgerFill const& fill)
-{
- using namespace ripple::RPC;
-
- auto& ledger = fill.ledger;
-
- bool const bFull (fill.options & LedgerFill::full);
- bool const bExpand (fill.options & LedgerFill::expand);
- bool const bBinary (fill.options & LedgerFill::binary);
-
- // DEPRECATED
- json[jss::seqNum] = to_string (ledger.getLedgerSeq());
- json[jss::parent_hash] = to_string (ledger.getParentHash());
- json[jss::ledger_index] = to_string (ledger.getLedgerSeq());
-
- if (ledger.isClosed() || bFull)
- {
- if (ledger.isClosed())
- json[jss::closed] = true;
-
- // DEPRECATED
- json[jss::hash] = to_string (ledger.getHash());
-
- // DEPRECATED
- json[jss::totalCoins] = to_string (ledger.getTotalCoins());
- json[jss::ledger_hash] = to_string (ledger.getHash());
- json[jss::transaction_hash] = to_string (ledger.getTransHash());
- json[jss::account_hash] = to_string (ledger.getAccountHash());
- json[jss::accepted] = ledger.isAccepted();
- json[jss::total_coins] = to_string (ledger.getTotalCoins());
-
- auto closeTime = ledger.getCloseTimeNC();
- if (closeTime != 0)
- {
- json[jss::close_time] = closeTime;
- json[jss::close_time_human]
- = boost::posix_time::to_simple_string (
- ptFromSeconds (closeTime));
- json[jss::close_time_resolution] = ledger.getCloseResolution();
-
- if (!ledger.getCloseAgree())
- json[jss::close_time_estimated] = true;
- }
- }
- else
- {
- json[jss::closed] = false;
- }
-
- if (ledger.haveTxMap() && (bFull || fill.options & LedgerFill::dumpTxrp))
- {
- auto const& txMap = ledger.txMap();
- auto&& txns = setArray (json, jss::transactions);
- SHAMapTreeNode::TNType type;
-
- CountedYield count (
- fill.yieldStrategy.transactionYieldCount, fill.yield);
- for (auto item = txMap.peekFirstItem (type); item;
- item = txMap.peekNextItem (item->key(), type))
- {
- count.yield();
- if (bFull || bExpand)
- {
- if (type == SHAMapTreeNode::tnTRANSACTION_NM)
- {
- if (bBinary)
- {
- auto&& obj = appendObject (txns);
- obj[jss::tx_blob] = strHex (item->peekData ());
- }
- else
- {
- SerialIter sit (item->slice ());
- STTx txn (sit);
- txns.append (txn.getJson (0));
- }
- }
- else if (type == SHAMapTreeNode::tnTRANSACTION_MD)
- {
- if (bBinary)
- {
- SerialIter sit (item->slice ());
-
- auto&& obj = appendObject (txns);
- obj[jss::tx_blob] = strHex (sit.getVL ());
- obj[jss::meta] = strHex (sit.getVL ());
- }
- else
- {
- // VFALCO This is making a needless copy
- SerialIter sit (item->slice ());
- auto const vl = sit.getVL();
- SerialIter tsit (makeSlice(vl));
- STTx txn (tsit);
-
- TxMeta meta (
- item->key(), ledger.getLedgerSeq(), sit.getVL ());
-
- auto&& txJson = appendObject (txns);
- copyFrom(txJson, txn.getJson (0));
- txJson[jss::metaData] = meta.getJson (0);
- }
- }
- else
- {
- auto&& error = appendObject (txns);
- error[to_string (item->key())] = (int) type;
- }
- }
- else
- {
- txns.append (to_string (item->key()));
- }
- }
- }
-
- if (ledger.haveStateMap() && (bFull || fill.options & LedgerFill::dumpState))
- {
- auto const& stateMap = ledger.stateMap();
- auto&& array = Json::setArray (json, jss::accountState);
- RPC::CountedYield count (
- fill.yieldStrategy.accountYieldCount, fill.yield);
- if (bFull || bExpand)
- {
- if (bBinary)
- {
- stateMap.visitLeaves (
- [&array] (std::shared_ptr const& smi)
- {
- auto&& obj = appendObject (array);
- obj[jss::hash] = to_string(smi->key());
- obj[jss::tx_blob] = strHex(smi->peekData ());
- });
- }
- else
- {
- ledger.visitStateItems (
- [&array, &count] (SLE::ref sle)
- {
- count.yield();
- array.append (sle->getJson(0));
- });
- }
- }
- else
- {
- stateMap.visitLeaves(
- [&array, &count] (std::shared_ptr const& smi)
- {
- count.yield();
- array.append (to_string(smi->key()));
- });
- }
- }
-}
-
-/** Add Json to an existing generic Object. */
-template
-void addJson (Object& json, LedgerFill const& fill)
-{
- auto&& object = Json::addObject (json, jss::ledger);
- fillJson (object, fill);
-}
-
-inline
-Json::Value getJson (LedgerFill const& fill)
-{
- Json::Value json;
- fillJson (json, fill);
- return json;
-}
+Json::Value getJson(LedgerFill const&);
} // ripple
diff --git a/src/ripple/app/ledger/impl/LedgerToJson.cpp b/src/ripple/app/ledger/impl/LedgerToJson.cpp
new file mode 100644
index 0000000000..de9ffb08da
--- /dev/null
+++ b/src/ripple/app/ledger/impl/LedgerToJson.cpp
@@ -0,0 +1,206 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012-2015 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.
+*/
+//==============================================================================
+
+#include
+
+namespace ripple {
+
+template
+void fillJson (Object& json, LedgerFill const& fill)
+{
+ using namespace ripple::RPC;
+
+ auto& ledger = fill.ledger;
+
+ bool const bFull (fill.options & LedgerFill::full);
+ bool const bExpand (fill.options & LedgerFill::expand);
+ bool const bBinary (fill.options & LedgerFill::binary);
+
+ // DEPRECATED
+ json[jss::seqNum] = to_string (ledger.getLedgerSeq());
+ json[jss::parent_hash] = to_string (ledger.getParentHash());
+ json[jss::ledger_index] = to_string (ledger.getLedgerSeq());
+
+ if (ledger.isClosed() || bFull)
+ {
+ if (ledger.isClosed())
+ json[jss::closed] = true;
+
+ // DEPRECATED
+ json[jss::hash] = to_string (ledger.getHash());
+
+ // DEPRECATED
+ json[jss::totalCoins] = to_string (ledger.getTotalCoins());
+ json[jss::ledger_hash] = to_string (ledger.getHash());
+ json[jss::transaction_hash] = to_string (ledger.getTransHash());
+ json[jss::account_hash] = to_string (ledger.getAccountHash());
+ json[jss::accepted] = ledger.isAccepted();
+ json[jss::total_coins] = to_string (ledger.getTotalCoins());
+
+ auto closeTime = ledger.getCloseTimeNC();
+ if (closeTime != 0)
+ {
+ json[jss::close_time] = closeTime;
+ json[jss::close_time_human]
+ = boost::posix_time::to_simple_string (
+ ptFromSeconds (closeTime));
+ json[jss::close_time_resolution] = ledger.getCloseResolution();
+
+ if (!ledger.getCloseAgree())
+ json[jss::close_time_estimated] = true;
+ }
+ }
+ else
+ {
+ json[jss::closed] = false;
+ }
+
+ if (ledger.haveTxMap() && (bFull || fill.options & LedgerFill::dumpTxrp))
+ {
+ auto const& txMap = ledger.txMap();
+ auto&& txns = setArray (json, jss::transactions);
+ SHAMapTreeNode::TNType type;
+
+ CountedYield count (
+ fill.yieldStrategy.transactionYieldCount, fill.yield);
+ for (auto item = txMap.peekFirstItem (type); item;
+ item = txMap.peekNextItem (item->key(), type))
+ {
+ count.yield();
+ if (bFull || bExpand)
+ {
+ if (type == SHAMapTreeNode::tnTRANSACTION_NM)
+ {
+ if (bBinary)
+ {
+ auto&& obj = appendObject (txns);
+ obj[jss::tx_blob] = strHex (item->peekData ());
+ }
+ else
+ {
+ SerialIter sit (item->slice ());
+ STTx txn (sit);
+ txns.append (txn.getJson (0));
+ }
+ }
+ else if (type == SHAMapTreeNode::tnTRANSACTION_MD)
+ {
+ if (bBinary)
+ {
+ SerialIter sit (item->slice ());
+
+ auto&& obj = appendObject (txns);
+ obj[jss::tx_blob] = strHex (sit.getVL ());
+ obj[jss::meta] = strHex (sit.getVL ());
+ }
+ else
+ {
+ // VFALCO This is making a needless copy
+ SerialIter sit (item->slice ());
+ auto const vl = sit.getVL();
+ SerialIter tsit (makeSlice(vl));
+ STTx txn (tsit);
+
+ TxMeta meta (
+ item->key(), ledger.getLedgerSeq(), sit.getVL ());
+
+ auto&& txJson = appendObject (txns);
+ copyFrom(txJson, txn.getJson (0));
+ txJson[jss::metaData] = meta.getJson (0);
+ }
+ }
+ else
+ {
+ auto&& error = appendObject (txns);
+ error[to_string (item->key())] = (int) type;
+ }
+ }
+ else
+ {
+ txns.append (to_string (item->key()));
+ }
+ }
+ }
+
+ if (ledger.haveStateMap() && (bFull || fill.options & LedgerFill::dumpState))
+ {
+ auto const& stateMap = ledger.stateMap();
+ auto&& array = Json::setArray (json, jss::accountState);
+ RPC::CountedYield count (
+ fill.yieldStrategy.accountYieldCount, fill.yield);
+ if (bFull || bExpand)
+ {
+ if (bBinary)
+ {
+ stateMap.visitLeaves (
+ [&array] (std::shared_ptr const& smi)
+ {
+ auto&& obj = appendObject (array);
+ obj[jss::hash] = to_string(smi->key());
+ obj[jss::tx_blob] = strHex(smi->peekData ());
+ });
+ }
+ else
+ {
+ ledger.visitStateItems (
+ [&array, &count] (SLE::ref sle)
+ {
+ count.yield();
+ array.append (sle->getJson(0));
+ });
+ }
+ }
+ else
+ {
+ stateMap.visitLeaves(
+ [&array, &count] (std::shared_ptr const& smi)
+ {
+ count.yield();
+ array.append (to_string(smi->key()));
+ });
+ }
+ }
+}
+
+/** Add Json to an existing generic Object. */
+template
+void addJsonImpl (Object& json, LedgerFill const& fill)
+{
+ auto&& object = Json::addObject (json, jss::ledger);
+ fillJson (object, fill);
+}
+
+void addJson(Json::Object& object, LedgerFill const& fill)
+{
+ addJsonImpl (object, fill);
+}
+
+void addJson(Json::Value& object, LedgerFill const& fill)
+{
+ addJsonImpl (object, fill);
+}
+
+Json::Value getJson (LedgerFill const& fill)
+{
+ Json::Value json;
+ fillJson (json, fill);
+ return json;
+}
+
+} // ripple
diff --git a/src/ripple/unity/app_ledger.cpp b/src/ripple/unity/app_ledger.cpp
index ecfc5fe765..8291de5eb9 100644
--- a/src/ripple/unity/app_ledger.cpp
+++ b/src/ripple/unity/app_ledger.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include