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