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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley
autogenerated on Wed Dec 20 2017 03:58:37