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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix
autogenerated on Thu Aug 13 2020 16:43:19