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
KvpFrameImpl::to_string() const noexcept
{
std::ostringstream ret;
ret << "{\n";
return to_string("");
}
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(),
[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)
ret << a.first;
ret << " => ";
{
new_prefix += a.first;
new_prefix += "/";
}
if (a.second)
ret << a.second->to_string();
ret << ",\n";
ret << a.second->to_string(new_prefix) << "\n";
else
ret << new_prefix << "(null)\n";
}
);
ret << "}\n";
return ret.str();
}

View File

@ -187,6 +187,12 @@ struct KvpFrameImpl
* @return A std::string representing the frame and all its children.
*/
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
* 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)
{
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)
{
output << "KVP_VALUE_GDATE(";
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_day(&val) << ')';
output << std::setw(2) << g_date_get_day(&val);
output << " (gdate)";
}
void operator()(GList * val)
{
output << "KVP_VALUE_GLIST(";
output << "[ ";
/*Since val is passed by value, we can modify it*/
for (;val; val = val->next)
{
auto realvalue = static_cast<const KvpValue *>(val->data);
output << ' ' << realvalue->to_string() << ',';
}
output << " ]";
output << ")";
}
@ -161,53 +159,66 @@ struct to_string_visitor : boost::static_visitor<void>
{
char tmp1[40] {};
gnc_timespec_to_iso8601_buff (val, tmp1);
output << "KVP_VALUE_TIMESPEC(" << tmp1 << ")";
output << tmp1 << " (timespec)";
}
void operator()(gnc_numeric val)
{
auto tmp1 = gnc_numeric_to_string(val);
output << "KVP_VALUE_NUMERIC(";
if (tmp1)
{
output << tmp1;
g_free(tmp1);
}
output << ")";
else
{
output << "(null)";
}
output << " (timespec)";
}
void operator()(GncGUID * val)
{
char guidstr[GUID_ENCODING_LENGTH+1];
output << "KVP_VALUE_GUID(";
if (val)
{
guid_to_string_buff(val,guidstr);
output << guidstr;
}
output << ")";
else
{
output << "(null)";
}
output << " (guid)";
}
void operator()(const char * val)
{
output << "KVP_VALUE_STRING(" << val << ")";
output << val << " (char *)";
}
void operator()(double val)
{
output << "KVP_VALUE_DOUBLE(" << val << ")";
output << val << " (double)";
}
};
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;
to_string_visitor visitor {ret};
boost::apply_visitor(visitor, datastore);
/*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

View File

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

View File

@ -885,7 +885,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
xaccTransCommitEdit (clone);
g_free (cleanup->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));