Subject: [Boost-bugs] [Boost C++ Libraries] #3828: No way to create smaller json output from property_tree::write_json
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-01-08 01:16:59
#3828: No way to create smaller json output from property_tree::write_json
-----------------------------------------------------+----------------------
Reporter: Michael Anderson <drmikeando@â¦> | Owner: cornedbee
Type: Bugs | Status: new
Milestone: Boost 1.42.0 | Component: property_tree
Version: Boost Development Trunk | Severity: Problem
Keywords: |
-----------------------------------------------------+----------------------
The current implementation of write_json is filled with whitespace and
newlines. This makes it very nice for human readability, but not so nice
for sending over the network.
It would be nice to have a way to write compact JSON.
I've implemented stripped down versions of the JSON writer that does this,
however there is a heap of common code between this version and the non-
compact version that could/should be factored out.
Heres a sample program
{{{
#include "boost/property_tree/json_parser.hpp"
#include "boost/array.hpp"
boost::property_tree::ptree foo()
{
boost::property_tree::ptree retval;
retval.put("moo","12345");
retval.put("zoo",12345);
return retval;
}
boost::property_tree::ptree bar()
{
boost::property_tree::ptree retval;
retval.put("mork","hello");
return retval;
}
int main()
{
// std::stringstream ss;
boost::property_tree::ptree pt;
pt.put_child("foo", foo() );
pt.put_child("bar", bar() );
boost::property_tree::write_json(std::cout, pt );
boost::property_tree::write_json_compact(std::cout, pt );
}
}}}
The output is:
{{{
"foo":
{
"moo": "12345",
"zoo": "12345"
},
"bar":
{
"mork": "hello"
}
}
{"foo":{"moo":"12345","zoo":"12345"},"bar":{"mork":"hello"}}
}}}
And here are the patches required to make it work
{{{
Index: boost/property_tree/detail/json_parser_write.hpp
===================================================================
--- boost/property_tree/detail/json_parser_write.hpp (revision 58794)
+++ boost/property_tree/detail/json_parser_write.hpp (working copy)
@@ -118,6 +117,56 @@
}
+ template<class Ptree>
+ void write_json_helper_compact(std::basic_ostream<typename
Ptree::key_type::value_type> &stream,
+ const Ptree &pt)
+ {
+
+ typedef typename Ptree::key_type::value_type Ch;
+ typedef typename std::basic_string<Ch> Str;
+
+ // Value or object or array
+ if ( pt.empty())
+ {
+
+ // Write value
+ Str data = create_escapes(pt.template get_value<Str>(),
stream.getloc());
+ stream << Ch('"') << data << Ch('"');
+
+ }
+ else if ( pt.count(Str()) == pt.size())
+ {
+
+ // Write array
+ stream << Ch('[');
+ typename Ptree::const_iterator it = pt.begin();
+ for (; it != pt.end(); ++it)
+ {
+ write_json_helper_compact(stream, it->second);
+ if (boost::next(it) != pt.end())
+ stream << Ch(',');
+ }
+ stream << Ch(']');
+
+ }
+ else
+ {
+
+ // Write object
+ stream << Ch('{');
+ typename Ptree::const_iterator it = pt.begin();
+ for (; it != pt.end(); ++it)
+ {
+ stream << Ch('"') << create_escapes(it->first,
stream.getloc()) << Ch('"') << Ch(':');
+ write_json_helper_compact(stream, it->second );
+ if (boost::next(it) != pt.end())
+ stream << Ch(',');
+ }
+ stream << Ch('}');
+ }
+
+ }
+
// Verify if ptree does not contain information that cannot be
written to json
template<class Ptree>
bool verify_json(const Ptree &pt, int depth)
@@ -159,6 +208,20 @@
BOOST_PROPERTY_TREE_THROW(json_parser_error("write error",
filename, 0));
}
+ // Write ptree to json stream
+ template<class Ptree>
+ void write_json_compact_internal(std::basic_ostream<typename
Ptree::key_type::value_type> &stream,
+ const Ptree &pt,
+ const std::string &filename)
+ {
+ if (!verify_json(pt, 0))
+ BOOST_PROPERTY_TREE_THROW(json_parser_error("ptree contains
data that cannot be represented in JSON format", filename, 0));
+ write_json_helper_compact(stream, pt);
+ stream << std::endl;
+ if (!stream.good())
+ BOOST_PROPERTY_TREE_THROW(json_parser_error("write error",
filename, 0));
+ }
+
} } }
#endif
Index: boost/property_tree/json_parser.hpp
===================================================================
--- boost/property_tree/json_parser.hpp (revision 58794)
+++ boost/property_tree/json_parser.hpp (working copy)
@@ -121,12 +121,61 @@
write_json_internal(stream, pt, filename);
}
+ /**
+ * Translates the property tree to JSON and writes it in a compact
form to
+ * the given output stream.
+ * @note Any property tree key containing only unnamed subkeys will
be
+ * rendered as JSON arrays.
+ * @pre @e pt cannot contain keys that have both subkeys and non-
empty data.
+ * @throw json_parser_error In case of error translating the property
tree
+ * to JSON or writing to the output stream.
+ * @param stream The stream to which to write the JSON representation
of the
+ * property tree.
+ * @param pt The property tree to tranlsate to JSON and output.
+ */
+ template<class Ptree>
+ void write_json_compact(std::basic_ostream<
+ typename Ptree::key_type::value_type
+ > &stream,
+ const Ptree &pt)
+ {
+ write_json_compact_internal(stream, pt, std::string());
+ }
+
+ /**
+ * Translates the property tree to JSON and writes it in a compact
style to
+ * the given file.
+ * @note Any property tree key containing only unnamed subkeys will
be
+ * rendered as JSON arrays.
+ * @pre @e pt cannot contain keys that have both subkeys and non-
empty data.
+ * @throw json_parser_error In case of error translating the property
tree
+ * to JSON or writing to the file.
+ * @param filename The name of the file to which to write the JSON
+ * representation of the property tree.
+ * @param pt The property tree to translate to JSON and output.
+ * @param loc The locale to use when writing out to the output file.
+ */
+ template<class Ptree>
+ void write_json_compact(const std::string &filename,
+ const Ptree &pt,
+ const std::locale &loc = std::locale())
+ {
+ std::basic_ofstream<typename Ptree::key_type::value_type>
+ stream(filename.c_str());
+ if (!stream)
+ BOOST_PROPERTY_TREE_THROW(json_parser_error(
+ "cannot open file", filename, 0));
+ stream.imbue(loc);
+ write_json_compact_internal(stream, pt, filename);
+ }
+
} } }
namespace boost { namespace property_tree
{
using json_parser::read_json;
using json_parser::write_json;
+ using json_parser::write_json_compact;
using json_parser::json_parser_error;
} }
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3828> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:02 UTC