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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix, Dirk Thomas
autogenerated on Mon Oct 19 2020 03:23:56