]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_xml.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / rgw / rgw_xml.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_RGW_XML_H
5 #define CEPH_RGW_XML_H
6
7 #include <map>
8 #include <string>
9 #include <iosfwd>
10 #include <include/types.h>
11 #include <common/Formatter.h>
12
13 using namespace std;
14
15
16 class XMLObj;
17
18 class XMLObjIter {
19 typedef map<string, XMLObj *>::iterator map_iter_t;
20 map_iter_t cur;
21 map_iter_t end;
22 public:
23 XMLObjIter();
24 ~XMLObjIter();
25 void set(const XMLObjIter::map_iter_t &_cur, const XMLObjIter::map_iter_t &_end);
26 XMLObj *get_next();
27 };
28
29 /**
30 * Represents a block of XML.
31 * Give the class an XML blob, and it will parse the blob into
32 * an attr_name->value map.
33 * This really ought to be an abstract class or something; it
34 * shouldn't be the startpoint for any parsing. Look at RGWXMLParser for that.
35 */
36 class XMLObj
37 {
38 XMLObj *parent;
39 string obj_type;
40 protected:
41 string data;
42 multimap<string, XMLObj *> children;
43 map<string, string> attr_map;
44 public:
45
46 XMLObj() : parent(NULL) {}
47
48 virtual ~XMLObj();
49 bool xml_start(XMLObj *parent, const char *el, const char **attr);
50 virtual bool xml_end(const char *el);
51 virtual void xml_handle_data(const char *s, int len);
52 string& get_data();
53 XMLObj *get_parent();
54 void add_child(string el, XMLObj *obj);
55 bool get_attr(string name, string& attr);
56 XMLObjIter find(string name);
57 XMLObj *find_first(string name);
58
59 friend ostream& operator<<(ostream &out, const XMLObj &obj);
60 };
61
62 struct XML_ParserStruct;
63 class RGWXMLParser : public XMLObj
64 {
65 XML_ParserStruct *p;
66 char *buf;
67 int buf_len;
68 XMLObj *cur_obj;
69 vector<XMLObj *> objs;
70 list<XMLObj *> allocated_objs;
71 list<XMLObj> unallocated_objs;
72 protected:
73 virtual XMLObj *alloc_obj(const char *el) {
74 return NULL;
75 }
76 public:
77 RGWXMLParser();
78 ~RGWXMLParser() override;
79 bool init();
80 bool xml_start(const char *el, const char **attr);
81 bool xml_end(const char *el) override;
82 void handle_data(const char *s, int len);
83
84 bool parse(const char *buf, int len, int done);
85 const char *get_xml() { return buf; }
86 void set_failure() { success = false; }
87
88 private:
89 bool success;
90 };
91
92 class RGWXMLDecoder {
93 public:
94 struct err {
95 string message;
96
97 explicit err(const string& m) : message(m) {}
98 };
99
100 class XMLParser : public RGWXMLParser {
101 public:
102 XMLParser() {}
103 ~XMLParser() override {}
104 } parser;
105
106 explicit RGWXMLDecoder(bufferlist& bl) {
107 if (!parser.parse(bl.c_str(), bl.length(), 1)) {
108 cout << "RGWXMLDecoder::err()" << std::endl;
109 throw RGWXMLDecoder::err("failed to parse XML input");
110 }
111 }
112
113 template<class T>
114 static bool decode_xml(const char *name, T& val, XMLObj *obj, bool mandatory = false);
115
116 template<class C>
117 static bool decode_xml(const char *name, C& container, void (*cb)(C&, XMLObj *obj), XMLObj *obj, bool mandatory = false);
118
119 template<class T>
120 static void decode_xml(const char *name, T& val, T& default_val, XMLObj *obj);
121 };
122
123 template<class T>
124 void decode_xml_obj(T& val, XMLObj *obj)
125 {
126 val.decode_xml(obj);
127 }
128
129 static inline void decode_xml_obj(string& val, XMLObj *obj)
130 {
131 val = obj->get_data();
132 }
133
134 void decode_xml_obj(unsigned long long& val, XMLObj *obj);
135 void decode_xml_obj(long long& val, XMLObj *obj);
136 void decode_xml_obj(unsigned long& val, XMLObj *obj);
137 void decode_xml_obj(long& val, XMLObj *obj);
138 void decode_xml_obj(unsigned& val, XMLObj *obj);
139 void decode_xml_obj(int& val, XMLObj *obj);
140 void decode_xml_obj(bool& val, XMLObj *obj);
141 void decode_xml_obj(bufferlist& val, XMLObj *obj);
142 class utime_t;
143 void decode_xml_obj(utime_t& val, XMLObj *obj);
144
145 template<class T>
146 void do_decode_xml_obj(list<T>& l, const string& name, XMLObj *obj)
147 {
148 l.clear();
149
150 XMLObjIter iter = obj->find(name);
151 XMLObj *o;
152
153 while ((o = iter.get_next())) {
154 T val;
155 decode_xml_obj(val, o);
156 l.push_back(val);
157 }
158 }
159
160 template<class T>
161 void do_decode_xml_obj(vector<T>& l, const string& name, XMLObj *obj)
162 {
163 l.clear();
164
165 XMLObjIter iter = obj->find(name);
166 XMLObj *o;
167
168 while (o = iter.get_next()) {
169 T val;
170 decode_xml_obj(val, o);
171 l.push_back(val);
172 }
173 }
174
175 template<class T>
176 bool RGWXMLDecoder::decode_xml(const char *name, T& val, XMLObj *obj, bool mandatory)
177 {
178 XMLObjIter iter = obj->find(name);
179 XMLObj *o = iter.get_next();
180 if (!o) {
181 if (mandatory) {
182 string s = "missing mandatory field " + string(name);
183 throw err(s);
184 }
185 val = T();
186 return false;
187 }
188
189 try {
190 decode_xml_obj(val, o);
191 } catch (err& e) {
192 string s = string(name) + ": ";
193 s.append(e.message);
194 throw err(s);
195 }
196
197 return true;
198 }
199
200 template<class C>
201 bool RGWXMLDecoder::decode_xml(const char *name, C& container, void (*cb)(C&, XMLObj *), XMLObj *obj, bool mandatory)
202 {
203 container.clear();
204
205 XMLObjIter iter = obj->find(name);
206 XMLObj *o = iter.get_next();
207 if (!o) {
208 if (mandatory) {
209 string s = "missing mandatory field " + string(name);
210 throw err(s);
211 }
212 return false;
213 }
214
215 try {
216 decode_xml_obj(container, cb, o);
217 } catch (err& e) {
218 string s = string(name) + ": ";
219 s.append(e.message);
220 throw err(s);
221 }
222
223 return true;
224 }
225
226 template<class T>
227 void RGWXMLDecoder::decode_xml(const char *name, T& val, T& default_val, XMLObj *obj)
228 {
229 XMLObjIter iter = obj->find(name);
230 XMLObj *o = iter.get_next();
231 if (!o) {
232 val = default_val;
233 return;
234 }
235
236 try {
237 decode_xml_obj(val, o);
238 } catch (err& e) {
239 val = default_val;
240 string s = string(name) + ": ";
241 s.append(e.message);
242 throw err(s);
243 }
244 }
245
246 template<class T>
247 static void encode_xml(const char *name, const T& val, ceph::Formatter *f)
248 {
249 f->open_object_section(name);
250 val.dump_xml(f);
251 f->close_section();
252 }
253
254 void encode_xml(const char *name, const string& val, ceph::Formatter *f);
255 void encode_xml(const char *name, const char *val, ceph::Formatter *f);
256 void encode_xml(const char *name, bool val, ceph::Formatter *f);
257 void encode_xml(const char *name, int val, ceph::Formatter *f);
258 void encode_xml(const char *name, unsigned val, ceph::Formatter *f);
259 void encode_xml(const char *name, long val, ceph::Formatter *f);
260 void encode_xml(const char *name, unsigned long val, ceph::Formatter *f);
261 void encode_xml(const char *name, long long val, ceph::Formatter *f);
262 void encode_xml(const char *name, const utime_t& val, ceph::Formatter *f);
263 void encode_xml(const char *name, const bufferlist& bl, ceph::Formatter *f);
264 void encode_xml(const char *name, long long val, ceph::Formatter *f);
265 void encode_xml(const char *name, long long unsigned val, ceph::Formatter *f);
266
267 template<class T>
268 static void do_encode_xml(const char *name, const std::list<T>& l, const char *entry_name, ceph::Formatter *f)
269 {
270 f->open_array_section(name);
271 for (typename std::list<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
272 encode_xml(entry_name, *iter, f);
273 }
274 f->close_section();
275 }
276
277
278
279 #endif