XmlRpcValue.cpp
Go to the documentation of this file.
1 
2 #include "xmlrpcpp/XmlRpcValue.h"
4 #include "xmlrpcpp/XmlRpcUtil.h"
5 
6 #include <b64/encode.h>
7 #include <b64/decode.h>
8 
9 #ifndef MAKEDEPEND
10 # include <iostream>
11 # include <ostream>
12 # include <stdlib.h>
13 # include <stdio.h>
14 #endif
15 
16 #include <sstream>
17 #include <mutex>
18 #include <vector>
19 
20 namespace XmlRpc {
21 
22 
23  static const char VALUE_TAG[] = "<value>";
24  static const char VALUE_ETAG[] = "</value>";
25 
26  static const char BOOLEAN_TAG[] = "<boolean>";
27  static const char BOOLEAN_ETAG[] = "</boolean>";
28  static const char DOUBLE_TAG[] = "<double>";
29  static const char DOUBLE_ETAG[] = "</double>";
30  static const char INT_TAG[] = "<int>";
31  static const char I4_TAG[] = "<i4>";
32  static const char I4_ETAG[] = "</i4>";
33  static const char STRING_TAG[] = "<string>";
34  static const char DATETIME_TAG[] = "<dateTime.iso8601>";
35  static const char DATETIME_ETAG[] = "</dateTime.iso8601>";
36  static const char BASE64_TAG[] = "<base64>";
37  static const char BASE64_ETAG[] = "</base64>";
38 
39  static const char ARRAY_TAG[] = "<array>";
40  static const char DATA_TAG[] = "<data>";
41  static const char DATA_ETAG[] = "</data>";
42  static const char ARRAY_ETAG[] = "</array>";
43 
44  static const char STRUCT_TAG[] = "<struct>";
45  static const char MEMBER_TAG[] = "<member>";
46  static const char NAME_TAG[] = "<name>";
47  static const char NAME_ETAG[] = "</name>";
48  static const char MEMBER_ETAG[] = "</member>";
49  static const char STRUCT_ETAG[] = "</struct>";
50 
51 
52 
53  // Format strings
54  std::string XmlRpcValue::_doubleFormat("%.16g");
55 
56 
57 
58  // Clean up
60  {
61  switch (_type) {
62  case TypeString: delete _value.asString; break;
63  case TypeDateTime: delete _value.asTime; break;
64  case TypeBase64: delete _value.asBinary; break;
65  case TypeArray: delete _value.asArray; break;
66  case TypeStruct: delete _value.asStruct; break;
67  default: break;
68  }
70  _value.asBinary = 0;
71  }
72 
73 
74  // Type checking
76  {
77  if (_type != t)
78  throw XmlRpcException("type error");
79  }
80 
82  {
83  if (_type == TypeInvalid)
84  {
85  _type = t;
86  switch (_type) { // Ensure there is a valid value for the type
87  case TypeString: _value.asString = new std::string(); break;
88  case TypeDateTime: _value.asTime = new struct tm(); break;
89  case TypeBase64: _value.asBinary = new BinaryData(); break;
90  case TypeArray: _value.asArray = new ValueArray(); break;
91  case TypeStruct: _value.asStruct = new ValueStruct(); break;
92  default: _value.asBinary = 0; break;
93  }
94  }
95  else if (_type != t)
96  throw XmlRpcException("type error");
97  }
98 
99  void XmlRpcValue::assertArray(int size) const
100  {
101  if (_type != TypeArray)
102  throw XmlRpcException("type error: expected an array");
103  else if (int(_value.asArray->size()) < size)
104  throw XmlRpcException("range error: array index too large");
105  }
106 
107 
109  {
110  if (_type == TypeInvalid) {
111  _type = TypeArray;
112  _value.asArray = new ValueArray(size);
113  } else if (_type == TypeArray) {
114  if (int(_value.asArray->size()) < size)
115  _value.asArray->resize(size);
116  } else
117  throw XmlRpcException("type error: expected an array");
118  }
119 
121  {
122  if (_type != TypeStruct)
123  throw XmlRpcException("type error: expected a struct");
124  }
125 
127  {
128  if (_type == TypeInvalid) {
129  _type = TypeStruct;
130  _value.asStruct = new ValueStruct();
131  } else if (_type != TypeStruct)
132  throw XmlRpcException("type error: expected a struct");
133  }
134 
135 
136  // Operators
138  {
139  if (this != &rhs)
140  {
141  invalidate();
142  _type = rhs._type;
143  switch (_type) {
144  case TypeBoolean: _value.asBool = rhs._value.asBool; break;
145  case TypeInt: _value.asInt = rhs._value.asInt; break;
146  case TypeDouble: _value.asDouble = rhs._value.asDouble; break;
147  case TypeDateTime: _value.asTime = new struct tm(*rhs._value.asTime); break;
148  case TypeString: _value.asString = new std::string(*rhs._value.asString); break;
149  case TypeBase64: _value.asBinary = new BinaryData(*rhs._value.asBinary); break;
150  case TypeArray: _value.asArray = new ValueArray(*rhs._value.asArray); break;
151  case TypeStruct: _value.asStruct = new ValueStruct(*rhs._value.asStruct); break;
152  default: _value.asBinary = 0; break;
153  }
154  }
155  return *this;
156  }
157 
158 
159  // Predicate for tm equality
160  static bool tmEq(struct tm const& t1, struct tm const& t2) {
161  return t1.tm_sec == t2.tm_sec && t1.tm_min == t2.tm_min &&
162  t1.tm_hour == t2.tm_hour && t1.tm_mday == t2.tm_mday &&
163  t1.tm_mon == t2.tm_mon && t1.tm_year == t2.tm_year;
164  }
165 
166  bool XmlRpcValue::operator==(XmlRpcValue const& other) const
167  {
168  if (_type != other._type)
169  return false;
170 
171  switch (_type) {
172  case TypeBoolean: return ( !_value.asBool && !other._value.asBool) ||
173  ( _value.asBool && other._value.asBool);
174  case TypeInt: return _value.asInt == other._value.asInt;
175  case TypeDouble: return _value.asDouble == other._value.asDouble;
176  case TypeDateTime: return tmEq(*_value.asTime, *other._value.asTime);
177  case TypeString: return *_value.asString == *other._value.asString;
178  case TypeBase64: return *_value.asBinary == *other._value.asBinary;
179  case TypeArray: return *_value.asArray == *other._value.asArray;
180 
181  // The map<>::operator== requires the definition of value< for kcc
182  case TypeStruct: //return *_value.asStruct == *other._value.asStruct;
183  {
184  if (_value.asStruct->size() != other._value.asStruct->size())
185  return false;
186 
187  ValueStruct::const_iterator it1=_value.asStruct->begin();
188  ValueStruct::const_iterator it2=other._value.asStruct->begin();
189  while (it1 != _value.asStruct->end()) {
190  const XmlRpcValue& v1 = it1->second;
191  const XmlRpcValue& v2 = it2->second;
192  if ( ! (v1 == v2))
193  return false;
194  it1++;
195  it2++;
196  }
197  return true;
198  }
199  default: break;
200  }
201  return true; // Both invalid values ...
202  }
203 
204  bool XmlRpcValue::operator!=(XmlRpcValue const& other) const
205  {
206  return !(*this == other);
207  }
208 
209 
210  // Works for strings, binary data, arrays, and structs.
211  int XmlRpcValue::size() const
212  {
213  switch (_type) {
214  case TypeString: return int(_value.asString->size());
215  case TypeBase64: return int(_value.asBinary->size());
216  case TypeArray: return int(_value.asArray->size());
217  case TypeStruct: return int(_value.asStruct->size());
218  default: break;
219  }
220 
221  throw XmlRpcException("type error");
222  }
223 
224  // Checks for existence of struct member
225  bool XmlRpcValue::hasMember(const std::string& name) const
226  {
227  return _type == TypeStruct && _value.asStruct->find(name) != _value.asStruct->end();
228  }
229 
230  // Set the value from xml. The chars at *offset into valueXml
231  // should be the start of a <value> tag. Destroys any existing value.
232  bool XmlRpcValue::fromXml(std::string const& valueXml, int* offset)
233  {
234  int savedOffset = *offset;
235 
236  invalidate();
237  if ( ! XmlRpcUtil::nextTagIs(VALUE_TAG, valueXml, offset))
238  return false; // Not a value, offset not updated
239 
240  int afterValueOffset = *offset;
241  std::string typeTag = XmlRpcUtil::getNextTag(valueXml, offset);
242  bool result = false;
243  if (typeTag == BOOLEAN_TAG)
244  result = boolFromXml(valueXml, offset);
245  else if (typeTag == I4_TAG || typeTag == INT_TAG)
246  result = intFromXml(valueXml, offset);
247  else if (typeTag == DOUBLE_TAG)
248  result = doubleFromXml(valueXml, offset);
249  else if (typeTag.empty() || typeTag == STRING_TAG)
250  result = stringFromXml(valueXml, offset);
251  else if (typeTag == DATETIME_TAG)
252  result = timeFromXml(valueXml, offset);
253  else if (typeTag == BASE64_TAG)
254  result = binaryFromXml(valueXml, offset);
255  else if (typeTag == ARRAY_TAG)
256  result = arrayFromXml(valueXml, offset);
257  else if (typeTag == STRUCT_TAG)
258  result = structFromXml(valueXml, offset);
259  // Watch for empty/blank strings with no <string>tag
260  else if (typeTag == VALUE_ETAG)
261  {
262  *offset = afterValueOffset; // back up & try again
263  result = stringFromXml(valueXml, offset);
264  }
265 
266  if (result) // Skip over the </value> tag
267  XmlRpcUtil::findTag(VALUE_ETAG, valueXml, offset);
268  else // Unrecognized tag after <value>
269  *offset = savedOffset;
270 
271  return result;
272  }
273 
274  // Encode the Value in xml
275  std::string XmlRpcValue::toXml() const
276  {
277  switch (_type) {
278  case TypeBoolean: return boolToXml();
279  case TypeInt: return intToXml();
280  case TypeDouble: return doubleToXml();
281  case TypeString: return stringToXml();
282  case TypeDateTime: return timeToXml();
283  case TypeBase64: return binaryToXml();
284  case TypeArray: return arrayToXml();
285  case TypeStruct: return structToXml();
286  default: break;
287  }
288  return std::string(); // Invalid value
289  }
290 
291 
292  // Boolean
293  bool XmlRpcValue::boolFromXml(std::string const& valueXml, int* offset)
294  {
295  const char* valueStart = valueXml.c_str() + *offset;
296  char* valueEnd;
297  long ivalue = strtol(valueStart, &valueEnd, 10);
298  if (valueEnd == valueStart || (ivalue != 0 && ivalue != 1))
299  return false;
300 
301  _type = TypeBoolean;
302  _value.asBool = (ivalue == 1);
303  *offset += int(valueEnd - valueStart);
304  return true;
305  }
306 
307  std::string XmlRpcValue::boolToXml() const
308  {
309  std::string xml = VALUE_TAG;
310  xml += BOOLEAN_TAG;
311  xml += (_value.asBool ? "1" : "0");
312  xml += BOOLEAN_ETAG;
313  xml += VALUE_ETAG;
314  return xml;
315  }
316 
317  // Int
318  bool XmlRpcValue::intFromXml(std::string const& valueXml, int* offset)
319  {
320  const char* valueStart = valueXml.c_str() + *offset;
321  char* valueEnd;
322  long ivalue = strtol(valueStart, &valueEnd, 10);
323  if (valueEnd == valueStart)
324  return false;
325 
326  _type = TypeInt;
327  _value.asInt = int(ivalue);
328  *offset += int(valueEnd - valueStart);
329  return true;
330  }
331 
332  std::string XmlRpcValue::intToXml() const
333  {
334  char buf[256];
335  std::snprintf(buf, sizeof(buf)-1, "%d", _value.asInt);
336  buf[sizeof(buf)-1] = 0;
337  std::string xml = VALUE_TAG;
338  xml += I4_TAG;
339  xml += buf;
340  xml += I4_ETAG;
341  xml += VALUE_ETAG;
342  return xml;
343  }
344 
345  // Double
346  bool XmlRpcValue::doubleFromXml(std::string const& valueXml, int* offset)
347  {
348  const char* valueStart = valueXml.c_str() + *offset;
349  char* valueEnd;
350 
351  // ticket #2438
352  // push/pop the locale here. Value 123.45 can get read by strtod
353  // as '123', if the locale expects a comma instead of dot.
354  // if there are locale problems, silently continue.
355  std::string tmplocale;
356  char* locale_cstr = setlocale(LC_NUMERIC, 0);
357  if (locale_cstr)
358  {
359  tmplocale = locale_cstr;
360  setlocale(LC_NUMERIC, "POSIX");
361  }
362 
363  double dvalue = strtod(valueStart, &valueEnd);
364 
365  if (tmplocale.size() > 0) {
366  setlocale(LC_NUMERIC, tmplocale.c_str());
367  }
368 
369  if (valueEnd == valueStart)
370  return false;
371 
372  _type = TypeDouble;
373  _value.asDouble = dvalue;
374  *offset += int(valueEnd - valueStart);
375  return true;
376  }
377 
378  std::string XmlRpcValue::doubleToXml() const
379  {
380  // ticket #2438
381  std::stringstream ss;
382  ss.imbue(std::locale::classic()); // ensure we're using "C" locale for formatting floating-point (1.4 vs. 1,4, etc.)
383  ss.precision(17);
384  ss << _value.asDouble;
385 
386  std::string xml = VALUE_TAG;
387  xml += DOUBLE_TAG;
388  xml += ss.str();
389  xml += DOUBLE_ETAG;
390  xml += VALUE_ETAG;
391  return xml;
392  }
393 
394  // String
395  bool XmlRpcValue::stringFromXml(std::string const& valueXml, int* offset)
396  {
397  size_t valueEnd = valueXml.find('<', *offset);
398  if (valueEnd == std::string::npos)
399  return false; // No end tag;
400 
401  _type = TypeString;
402  _value.asString = new std::string(XmlRpcUtil::xmlDecode(valueXml.substr(*offset, valueEnd-*offset)));
403  *offset += int(_value.asString->length());
404  return true;
405  }
406 
407  std::string XmlRpcValue::stringToXml() const
408  {
409  std::string xml = VALUE_TAG;
410  //xml += STRING_TAG; optional
411  xml += XmlRpcUtil::xmlEncode(*_value.asString);
412  //xml += STRING_ETAG;
413  xml += VALUE_ETAG;
414  return xml;
415  }
416 
417  // DateTime (stored as a struct tm)
418  bool XmlRpcValue::timeFromXml(std::string const& valueXml, int* offset)
419  {
420  size_t valueEnd = valueXml.find('<', *offset);
421  if (valueEnd == std::string::npos)
422  return false; // No end tag;
423 
424  std::string stime = valueXml.substr(*offset, valueEnd-*offset);
425 
426  struct tm t;
427 #ifdef _MSC_VER
428  if (sscanf_s(stime.c_str(),"%4d%2d%2dT%2d:%2d:%2d",&t.tm_year,&t.tm_mon,&t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec) != 6)
429 #else
430  if (sscanf(stime.c_str(),"%4d%2d%2dT%2d:%2d:%2d",&t.tm_year,&t.tm_mon,&t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec) != 6)
431 #endif
432  return false;
433 
434  t.tm_isdst = -1;
436  _value.asTime = new struct tm(t);
437  *offset += int(stime.length());
438  return true;
439  }
440 
441  std::string XmlRpcValue::timeToXml() const
442  {
443  struct tm* t = _value.asTime;
444  char buf[20];
445  std::snprintf(buf, sizeof(buf)-1, "%4d%02d%02dT%02d:%02d:%02d",
446  t->tm_year,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
447  buf[sizeof(buf)-1] = 0;
448 
449  std::string xml = VALUE_TAG;
450  xml += DATETIME_TAG;
451  xml += buf;
452  xml += DATETIME_ETAG;
453  xml += VALUE_ETAG;
454  return xml;
455  }
456 
457  namespace {
458  std::size_t base64EncodedSize(std::size_t raw_size)
459  {
460  // encoder will still write to output buffer for empty input.
461  if (raw_size == 0) return 1;
462 
463  // 4 encoded character per 3 input bytes, rounded up,
464  // plus a newline character per 72 output characters, rounded up.
465  std::size_t encoded = (raw_size + 2) / 3 * 4;
466  encoded += (encoded + 71) / 72;
467  return encoded;
468  }
469 
470  std::size_t base64DecodedSize(std::size_t encoded_size)
471  {
472  // decoded will still write to output buffer for empty input.
473  if (encoded_size == 0) return 1;
474 
475  // 3 decoded bytes per 4 encoded characters, rounded up just to be sure.
476  return (encoded_size + 3) / 4 * 3;
477  }
478 
479  }
480 
481  // Base64
482  bool XmlRpcValue::binaryFromXml(std::string const& valueXml, int* offset)
483  {
484  size_t valueEnd = valueXml.find('<', *offset);
485  if (valueEnd == std::string::npos)
486  return false; // No end tag;
487 
488  std::size_t encoded_size = valueEnd - *offset;
489 
490 
491  _type = TypeBase64;
492  // might reserve too much, we'll shrink later
493  _value.asBinary = new BinaryData(base64DecodedSize(encoded_size), '\0');
494 
495  base64::decoder decoder;
496  std::size_t size = decoder.decode(&valueXml[*offset], encoded_size, &(*_value.asBinary)[0]);
497  _value.asBinary->resize(size);
498 
499  *offset += encoded_size;
500  return true;
501  }
502 
503  std::string XmlRpcValue::binaryToXml() const
504  {
505  // Wrap with xml
506  std::string xml = VALUE_TAG;
507  xml += BASE64_TAG;
508 
509  std::size_t offset = xml.size();
510  // might reserve too much, we'll shrink later
511  xml.resize(xml.size() + base64EncodedSize(_value.asBinary->size()));
512 
513  base64::encoder encoder;
514  offset += encoder.encode(_value.asBinary->data(), _value.asBinary->size(), &xml[offset]);
515  offset += encoder.encode_end(&xml[offset]);
516  xml.resize(offset);
517 
518  xml += BASE64_ETAG;
519  xml += VALUE_ETAG;
520  return xml;
521  }
522 
523 
524  // Array
525  bool XmlRpcValue::arrayFromXml(std::string const& valueXml, int* offset)
526  {
527  if ( ! XmlRpcUtil::nextTagIs(DATA_TAG, valueXml, offset))
528  return false;
529 
530  _type = TypeArray;
531  _value.asArray = new ValueArray;
532  XmlRpcValue v;
533  while (v.fromXml(valueXml, offset))
534  _value.asArray->push_back(v); // copy...
535 
536  // Skip the trailing </data>
537  (void) XmlRpcUtil::nextTagIs(DATA_ETAG, valueXml, offset);
538  return true;
539  }
540 
541 
542  // In general, its preferable to generate the xml of each element of the
543  // array as it is needed rather than glomming up one big string.
544  std::string XmlRpcValue::arrayToXml() const
545  {
546  std::string xml = VALUE_TAG;
547  xml += ARRAY_TAG;
548  xml += DATA_TAG;
549 
550  int s = int(_value.asArray->size());
551  for (int i=0; i<s; ++i)
552  xml += _value.asArray->at(i).toXml();
553 
554  xml += DATA_ETAG;
555  xml += ARRAY_ETAG;
556  xml += VALUE_ETAG;
557  return xml;
558  }
559 
560 
561  // Struct
562  bool XmlRpcValue::structFromXml(std::string const& valueXml, int* offset)
563  {
564  _type = TypeStruct;
565  _value.asStruct = new ValueStruct;
566 
567  while (XmlRpcUtil::nextTagIs(MEMBER_TAG, valueXml, offset)) {
568  // name
569  const std::string name = XmlRpcUtil::parseTag(NAME_TAG, valueXml, offset);
570  // value
571  XmlRpcValue val(valueXml, offset);
572  if ( ! val.valid()) {
573  invalidate();
574  return false;
575  }
576  const std::pair<const std::string, XmlRpcValue> p(name, val);
577  _value.asStruct->insert(p);
578 
579  (void) XmlRpcUtil::nextTagIs(MEMBER_ETAG, valueXml, offset);
580  }
581  return true;
582  }
583 
584 
585  // In general, its preferable to generate the xml of each element
586  // as it is needed rather than glomming up one big string.
587  std::string XmlRpcValue::structToXml() const
588  {
589  std::string xml = VALUE_TAG;
590  xml += STRUCT_TAG;
591 
592  ValueStruct::const_iterator it;
593  for (it=_value.asStruct->begin(); it!=_value.asStruct->end(); ++it) {
594  xml += MEMBER_TAG;
595  xml += NAME_TAG;
596  xml += XmlRpcUtil::xmlEncode(it->first);
597  xml += NAME_ETAG;
598  xml += it->second.toXml();
599  xml += MEMBER_ETAG;
600  }
601 
602  xml += STRUCT_ETAG;
603  xml += VALUE_ETAG;
604  return xml;
605  }
606 
607 
608 
609  // Write the value without xml encoding it
610  std::ostream& XmlRpcValue::write(std::ostream& os) const {
611  switch (_type) {
612  default: break;
613  case TypeBoolean: os << _value.asBool; break;
614  case TypeInt: os << _value.asInt; break;
615  case TypeDouble:
616  {
617  static std::once_flag once;
618  char buf[128]; // Should be long enough
619  int required_size = std::snprintf(buf, sizeof(buf)-1,
620  getDoubleFormat().c_str(), _value.asDouble);
621  if (required_size < 0) {
622  std::call_once(once,
623  [](){XmlRpcUtil::error("Failed to format with %s", getDoubleFormat().c_str());});
624  os << _value.asDouble;
625  } else if (required_size < static_cast<int>(sizeof(buf))) {
626  buf[sizeof(buf)-1] = 0;
627  os << buf;
628  } else { // required_size >= static_cast<int>(sizeof(buf)
629  std::vector<char> required_buf(required_size+1);
630  std::snprintf(required_buf.data(), required_size,
631  getDoubleFormat().c_str(), _value.asDouble);
632  required_buf[required_size] = 0;
633  os << required_buf.data();
634  }
635  break;
636  }
637  case TypeString: os << *_value.asString; break;
638  case TypeDateTime:
639  {
640  struct tm* t = _value.asTime;
641  char buf[20];
642  std::snprintf(buf, sizeof(buf)-1, "%4d%02d%02dT%02d:%02d:%02d",
643  t->tm_year,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
644  buf[sizeof(buf)-1] = 0;
645  os << buf;
646  break;
647  }
648  case TypeBase64:
649  {
650  std::stringstream buffer;
651  buffer.write(_value.asBinary->data(), _value.asBinary->size());
652  base64::encoder encoder;
653  encoder.encode(buffer, os);
654  break;
655  }
656  case TypeArray:
657  {
658  int s = int(_value.asArray->size());
659  os << '{';
660  for (int i=0; i<s; ++i)
661  {
662  if (i > 0) os << ',';
663  _value.asArray->at(i).write(os);
664  }
665  os << '}';
666  break;
667  }
668  case TypeStruct:
669  {
670  os << '[';
671  ValueStruct::const_iterator it;
672  for (it=_value.asStruct->begin(); it!=_value.asStruct->end(); ++it)
673  {
674  if (it!=_value.asStruct->begin()) os << ',';
675  os << it->first << ':';
676  it->second.write(os);
677  }
678  os << ']';
679  break;
680  }
681 
682  }
683 
684  return os;
685  }
686 
687 } // namespace XmlRpc
688 
689 
690 // ostream
691 std::ostream& operator<<(std::ostream& os, const XmlRpc::XmlRpcValue& v)
692 {
693  // If you want to output in xml format:
694  //return os << v.toXml();
695  return v.write(os);
696 }
697 
XmlRpc::DATA_TAG
static const char DATA_TAG[]
Definition: XmlRpcValue.cpp:40
XmlRpc::XmlRpcValue::size
int size() const
Return the size for string, base64, array, and struct values.
Definition: XmlRpcValue.cpp:211
XmlRpc::XmlRpcValue::assertArray
void assertArray(int size) const
Definition: XmlRpcValue.cpp:99
XmlRpc::XmlRpcValue::toXml
std::string toXml() const
Encode the Value in xml.
Definition: XmlRpcValue.cpp:275
XmlRpc::XmlRpcValue::asInt
int asInt
Definition: XmlRpcValue.h:194
operator<<
std::ostream & operator<<(std::ostream &os, const XmlRpc::XmlRpcValue &v)
Definition: XmlRpcValue.cpp:691
XmlRpc::DOUBLE_TAG
static const char DOUBLE_TAG[]
Definition: XmlRpcValue.cpp:28
XmlRpc::NAME_ETAG
static const char NAME_ETAG[]
Definition: XmlRpcValue.cpp:47
XmlRpc::XmlRpcValue::asStruct
ValueStruct * asStruct
Definition: XmlRpcValue.h:200
XmlRpc::XmlRpcValue::BinaryData
std::vector< char > BinaryData
Definition: XmlRpcValue.h:41
XmlRpc::VALUE_ETAG
static const char VALUE_ETAG[]
Definition: XmlRpcValue.cpp:24
XmlRpc::XmlRpcValue::TypeBase64
@ TypeBase64
Definition: XmlRpcValue.h:35
XmlRpc::XmlRpcUtil::xmlEncode
static std::string xmlEncode(const std::string &raw)
Convert raw text to encoded xml.
Definition: XmlRpcUtil.cpp:241
XmlRpc::XmlRpcValue::intToXml
std::string intToXml() const
Definition: XmlRpcValue.cpp:332
XmlRpc::XmlRpcValue::structToXml
std::string structToXml() const
Definition: XmlRpcValue.cpp:587
encode.h
XmlRpc::XmlRpcValue::ValueStruct
std::map< std::string, XmlRpcValue > ValueStruct
Definition: XmlRpcValue.h:43
s
XmlRpcServer s
Definition: HelloServer.cpp:11
XmlRpc::XmlRpcValue::fromXml
bool fromXml(std::string const &valueXml, int *offset)
Decode xml. Destroys any existing value.
Definition: XmlRpcValue.cpp:232
XmlRpc::STRUCT_ETAG
static const char STRUCT_ETAG[]
Definition: XmlRpcValue.cpp:49
XmlRpc::XmlRpcValue::_doubleFormat
static std::string _doubleFormat
Definition: XmlRpcValue.h:185
XmlRpc::tmEq
static bool tmEq(struct tm const &t1, struct tm const &t2)
Definition: XmlRpcValue.cpp:160
XmlRpc::DATETIME_TAG
static const char DATETIME_TAG[]
Definition: XmlRpcValue.cpp:34
XmlRpc::XmlRpcValue::assertStruct
void assertStruct() const
Definition: XmlRpcValue.cpp:120
XmlRpcValue.h
XmlRpc::DATETIME_ETAG
static const char DATETIME_ETAG[]
Definition: XmlRpcValue.cpp:35
XmlRpc::XmlRpcValue::TypeInt
@ TypeInt
Definition: XmlRpcValue.h:31
XmlRpc::DATA_ETAG
static const char DATA_ETAG[]
Definition: XmlRpcValue.cpp:41
XmlRpc::XmlRpcValue::TypeInvalid
@ TypeInvalid
Definition: XmlRpcValue.h:29
XmlRpc::INT_TAG
static const char INT_TAG[]
Definition: XmlRpcValue.cpp:30
XmlRpc::XmlRpcValue::doubleFromXml
bool doubleFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:346
XmlRpc
Definition: XmlRpcClient.h:20
XmlRpc::DOUBLE_ETAG
static const char DOUBLE_ETAG[]
Definition: XmlRpcValue.cpp:29
XmlRpc::MEMBER_ETAG
static const char MEMBER_ETAG[]
Definition: XmlRpcValue.cpp:48
XmlRpc::XmlRpcUtil::parseTag
static std::string parseTag(const char *tag, std::string const &xml, int *offset)
Returns contents between <tag> and </tag>, updates offset to char after </tag>
Definition: XmlRpcUtil.cpp:110
XmlRpc::XmlRpcValue::TypeStruct
@ TypeStruct
Definition: XmlRpcValue.h:37
XmlRpc::ARRAY_ETAG
static const char ARRAY_ETAG[]
Definition: XmlRpcValue.cpp:42
XmlRpc::XmlRpcValue::assertTypeOrInvalid
void assertTypeOrInvalid(Type t) const
Definition: XmlRpcValue.cpp:75
decode.h
XmlRpc::XmlRpcValue::getDoubleFormat
static std::string const & getDoubleFormat()
Return the format used to write double values.
Definition: XmlRpcValue.h:146
XmlRpc::XmlRpcValue::TypeDouble
@ TypeDouble
Definition: XmlRpcValue.h:32
XmlRpc::XmlRpcUtil::findTag
static bool findTag(const char *tag, std::string const &xml, int *offset)
Returns true if the tag is found and updates offset to the char after the tag.
Definition: XmlRpcUtil.cpp:130
XmlRpc::XmlRpcValue::arrayToXml
std::string arrayToXml() const
Definition: XmlRpcValue.cpp:544
XmlRpc::XmlRpcValue::boolFromXml
bool boolFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:293
XmlRpc::ARRAY_TAG
static const char ARRAY_TAG[]
Definition: XmlRpcValue.cpp:39
XmlRpc::MEMBER_TAG
static const char MEMBER_TAG[]
Definition: XmlRpcValue.cpp:45
XmlRpc::XmlRpcValue::asArray
ValueArray * asArray
Definition: XmlRpcValue.h:199
XmlRpc::XmlRpcValue::timeFromXml
bool timeFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:418
base64::encoder::encode_end
int encode_end(char *plaintext_out)
Definition: encode.h:43
XmlRpc::XmlRpcValue::TypeString
@ TypeString
Definition: XmlRpcValue.h:33
XmlRpc::XmlRpcValue::_type
Type _type
Definition: XmlRpcValue.h:188
XmlRpc::XmlRpcUtil::nextTagIs
static bool nextTagIs(const char *tag, std::string const &xml, int *offset)
Definition: XmlRpcUtil.cpp:146
XmlRpc::STRING_TAG
static const char STRING_TAG[]
Definition: XmlRpcValue.cpp:33
XmlRpc::XmlRpcValue::stringFromXml
bool stringFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:395
XmlRpc::XmlRpcValue::operator==
bool operator==(XmlRpcValue const &other) const
Definition: XmlRpcValue.cpp:166
XmlRpc::XmlRpcValue::Type
Type
Definition: XmlRpcValue.h:28
XmlRpc::XmlRpcValue::ValueArray
std::vector< XmlRpcValue > ValueArray
Definition: XmlRpcValue.h:42
XmlRpc::BASE64_TAG
static const char BASE64_TAG[]
Definition: XmlRpcValue.cpp:36
XmlRpc::VALUE_TAG
static const char VALUE_TAG[]
Definition: XmlRpcValue.cpp:23
XmlRpc::XmlRpcUtil::error
static void error(const char *fmt,...)
Dump error messages somewhere.
Definition: XmlRpcUtil.cpp:96
XmlRpc::XmlRpcUtil::xmlDecode
static std::string xmlDecode(const std::string &encoded)
Convert encoded xml to raw text.
Definition: XmlRpcUtil.cpp:204
XmlRpc::I4_TAG
static const char I4_TAG[]
Definition: XmlRpcValue.cpp:31
XmlRpc::XmlRpcValue::asBinary
BinaryData * asBinary
Definition: XmlRpcValue.h:198
XmlRpc::XmlRpcValue::asTime
struct tm * asTime
Definition: XmlRpcValue.h:196
XmlRpc::XmlRpcValue::doubleToXml
std::string doubleToXml() const
Definition: XmlRpcValue.cpp:378
XmlRpc::XmlRpcValue::boolToXml
std::string boolToXml() const
Definition: XmlRpcValue.cpp:307
XmlRpc::XmlRpcValue::arrayFromXml
bool arrayFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:525
XmlRpc::XmlRpcValue::binaryFromXml
bool binaryFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:482
XmlRpc::XmlRpcValue::TypeArray
@ TypeArray
Definition: XmlRpcValue.h:36
XmlRpc::XmlRpcValue::invalidate
void invalidate()
Definition: XmlRpcValue.cpp:59
XmlRpc::XmlRpcValue::structFromXml
bool structFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:562
XmlRpc::XmlRpcException
Definition: XmlRpcException.h:23
XmlRpc::XmlRpcValue::hasMember
bool hasMember(const std::string &name) const
Check for the existence of a struct member by name.
Definition: XmlRpcValue.cpp:225
XmlRpc::XmlRpcValue::intFromXml
bool intFromXml(std::string const &valueXml, int *offset)
Definition: XmlRpcValue.cpp:318
XmlRpc::XmlRpcValue::operator=
XmlRpcValue & operator=(XmlRpcValue const &rhs)
Definition: XmlRpcValue.cpp:137
base64::decoder::decode
int decode(char value_in)
Definition: decode.h:33
XmlRpc::XmlRpcValue::valid
bool valid() const
Return true if the value has been set to something.
Definition: XmlRpcValue.h:121
XmlRpc::XmlRpcValue::asString
std::string * asString
Definition: XmlRpcValue.h:197
XmlRpc::XmlRpcValue::stringToXml
std::string stringToXml() const
Definition: XmlRpcValue.cpp:407
XmlRpc::XmlRpcValue::_value
union XmlRpc::XmlRpcValue::@0 _value
base64::encoder::encode
int encode(char value_in)
Definition: encode.h:33
XmlRpc::XmlRpcValue::asDouble
double asDouble
Definition: XmlRpcValue.h:195
XmlRpc::XmlRpcValue::operator!=
bool operator!=(XmlRpcValue const &other) const
Definition: XmlRpcValue.cpp:204
XmlRpc::I4_ETAG
static const char I4_ETAG[]
Definition: XmlRpcValue.cpp:32
XmlRpcException.h
XmlRpc::BOOLEAN_TAG
static const char BOOLEAN_TAG[]
Definition: XmlRpcValue.cpp:26
XmlRpc::BOOLEAN_ETAG
static const char BOOLEAN_ETAG[]
Definition: XmlRpcValue.cpp:27
base64::decoder
Definition: decode.h:22
XmlRpc::XmlRpcValue::timeToXml
std::string timeToXml() const
Definition: XmlRpcValue.cpp:441
XmlRpc::XmlRpcValue::TypeBoolean
@ TypeBoolean
Definition: XmlRpcValue.h:30
XmlRpc::XmlRpcValue::TypeDateTime
@ TypeDateTime
Definition: XmlRpcValue.h:34
XmlRpc::XmlRpcValue::asBool
bool asBool
Definition: XmlRpcValue.h:193
XmlRpc::NAME_TAG
static const char NAME_TAG[]
Definition: XmlRpcValue.cpp:46
base64::encoder
Definition: encode.h:22
XmlRpcUtil.h
XmlRpc::XmlRpcValue::binaryToXml
std::string binaryToXml() const
Definition: XmlRpcValue.cpp:503
XmlRpc::BASE64_ETAG
static const char BASE64_ETAG[]
Definition: XmlRpcValue.cpp:37
XmlRpc::XmlRpcValue::write
std::ostream & write(std::ostream &os) const
Write the value (no xml encoding)
Definition: XmlRpcValue.cpp:610
XmlRpc::STRUCT_TAG
static const char STRUCT_TAG[]
Definition: XmlRpcValue.cpp:44
XmlRpc::XmlRpcValue
RPC method arguments and results are represented by Values.
Definition: XmlRpcValue.h:24
XmlRpc::XmlRpcUtil::getNextTag
static std::string getNextTag(std::string const &xml, int *offset)
Definition: XmlRpcUtil.cpp:168


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix, Dirk Thomas
autogenerated on Thu Apr 8 2021 03:00:12