// -----------------------
-JSONFormatter::JSONFormatter(bool p)
-: m_pretty(p), m_is_pending_string(false)
-{
- reset();
-}
-
void JSONFormatter::flush(std::ostream& os)
{
finish_pending_string();
void JSONFormatter::print_comma(json_formatter_stack_entry_d& entry)
{
+ auto& ss = get_ss();
if (entry.size) {
if (m_pretty) {
- m_ss << ",\n";
+ ss << ",\n";
for (unsigned i = 1; i < m_stack.size(); i++)
- m_ss << " ";
+ ss << " ";
} else {
- m_ss << ",";
+ ss << ",";
}
} else if (m_pretty) {
- m_ss << "\n";
+ ss << "\n";
for (unsigned i = 1; i < m_stack.size(); i++)
- m_ss << " ";
+ ss << " ";
}
if (m_pretty && entry.is_array)
- m_ss << " ";
+ ss << " ";
}
void JSONFormatter::print_quoted_string(std::string_view s)
{
- m_ss << '\"' << json_stream_escaper(s) << '\"';
+ auto& ss = get_ss();
+ ss << '\"' << json_stream_escaper(s) << '\"';
}
void JSONFormatter::print_name(std::string_view name)
{
+ auto& ss = get_ss();
finish_pending_string();
if (m_stack.empty())
return;
print_comma(entry);
if (!entry.is_array) {
if (m_pretty) {
- m_ss << " ";
+ ss << " ";
}
- m_ss << "\"" << name << "\"";
+ ss << "\"" << name << "\"";
if (m_pretty)
- m_ss << ": ";
+ ss << ": ";
else
- m_ss << ':';
+ ss << ':';
}
++entry.size;
}
void JSONFormatter::open_section(std::string_view name, const char *ns, bool is_array)
{
+ auto& ss = get_ss();
if (handle_open_section(name, ns, is_array)) {
return;
}
print_name(name);
}
if (is_array)
- m_ss << '[';
+ ss << '[';
else
- m_ss << '{';
+ ss << '{';
json_formatter_stack_entry_d n;
n.is_array = is_array;
void JSONFormatter::close_section()
{
-
+ auto& ss = get_ss();
if (handle_close_section()) {
return;
}
struct json_formatter_stack_entry_d& entry = m_stack.back();
if (m_pretty && entry.size) {
- m_ss << "\n";
+ ss << "\n";
for (unsigned i = 1; i < m_stack.size(); i++)
- m_ss << " ";
+ ss << " ";
}
- m_ss << (entry.is_array ? ']' : '}');
+ ss << (entry.is_array ? ']' : '}');
m_stack.pop_back();
if (m_pretty && m_stack.empty())
- m_ss << "\n";
+ ss << "\n";
}
void JSONFormatter::finish_pending_string()
void JSONFormatter::add_value(std::string_view name, std::string_view val, bool quoted)
{
+ auto& ss = get_ss();
if (handle_value(name, val, quoted)) {
return;
}
print_name(name);
if (!quoted) {
- m_ss << val;
+ ss << val;
} else {
print_quoted_string(val);
}
int JSONFormatter::get_len() const
{
- return m_ss.str().size();
+ return m_ss.tellp();
}
void JSONFormatter::write_raw_data(const char *data)
{
- m_ss << data;
+ get_ss() << data;
}
const char *XMLFormatter::XML_1_DTD =
#include "include/buffer_fwd.h"
#include <deque>
+#include <fstream>
#include <list>
#include <memory>
#include <vector>
virtual void write_bin_data(const char* buff, int buf_len);
};
- class copyable_sstream : public std::stringstream {
+ class JSONFormatter : public Formatter {
public:
- copyable_sstream() {}
- copyable_sstream(const copyable_sstream& rhs) {
- str(rhs.str());
+ explicit JSONFormatter(bool p = false) : m_pretty(p) {}
+ JSONFormatter(const JSONFormatter& f) :
+ m_pretty(f.m_pretty),
+ m_pending_name(f.m_pending_name),
+ m_stack(f.m_stack),
+ m_is_pending_string(f.m_is_pending_string),
+ m_line_break_enabled(f.m_line_break_enabled)
+ {
+ m_ss.str(f.m_ss.str());
+ m_pending_string.str(f.m_pending_string.str());
+ }
+ JSONFormatter(JSONFormatter&& f) :
+ m_pretty(f.m_pretty),
+ m_ss(std::move(f.m_ss)),
+ m_pending_string(std::move(f.m_pending_string)),
+ m_pending_name(f.m_pending_name),
+ m_stack(std::move(f.m_stack)),
+ m_is_pending_string(f.m_is_pending_string),
+ m_line_break_enabled(f.m_line_break_enabled)
+ {
}
- copyable_sstream& operator=(const copyable_sstream& rhs) {
- str(rhs.str());
+ JSONFormatter& operator=(const JSONFormatter& f)
+ {
+ m_pretty = f.m_pretty;
+ m_ss.str(f.m_ss.str());
+ m_pending_string.str(f.m_pending_string.str());
+ m_pending_name = f.m_pending_name;
+ m_stack = f.m_stack;
+ m_is_pending_string = f.m_is_pending_string;
+ m_line_break_enabled = f.m_line_break_enabled;
return *this;
}
- };
- class JSONFormatter : public Formatter {
- public:
- explicit JSONFormatter(bool p = false);
+ JSONFormatter& operator=(JSONFormatter&& f)
+ {
+ m_pretty = f.m_pretty;
+ m_ss = std::move(f.m_ss);
+ m_pending_string = std::move(f.m_pending_string);
+ m_pending_name = f.m_pending_name;
+ m_stack = std::move(f.m_stack);
+ m_is_pending_string = f.m_is_pending_string;
+ m_line_break_enabled = f.m_line_break_enabled;
+ return *this;
+ }
void set_status(int status, const char* status_name) override {};
void output_header() override {};
int stack_size() { return m_stack.size(); }
+ virtual std::ostream& get_ss() {
+ return m_ss;
+ }
+
private:
struct json_formatter_stack_entry_d {
- int size;
- bool is_array;
- json_formatter_stack_entry_d() : size(0), is_array(false) { }
+ int size = 0;
+ bool is_array = false;
};
- bool m_pretty;
+ bool m_pretty = false;
void open_section(std::string_view name, const char *ns, bool is_array);
void print_quoted_string(std::string_view s);
void print_name(std::string_view name);
void add_value(std::string_view name, T val);
void add_value(std::string_view name, std::string_view val, bool quoted);
- copyable_sstream m_ss;
- copyable_sstream m_pending_string;
+ mutable std::stringstream m_ss; // mutable for get_len
+ std::stringstream m_pending_string;
std::string m_pending_name;
std::vector<json_formatter_stack_entry_d> m_stack;
- bool m_is_pending_string;
+ bool m_is_pending_string = false;
bool m_line_break_enabled = false;
};
+ class JSONFormatterFile : public JSONFormatter {
+public:
+ JSONFormatterFile(const std::string& path, bool pretty=false) :
+ JSONFormatter(pretty),
+ path(path),
+ file(path, std::ios::out | std::ios::trunc)
+ {
+ }
+ ~JSONFormatterFile() {
+ file.flush();
+ }
+
+ void reset() override {
+ JSONFormatter::reset();
+ file = std::ofstream(path, std::ios::out | std::ios::trunc);
+ }
+ int get_len() const override {
+ return file.tellp();
+ }
+
+protected:
+ std::ostream& get_ss() override {
+ return file;
+ }
+
+private:
+ std::string path;
+ mutable std::ofstream file; // mutable for get_len
+ };
+
template <class T>
void add_value(std::string_view name, T val);