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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix, Dirk Thomas
autogenerated on Mon Nov 2 2020 03:52:24