summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_formats.h
blob: 10cc0debfe45d39c5eb3dc40b34e4e5ecb4508de (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
135
136
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#ifndef CEPH_RGW_FORMATS_H
#define CEPH_RGW_FORMATS_H

#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(ostream& os) override;
  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, std::string_view 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:
  void write_data(const char *fmt, ...);
  void dump_value_int(const char *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 {
  ostream& os;
protected:
  void do_flush() override {
    formatter->flush(os);
  }
public:
  RGWStreamFlusher(Formatter *f, ostream& _os) : RGWFormatterFlusher(f), os(_os) {}
};

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

#endif