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