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