Change kvp string representation

The nested representation was very noisy. Now, the string representation
shows one line per value with the full prefix which is also more
expressive than the old version.
This commit is contained in:
lmat
2017-10-19 15:23:16 -04:00
parent 34e0d6cfa0
commit 08aa0104ef
5 changed files with 53 additions and 28 deletions

View File

@@ -181,23 +181,30 @@ KvpFrameImpl::set_path(Path path, KvpValue* value) noexcept
std::string std::string
KvpFrameImpl::to_string() const noexcept KvpFrameImpl::to_string() const noexcept
{ {
std::ostringstream ret; return to_string("");
ret << "{\n"; }
std::string
KvpFrameImpl::to_string(std::string const & prefix) const noexcept
{
if (!m_valuemap.size())
return prefix;
std::ostringstream ret;
std::for_each(m_valuemap.begin(), m_valuemap.end(), std::for_each(m_valuemap.begin(), m_valuemap.end(),
[this,&ret](const map_type::value_type &a) [this,&ret,&prefix](const map_type::value_type &a)
{ {
ret << " "; std::string new_prefix {prefix};
if (a.first) if (a.first)
ret << a.first; {
ret << " => "; new_prefix += a.first;
new_prefix += "/";
}
if (a.second) if (a.second)
ret << a.second->to_string(); ret << a.second->to_string(new_prefix) << "\n";
ret << ",\n"; else
ret << new_prefix << "(null)\n";
} }
); );
ret << "}\n";
return ret.str(); return ret.str();
} }

View File

@@ -187,6 +187,12 @@ struct KvpFrameImpl
* @return A std::string representing the frame and all its children. * @return A std::string representing the frame and all its children.
*/ */
std::string to_string() const noexcept; std::string to_string() const noexcept;
/**
* Make a string representation of the frame with the specified string
* prefixed to every item in the frame.
* @return A std::string representing all the children of the frame.
*/
std::string to_string(std::string const & prefix) const noexcept;
/** /**
* Report the keys in the immediate frame. Be sensible about using this, it * Report the keys in the immediate frame. Be sensible about using this, it
* isn't a very efficient way to iterate. * isn't a very efficient way to iterate.

View File

@@ -125,34 +125,32 @@ struct to_string_visitor : boost::static_visitor<void>
void operator()(int64_t val) void operator()(int64_t val)
{ {
output << "KVP_VALUE_GINT64(" << val << ")"; output << val << " (64-bit int)";
} }
void operator()(KvpFrame * val) void operator()(KvpFrame* val)
{ {
output << "KVP_VALUE_FRAME(" << val->to_string() << ")"; output << val->to_string();
} }
void operator()(GDate val) void operator()(GDate val)
{ {
output << "KVP_VALUE_GDATE(";
output << std::setw(4) << g_date_get_year(&val) << '-'; output << std::setw(4) << g_date_get_year(&val) << '-';
output << std::setw(2) << g_date_get_month(&val) << '-'; output << std::setw(2) << g_date_get_month(&val) << '-';
output << std::setw(2) << g_date_get_day(&val) << ')'; output << std::setw(2) << g_date_get_day(&val);
output << " (gdate)";
} }
void operator()(GList * val) void operator()(GList * val)
{ {
output << "KVP_VALUE_GLIST("; output << "KVP_VALUE_GLIST(";
output << "[ "; output << "[ ";
/*Since val is passed by value, we can modify it*/ /*Since val is passed by value, we can modify it*/
for (;val; val = val->next) for (;val; val = val->next)
{ {
auto realvalue = static_cast<const KvpValue *>(val->data); auto realvalue = static_cast<const KvpValue *>(val->data);
output << ' ' << realvalue->to_string() << ','; output << ' ' << realvalue->to_string() << ',';
} }
output << " ]"; output << " ]";
output << ")"; output << ")";
} }
@@ -161,53 +159,66 @@ struct to_string_visitor : boost::static_visitor<void>
{ {
char tmp1[40] {}; char tmp1[40] {};
gnc_timespec_to_iso8601_buff (val, tmp1); gnc_timespec_to_iso8601_buff (val, tmp1);
output << "KVP_VALUE_TIMESPEC(" << tmp1 << ")"; output << tmp1 << " (timespec)";
} }
void operator()(gnc_numeric val) void operator()(gnc_numeric val)
{ {
auto tmp1 = gnc_numeric_to_string(val); auto tmp1 = gnc_numeric_to_string(val);
output << "KVP_VALUE_NUMERIC(";
if (tmp1) if (tmp1)
{ {
output << tmp1; output << tmp1;
g_free(tmp1); g_free(tmp1);
} }
output << ")"; else
{
output << "(null)";
}
output << " (timespec)";
} }
void operator()(GncGUID * val) void operator()(GncGUID * val)
{ {
char guidstr[GUID_ENCODING_LENGTH+1]; char guidstr[GUID_ENCODING_LENGTH+1];
output << "KVP_VALUE_GUID(";
if (val) if (val)
{ {
guid_to_string_buff(val,guidstr); guid_to_string_buff(val,guidstr);
output << guidstr; output << guidstr;
} }
output << ")"; else
{
output << "(null)";
}
output << " (guid)";
} }
void operator()(const char * val) void operator()(const char * val)
{ {
output << "KVP_VALUE_STRING(" << val << ")"; output << val << " (char *)";
} }
void operator()(double val) void operator()(double val)
{ {
output << "KVP_VALUE_DOUBLE(" << val << ")"; output << val << " (double)";
} }
}; };
std::string std::string
KvpValueImpl::to_string() const noexcept KvpValueImpl::to_string(std::string const & prefix) const noexcept
{ {
if (this->datastore.type() == typeid(KvpFrame*))
return this->get<KvpFrame*>()->to_string(prefix);
std::ostringstream ret; std::ostringstream ret;
to_string_visitor visitor {ret}; to_string_visitor visitor {ret};
boost::apply_visitor(visitor, datastore); boost::apply_visitor(visitor, datastore);
/*We still use g_strdup since the return value will be freed by g_free*/ /*We still use g_strdup since the return value will be freed by g_free*/
return ret.str(); return prefix + ret.str();
}
std::string
KvpValueImpl::to_string() const noexcept
{
return to_string("");
} }
static int static int

View File

@@ -138,6 +138,7 @@ struct KvpValueImpl
KvpValueImpl::Type get_type() const noexcept; KvpValueImpl::Type get_type() const noexcept;
std::string to_string() const noexcept; std::string to_string() const noexcept;
std::string to_string(std::string const & prefix) const noexcept;
template <typename T> template <typename T>
T get() const noexcept; T get() const noexcept;

View File

@@ -885,7 +885,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
xaccTransCommitEdit (clone); xaccTransCommitEdit (clone);
g_free (cleanup->msg); g_free (cleanup->msg);
g_free (check->msg); g_free (check->msg);
check->msg = g_strdup ("[xaccTransEqual] kvp frames differ:\n{\n notes => KVP_VALUE_STRING(Salt pork sausage),\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(654.321),\n}\n),\n}\n),\n}\n\n\nvs\n\n{\n notes => KVP_VALUE_STRING(Salt pork sausage),\n qux => KVP_VALUE_FRAME({\n quux => KVP_VALUE_FRAME({\n corge => KVP_VALUE_DOUBLE(123.456),\n}\n),\n}\n),\n}\n"); check->msg = g_strdup ("[xaccTransEqual] kvp frames differ:\nnotes/Salt pork sausage (char *)\nqux/quux/corge/654.321 (double)\n\n\n\n\nvs\n\nnotes/Salt pork sausage (char *)\nqux/quux/corge/123.456 (double)\n\n\n");
g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE)); g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE));