summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_formats.h
blob: e645d3ec2cff4038fcdf6f9594218b8129756429 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp

#pragma once

#include "common/Formatter.h"

#include <list>
#include <stdint.h>
#include <string>
#include <ostream>

struct plain_stack_entry {
  int size;
  bool is_array;
};

/* FIXME: this class is mis-named.
 * FIXME: This was a hack to send certain swift messages.
 * There is a much better way to do this.
 */
class RGWFormatter_Plain : public Formatter {
  void reset_buf();
public:
  explicit RGWFormatter_Plain(bool use_kv = false);
  ~RGWFormatter_Plain() override;

  void set_status(int status, const char* status_name) override {};
  void output_header() override {};
  void output_footer() override {};
  void enable_line_break() override {};
  void flush(std::ostream& os) override;
  void reset() override;

  void open_array_section(std::string_view name) override;
  void open_array_section_in_ns(std::string_view name, const char *ns) override;
  void open_object_section(std::string_view name) override;
  void open_object_section_in_ns(std::string_view name, const char *ns) override;
  void close_section() override;
  void dump_null(std::string_view name) override;
  void dump_unsigned(std::string_view name, uint64_t u) override;
  void dump_int(std::string_view name, int64_t u) override;
  void dump_float(std::string_view name, double d) override;
  void dump_string(std::string_view name, std::string_view s) override;
  std::ostream& dump_stream(std::string_view name) override;
  void dump_format_va(std::string_view 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:
  void write_data(const char *fmt, ...);
  void dump_value_int(std::string_view name, const char *fmt, ...);

  char *buf = nullptr;
  int len = 0;
  int max_len = 0;

  std::list<struct plain_stack_entry> stack;
  size_t min_stack_level = 0;
  bool use_kv;
  bool wrote_something = 0;
};


/* This is a presentation layer. No logic inside, please. */
class RGWSwiftWebsiteListingFormatter {
  std::ostream& ss;
  const std::string prefix;
protected:
  std::string format_name(const std::string& item_name) const;
public:
  RGWSwiftWebsiteListingFormatter(std::ostream& ss,
                                  std::string prefix)
    : ss(ss),
      prefix(std::move(prefix)) {
  }

  /* The supplied css_path can be empty. In such situation a default,
   * embedded style sheet will be generated. */
  void generate_header(const std::string& dir_path,
                       const std::string& css_path);
  void generate_footer();
  void dump_object(const rgw_bucket_dir_entry& objent);
  void dump_subdir(const std::string& name);
};


class RGWFormatterFlusher {
protected:
  Formatter *formatter;
  bool flushed;
  bool started;
  virtual void do_flush() = 0;
  virtual void do_start(int ret) {}
  void set_formatter(Formatter *f) {
    formatter = f;
  }
public:
  explicit RGWFormatterFlusher(Formatter *f) : formatter(f), flushed(false), started(false) {}
  virtual ~RGWFormatterFlusher() {}

  void flush() {
    do_flush();
    flushed = true;
  }

  virtual void start(int client_ret) {
    if (!started)
      do_start(client_ret);
    started = true;
  }

  Formatter *get_formatter() { return formatter; }
  bool did_flush() { return flushed; }
  bool did_start() { return started; }
};

class RGWStreamFlusher : public RGWFormatterFlusher {
  std::ostream& os;
protected:
  void do_flush() override {
    formatter->flush(os);
  }
public:
  RGWStreamFlusher(Formatter *f, std::ostream& _os) : RGWFormatterFlusher(f), os(_os) {}
};

class RGWNullFlusher : public RGWFormatterFlusher {
protected:
  void do_flush() override {
  }
public:
  RGWNullFlusher() : RGWFormatterFlusher(nullptr) {}
};