mirror of
https://github.com/ceph/ceph
synced 2024-12-22 19:34:30 +00:00
edbd6edb04
Fixes: http://tracker.ceph.com/issues/19883 (Partially) Signed-off-by: Jos Collin <jcollin@redhat.com>
232 lines
8.9 KiB
C++
232 lines
8.9 KiB
C++
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
|
// vim: ts=8 sw=2 smarttab
|
|
#ifndef CEPH_FORMATTER_H
|
|
#define CEPH_FORMATTER_H
|
|
|
|
#include "include/int_types.h"
|
|
#include "include/buffer_fwd.h"
|
|
|
|
#include <deque>
|
|
#include <list>
|
|
#include <vector>
|
|
#include <stdarg.h>
|
|
#include <sstream>
|
|
#include <map>
|
|
|
|
namespace ceph {
|
|
|
|
struct FormatterAttrs {
|
|
std::list< std::pair<std::string, std::string> > attrs;
|
|
|
|
FormatterAttrs(const char *attr, ...);
|
|
};
|
|
|
|
class Formatter {
|
|
public:
|
|
static Formatter *create(const std::string& type,
|
|
const std::string& default_type,
|
|
const std::string& fallback);
|
|
static Formatter *create(const std::string& type,
|
|
const std::string& default_type) {
|
|
return create(type, default_type, "");
|
|
}
|
|
static Formatter *create(const std::string& type) {
|
|
return create(type, "json-pretty", "");
|
|
}
|
|
|
|
Formatter();
|
|
virtual ~Formatter();
|
|
|
|
virtual void flush(std::ostream& os) = 0;
|
|
void flush(bufferlist &bl);
|
|
virtual void reset() = 0;
|
|
|
|
virtual void set_status(int status, const char* status_name) = 0;
|
|
virtual void output_header() = 0;
|
|
virtual void output_footer() = 0;
|
|
|
|
virtual void open_array_section(const char *name) = 0;
|
|
virtual void open_array_section_in_ns(const char *name, const char *ns) = 0;
|
|
virtual void open_object_section(const char *name) = 0;
|
|
virtual void open_object_section_in_ns(const char *name, const char *ns) = 0;
|
|
virtual void close_section() = 0;
|
|
virtual void dump_unsigned(const char *name, uint64_t u) = 0;
|
|
virtual void dump_int(const char *name, int64_t s) = 0;
|
|
virtual void dump_float(const char *name, double d) = 0;
|
|
virtual void dump_string(const char *name, const std::string& s) = 0;
|
|
virtual void dump_bool(const char *name, bool b)
|
|
{
|
|
dump_format_unquoted(name, "%s", (b ? "true" : "false"));
|
|
}
|
|
template<typename T>
|
|
void dump_object(const char *name, const T& foo) {
|
|
open_object_section(name);
|
|
foo.dump(this);
|
|
close_section();
|
|
}
|
|
virtual std::ostream& dump_stream(const char *name) = 0;
|
|
virtual void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) = 0;
|
|
virtual void dump_format(const char *name, const char *fmt, ...);
|
|
virtual void dump_format_ns(const char *name, const char *ns, const char *fmt, ...);
|
|
virtual void dump_format_unquoted(const char *name, const char *fmt, ...);
|
|
virtual int get_len() const = 0;
|
|
virtual void write_raw_data(const char *data) = 0;
|
|
/* with attrs */
|
|
virtual void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs)
|
|
{
|
|
open_array_section(name);
|
|
}
|
|
virtual void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs)
|
|
{
|
|
open_object_section(name);
|
|
}
|
|
virtual void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs)
|
|
{
|
|
dump_string(name, s);
|
|
}
|
|
};
|
|
|
|
class JSONFormatter : public Formatter {
|
|
public:
|
|
explicit JSONFormatter(bool p = false);
|
|
|
|
void set_status(int status, const char* status_name) override {};
|
|
void output_header() override {};
|
|
void output_footer() override {};
|
|
void flush(std::ostream& os) override;
|
|
using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
|
|
void reset() override;
|
|
void open_array_section(const char *name) override;
|
|
void open_array_section_in_ns(const char *name, const char *ns) override;
|
|
void open_object_section(const char *name) override;
|
|
void open_object_section_in_ns(const char *name, const char *ns) override;
|
|
void close_section() override;
|
|
void dump_unsigned(const char *name, uint64_t u) override;
|
|
void dump_int(const char *name, int64_t u) override;
|
|
void dump_float(const char *name, double d) override;
|
|
void dump_string(const char *name, const std::string& s) override;
|
|
std::ostream& dump_stream(const char *name) override;
|
|
void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
|
|
int get_len() const override;
|
|
void write_raw_data(const char *data) override;
|
|
|
|
private:
|
|
|
|
struct json_formatter_stack_entry_d {
|
|
int size;
|
|
bool is_array;
|
|
json_formatter_stack_entry_d() : size(0), is_array(false) { }
|
|
};
|
|
|
|
bool m_pretty;
|
|
void open_section(const char *name, bool is_array);
|
|
void print_quoted_string(const std::string& s);
|
|
void print_name(const char *name);
|
|
void print_comma(json_formatter_stack_entry_d& entry);
|
|
void finish_pending_string();
|
|
|
|
std::stringstream m_ss, m_pending_string;
|
|
std::list<json_formatter_stack_entry_d> m_stack;
|
|
bool m_is_pending_string;
|
|
};
|
|
|
|
class XMLFormatter : public Formatter {
|
|
public:
|
|
static const char *XML_1_DTD;
|
|
XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true);
|
|
|
|
void set_status(int status, const char* status_name) override {}
|
|
void output_header() override;
|
|
void output_footer() override;
|
|
|
|
void flush(std::ostream& os) override;
|
|
using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
|
|
void reset() override;
|
|
void open_array_section(const char *name) override;
|
|
void open_array_section_in_ns(const char *name, const char *ns) override;
|
|
void open_object_section(const char *name) override;
|
|
void open_object_section_in_ns(const char *name, const char *ns) override;
|
|
void close_section() override;
|
|
void dump_unsigned(const char *name, uint64_t u) override;
|
|
void dump_int(const char *name, int64_t u) override;
|
|
void dump_float(const char *name, double d) override;
|
|
void dump_string(const char *name, const std::string& s) override;
|
|
std::ostream& dump_stream(const char *name) override;
|
|
void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
|
|
int get_len() const override;
|
|
void write_raw_data(const char *data) override;
|
|
|
|
/* with attrs */
|
|
void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
|
|
void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
|
|
void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) override;
|
|
|
|
protected:
|
|
void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs);
|
|
void finish_pending_string();
|
|
void print_spaces();
|
|
static std::string escape_xml_str(const char *str);
|
|
void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
|
|
char to_lower_underscore(char c) const;
|
|
|
|
std::stringstream m_ss, m_pending_string;
|
|
std::deque<std::string> m_sections;
|
|
const bool m_pretty;
|
|
const bool m_lowercased;
|
|
const bool m_underscored;
|
|
std::string m_pending_string_name;
|
|
bool m_header_done;
|
|
};
|
|
|
|
class TableFormatter : public Formatter {
|
|
public:
|
|
explicit TableFormatter(bool keyval = false);
|
|
|
|
void set_status(int status, const char* status_name) override {};
|
|
void output_header() override {};
|
|
void output_footer() override {};
|
|
void flush(std::ostream& os) override;
|
|
using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
|
|
void reset() override;
|
|
void open_array_section(const char *name) override;
|
|
void open_array_section_in_ns(const char *name, const char *ns) override;
|
|
void open_object_section(const char *name) override;
|
|
void open_object_section_in_ns(const char *name, const char *ns) override;
|
|
|
|
void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
|
|
void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
|
|
|
|
void close_section() override;
|
|
void dump_unsigned(const char *name, uint64_t u) override;
|
|
void dump_int(const char *name, int64_t u) override;
|
|
void dump_float(const char *name, double d) override;
|
|
void dump_string(const char *name, const std::string& s) override;
|
|
void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
|
|
void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) override;
|
|
std::ostream& dump_stream(const char *name) override;
|
|
|
|
int get_len() const override;
|
|
void write_raw_data(const char *data) override;
|
|
void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
|
|
|
|
private:
|
|
void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs);
|
|
std::vector< std::vector<std::pair<std::string, std::string> > > m_vec;
|
|
std::stringstream m_ss;
|
|
size_t m_vec_index(const char* name);
|
|
std::string get_section_name(const char* name);
|
|
void finish_pending_string();
|
|
std::string m_pending_name;
|
|
bool m_keyval;
|
|
|
|
int m_section_open;
|
|
std::vector< std::string > m_section;
|
|
std::map<std::string, int> m_section_cnt;
|
|
std::vector<size_t> m_column_size;
|
|
std::vector< std::string > m_column_name;
|
|
};
|
|
|
|
|
|
}
|
|
#endif
|