1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
11 #include "include/types.h"
13 #include "rgw_common.h"
16 #define dout_subsys ceph_subsys_rgw
31 set(const XMLObjIter::map_iter_t &_cur, const XMLObjIter::map_iter_t &_end)
48 ostream& operator<<(ostream &out, const XMLObj &obj) {
49 out << obj.obj_type << ": " << obj.data;
59 xml_start(XMLObj *parent, const char *el, const char **attr)
61 this->parent = parent;
63 for (int i = 0; attr[i]; i += 2) {
64 attr_map[attr[i]] = string(attr[i + 1]);
70 xml_end(const char *el)
76 xml_handle_data(const char *s, int len)
94 add_child(string el, XMLObj *obj)
96 children.insert(pair<string, XMLObj *>(el, obj));
100 get_attr(string name, string& attr)
102 map<string, string>::iterator iter = attr_map.find(name);
103 if (iter == attr_map.end())
113 map<string, XMLObj *>::iterator first;
114 map<string, XMLObj *>::iterator last;
115 first = children.find(name);
116 if (first != children.end()) {
117 last = children.upper_bound(name);
119 last = children.end();
120 iter.set(first, last);
125 find_first(string name)
128 map<string, XMLObj *>::iterator first;
129 first = children.find(name);
130 if (first != children.end())
131 return first->second;
134 static void xml_start(void *data, const char *el, const char **attr) {
135 RGWXMLParser *handler = static_cast<RGWXMLParser *>(data);
137 if (!handler->xml_start(el, attr))
138 handler->set_failure();
142 RGWXMLParser() : buf(NULL), buf_len(0), cur_obj(NULL), success(true)
144 p = XML_ParserCreate(NULL);
153 list<XMLObj *>::iterator iter;
154 for (iter = allocated_objs.begin(); iter != allocated_objs.end(); ++iter) {
161 bool RGWXMLParser::xml_start(const char *el, const char **attr) {
162 XMLObj * obj = alloc_obj(el);
164 unallocated_objs.push_back(XMLObj());
165 obj = &unallocated_objs.back();
167 allocated_objs.push_back(obj);
169 if (!obj->xml_start(cur_obj, el, attr))
172 cur_obj->add_child(el, obj);
174 children.insert(pair<string, XMLObj *>(el, obj));
182 static void xml_end(void *data, const char *el) {
183 RGWXMLParser *handler = static_cast<RGWXMLParser *>(data);
185 if (!handler->xml_end(el))
186 handler->set_failure();
189 bool RGWXMLParser::xml_end(const char *el) {
190 XMLObj *parent_obj = cur_obj->get_parent();
191 if (!cur_obj->xml_end(el))
193 cur_obj = parent_obj;
197 static void handle_data(void *data, const char *s, int len)
199 RGWXMLParser *handler = static_cast<RGWXMLParser *>(data);
201 handler->handle_data(s, len);
204 void RGWXMLParser::handle_data(const char *s, int len)
206 cur_obj->xml_handle_data(s, len);
210 bool RGWXMLParser::init()
215 XML_SetElementHandler(p, ::xml_start, ::xml_end);
216 XML_SetCharacterDataHandler(p, ::handle_data);
217 XML_SetUserData(p, (void *)this);
221 bool RGWXMLParser::parse(const char *_buf, int len, int done)
225 tmp_buf = (char *)realloc(buf, buf_len + len);
226 if (tmp_buf == NULL){
234 memcpy(&buf[buf_len], _buf, len);
238 if (!XML_Parse(p, &buf[pos], len, done)) {
239 fprintf(stderr, "Parse error at line %d:\n%s\n",
240 (int)XML_GetCurrentLineNumber(p),
241 XML_ErrorString(XML_GetErrorCode(p)));
248 void decode_xml_obj(unsigned long& val, XMLObj *obj)
250 string& s = obj->get_data();
251 const char *start = s.c_str();
255 val = strtoul(start, &p, 10);
257 /* Check for various possible errors */
259 if ((errno == ERANGE && val == ULONG_MAX) ||
260 (errno != 0 && val == 0)) {
261 throw RGWXMLDecoder::err("failed to number");
265 throw RGWXMLDecoder::err("failed to parse number");
270 throw RGWXMLDecoder::err("failed to parse number");
277 void decode_xml_obj(long& val, XMLObj *obj)
279 string s = obj->get_data();
280 const char *start = s.c_str();
284 val = strtol(start, &p, 10);
286 /* Check for various possible errors */
288 if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
289 (errno != 0 && val == 0)) {
290 throw RGWXMLDecoder::err("failed to parse number");
294 throw RGWXMLDecoder::err("failed to parse number");
299 throw RGWXMLDecoder::err("failed to parse number");
305 void decode_xml_obj(long long& val, XMLObj *obj)
307 string s = obj->get_data();
308 const char *start = s.c_str();
312 val = strtoll(start, &p, 10);
314 /* Check for various possible errors */
316 if ((errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN)) ||
317 (errno != 0 && val == 0)) {
318 throw RGWXMLDecoder::err("failed to parse number");
322 throw RGWXMLDecoder::err("failed to parse number");
327 throw RGWXMLDecoder::err("failed to parse number");
333 void decode_xml_obj(unsigned long long& val, XMLObj *obj)
335 string s = obj->get_data();
336 const char *start = s.c_str();
340 val = strtoull(start, &p, 10);
342 /* Check for various possible errors */
344 if ((errno == ERANGE && val == ULLONG_MAX) ||
345 (errno != 0 && val == 0)) {
346 throw RGWXMLDecoder::err("failed to number");
350 throw RGWXMLDecoder::err("failed to parse number");
355 throw RGWXMLDecoder::err("failed to parse number");
361 void decode_xml_obj(int& val, XMLObj *obj)
364 decode_xml_obj(l, obj);
365 #if LONG_MAX > INT_MAX
366 if (l > INT_MAX || l < INT_MIN) {
367 throw RGWXMLDecoder::err("integer out of range");
374 void decode_xml_obj(unsigned& val, XMLObj *obj)
377 decode_xml_obj(l, obj);
378 #if ULONG_MAX > UINT_MAX
380 throw RGWXMLDecoder::err("unsigned integer out of range");
387 void decode_xml_obj(bool& val, XMLObj *obj)
389 string s = obj->get_data();
390 if (strcasecmp(s.c_str(), "true") == 0) {
394 if (strcasecmp(s.c_str(), "false") == 0) {
399 decode_xml_obj(i, obj);
403 void decode_xml_obj(bufferlist& val, XMLObj *obj)
405 string s = obj->get_data();
408 bl.append(s.c_str(), s.size());
410 val.decode_base64(bl);
411 } catch (buffer::error& err) {
412 throw RGWXMLDecoder::err("failed to decode base64");
416 void decode_xml_obj(utime_t& val, XMLObj *obj)
418 string s = obj->get_data();
421 int r = utime_t::parse_date(s, &epoch, &nsec);
423 val = utime_t(epoch, nsec);
425 throw RGWXMLDecoder::err("failed to decode utime_t");
429 void encode_xml(const char *name, const string& val, Formatter *f)
431 f->dump_string(name, val);
434 void encode_xml(const char *name, const char *val, Formatter *f)
436 f->dump_string(name, val);
439 void encode_xml(const char *name, bool val, Formatter *f)
447 f->dump_string(name, s);
450 void encode_xml(const char *name, int val, Formatter *f)
452 f->dump_int(name, val);
455 void encode_xml(const char *name, long val, Formatter *f)
457 f->dump_int(name, val);
460 void encode_xml(const char *name, unsigned val, Formatter *f)
462 f->dump_unsigned(name, val);
465 void encode_xml(const char *name, unsigned long val, Formatter *f)
467 f->dump_unsigned(name, val);
470 void encode_xml(const char *name, unsigned long long val, Formatter *f)
472 f->dump_unsigned(name, val);
475 void encode_xml(const char *name, long long val, Formatter *f)
477 f->dump_int(name, val);
480 void encode_xml(const char *name, const utime_t& val, Formatter *f)
482 val.gmtime(f->dump_stream(name));
485 void encode_xml(const char *name, const bufferlist& bl, Formatter *f)
487 /* need to copy data from bl, as it is const bufferlist */
491 src.encode_base64(b64);
493 string s(b64.c_str(), b64.length());
495 encode_xml(name, s, f);