Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "httpclnt.h"
00038
00039 #pragma warning(disable: 4355)
00040
00041 #include <time.h>
00042
00043
00044 namespace XMLRPC {
00045
00046
00047 ISODate::ISODate()
00048 {
00049 #ifdef _WIN32
00050 SYSTEMTIME time;
00051
00052 GetLocalTime(&time);
00053
00054 _year = time.wYear;
00055 _month = time.wMonth;
00056 _day = time.wDay;
00057
00058 _hour = time.wHour;
00059 _minute = time.wMinute;
00060 _second = time.wSecond;
00061 #else
00062 time_t t;
00063 struct tm lc;
00064
00065 time(&t);
00066 localtime_r(&t, &lc);
00067
00068 _year = lc.tm_year + 1900;
00069 _month = lc.tm_mon + 1;
00070 _day = lc.tm_mday;
00071
00072 _hour = lc.tm_hour;
00073 _minute = lc.tm_min;
00074 _second = lc.tm_sec;
00075 #endif
00076 }
00077
00078 ISODate::ISODate(const char* str)
00079 {
00080 if (sscanf_s(str, "%04d%02d%02dT%02d:%02d:%02d", &_year, &_month, &_day, &_hour, &_minute, &_second) != 6)
00081 throw Exception("invalid date format");
00082 }
00083
00084 string ISODate::str() const
00085 {
00086 char buffer[18];
00087
00088 sprintf(buffer, "%04d%02d%02dT%02d:%02d:%02d", _year, _month, _day, _hour, _minute, _second);
00089
00090 return buffer;
00091 }
00092
00093
00094 #ifdef _WIN32
00095
00096 static ULARGE_INTEGER get_time_number(const ISODate& date)
00097 {
00098 SYSTEMTIME st = {0};
00099
00100 st.wYear = date._year;
00101 st.wMonth = date._month;
00102 st.wDay = date._day;
00103 st.wHour = date._hour;
00104 st.wMinute = date._minute;
00105 st.wSecond = date._second;
00106
00107 FILETIME ft;
00108 SystemTimeToFileTime(&st, &ft);
00109
00110 ULARGE_INTEGER li;
00111
00112 li.LowPart = ft.dwLowDateTime;
00113 li.HighPart = ft.dwHighDateTime;
00114
00115 return li;
00116 }
00117
00118 long ISODate::diff(const ISODate& other) const
00119 {
00120 ULARGE_INTEGER li1 = get_time_number(*this);
00121 ULARGE_INTEGER li2 = get_time_number(other);
00122
00123 return long((li1.QuadPart - li2.QuadPart) / 10000000);
00124 }
00125
00126 #else // _WIN32
00127
00128 static time_t get_time_t(const ISODate& date)
00129 {
00130 struct tm t = {
00131 date._second,
00132 date._minute,
00133 date._hour,
00134 date._day,
00135 date._month - 1,
00136 date._year - 1900
00137 };
00138
00139 return mktime(&t);
00140 }
00141
00142 long ISODate::diff(const ISODate& other) const
00143 {
00144 time_t t1 = get_time_t(*this);
00145 time_t t2 = get_time_t(other);
00146
00147 return (long) difftime(t1, t2);
00148 }
00149
00150 #endif
00151
00152
00153 Binary::Binary(const void* buffer, size_t len)
00154 : _buffer(malloc(len)),
00155 _len(len)
00156 {
00157 memcpy(_buffer, buffer, len);
00158 }
00159
00160 Binary::Binary(const char* base64)
00161 {
00162 _buffer = base64_decode(base64, _len);
00163 }
00164
00165 Binary::Binary(const Binary& other)
00166 : _buffer(malloc(other._len)),
00167 _len(other._len)
00168 {
00169 memcpy(_buffer, other._buffer, other._len);
00170 }
00171
00172 string Binary::str() const
00173 {
00174 char* s = base64_encode(_buffer, _len);
00175 string ret = s;
00176 free(s);
00177
00178 return ret;
00179 }
00180
00181
00182 XMLRPCArray::XMLRPCArray(const_XMLPos pos)
00183 {
00184 if (pos.go_down("data")) {
00185 const XMLNode::Children& values = pos->get_children();
00186
00187 for(XMLNode::Children::const_iterator it=values.begin(); it!=values.end(); ++it) {
00188 assert(**it=="value");
00189
00190 string value = XMLRPCValue::get_any(*it);
00191
00192 push_back(value);
00193 }
00194 }
00195 }
00196
00197
00198 XMLRPCStruct::XMLRPCStruct(const XMLNode& node)
00199 {
00200 const XMLNode::Children& members = node.get_children();
00201
00202 for(XMLNode::Children::const_iterator it=members.begin(); it!=members.end(); ++it) {
00203 const XMLNode* pNode = *it;
00204 assert(*pNode=="member");
00205
00206 string value;
00207
00208 const_XMLPos pos(pNode);
00209 if (pos.go_down("value"))
00210 value = XMLRPCValue::get_any(pos);
00211
00212 const string& name = pNode->get_sub_content("name");
00213
00214 (*this)[name] = value;
00215 }
00216 }
00217
00218
00219 string XMLRPCWriter::flush()
00220 {
00221 if (_params)
00222 _writer.back();
00223
00224 _writer.back();
00225
00226 return _buffer.str();
00227 }
00228
00229 void XMLRPCWriter::write_string_param(const string& value)
00230 {
00231 if (!_params++)
00232 _writer.create("params");
00233
00234 _writer.create("param");
00235 _writer.create("value");
00236 _writer.set_content(value);
00237 _writer.back();
00238 _writer.back();
00239 }
00240
00241 void XMLRPCWriter::write_param(const string& type, const string& value)
00242 {
00243 if (!_params++)
00244 _writer.create("params");
00245
00246 _writer.create("param");
00247 _writer.create("value");
00248 _writer.create(type);
00249 _writer.set_content(value);
00250 _writer.back();
00251 _writer.back();
00252 _writer.back();
00253 }
00254
00255 void XMLRPCWriter::write_param(const XMLRPCArray& arr)
00256 {
00257 if (!_params++)
00258 _writer.create("params");
00259
00260 _writer.create("param");
00261 _writer.create("value");
00262 _writer.create("array");
00263 _writer.create("data");
00264
00265 for(XMLRPCArray::const_iterator it=arr.begin(); it!=arr.end(); ++it) {
00266 _writer.create("value");
00267 _writer.set_content(*it);
00268 _writer.back();
00269 }
00270
00271 _writer.back();
00272 _writer.back();
00273 _writer.back();
00274 _writer.back();
00275 }
00276
00277 void XMLRPCWriter::write_param(const XMLRPCStruct& str)
00278 {
00279 if (!_params++)
00280 _writer.create("params");
00281
00282 write_struct(str, "param");
00283 }
00284
00285
00286
00287 void XMLRPCWriter::write_struct(const XMLRPCStruct& str, const string& keyword)
00288 {
00289 _writer.create(keyword);
00290 _writer.create("value");
00291 _writer.create("struct");
00292
00293 for(XMLRPCStruct::const_iterator it=str.begin(); it!=str.end(); ++it) {
00294 _writer.create("member");
00295 _writer.create("name");
00296 _writer.set_content(it->first);
00297 _writer.back();
00298
00299 _writer.create("value");
00300 _writer.set_content(it->second);
00301 _writer.back();
00302 _writer.back();
00303 }
00304
00305 _writer.back();
00306 _writer.back();
00307 _writer.back();
00308 }
00309
00310
00311 XMLRPCParser::XMLRPCParser(const string& xml_str, const string& keyword)
00312 : _pos(&_doc),
00313 _value_cnt(0)
00314 {
00315 if (_doc.read_buffer(xml_str))
00316 _pos.go_down(keyword);
00317 }
00318
00319 bool XMLRPCParser::next_parameter()
00320 {
00321 if (!_pos.iterate("param", _value_cnt))
00322 return false;
00323
00324 return _pos.go_down("value");
00325 }
00326
00327 bool XMLRPCParser::more_parameters() const
00328 {
00329 XPath xpath;
00330 xpath.push_back(XPathElement("param", _value_cnt));
00331
00332 return _pos->find_relative(xpath) != NULL;
00333 }
00334
00335 XMLRPC_TYPE XMLRPCParser::get_next_type() const
00336 {
00337 XPath xpath;
00338 xpath.push_back(XPathElement("param", _value_cnt));
00339
00340 const XMLNode* pNode = _pos->find_relative(xpath);
00341 if (!pNode)
00342 return XRT_VOID;
00343
00344 return get_param_type(pNode);
00345 }
00346
00347 XMLRPC_TYPE XMLRPCParser::get_param_type(const XMLNode* pNode)
00348 {
00349 pNode = pNode->find_relative("value");
00350 if (!pNode)
00351 return XRT_VOID;
00352
00353 pNode = pNode->get_first_child();
00354 if (!pNode)
00355 return XRT_STRING;
00356
00357 const XS_String& tag = *pNode;
00358
00359 if (tag=="i4" || tag=="int")
00360 return XRT_INT;
00361 else if (tag == "double")
00362 return XRT_DOUBLE;
00363 else if (tag == "boolean")
00364 return XRT_BOOLEAN;
00365 else if (tag == "string")
00366 return XRT_STRING;
00367 else if (tag == "dateTime.iso8601")
00368 return XRT_DATE;
00369 else if (tag == "base64")
00370 return XRT_BINARY;
00371 else if (tag == "array")
00372 return XRT_ARRAY;
00373 else if (tag == "struct")
00374 return XRT_STRUCT;
00375 else
00376 return XRT_VOID;
00377 }
00378
00379 size_t XMLRPCParser::get_parameter_types(TypeList& types) const
00380 {
00381 int n = 0;
00382
00383 XMLPos pos = _pos;
00384
00385 while(pos.iterate("param", n)) {
00386 types.push_back(get_param_type(pos));
00387
00388 pos.back();
00389 }
00390
00391 return n;
00392 }
00393
00394
00395 string XMLRPCParser::get_any()
00396 {
00397 if (next_parameter()) {
00398 const string& ret = XMLRPCValue::get_any(_pos);
00399
00400 _pos.back();
00401 _pos.back();
00402
00403 return ret;
00404 } else
00405 throw Exception("missing parameter value");
00406 }
00407
00408 int XMLRPCParser::get_int()
00409 {
00410 if (next_parameter()) {
00411 int ret = XMLRPCValue::get_int(_pos);
00412
00413 _pos.back();
00414 _pos.back();
00415
00416 return ret;
00417 } else
00418 throw Exception("missing parameter value");
00419 }
00420
00421 double XMLRPCParser::get_double()
00422 {
00423 if (next_parameter()) {
00424 double ret = XMLRPCValue::get_double(_pos);
00425
00426 _pos.back();
00427 _pos.back();
00428
00429 return ret;
00430 } else
00431 throw Exception("missing parameter value");
00432 }
00433
00434 bool XMLRPCParser::get_bool()
00435 {
00436 if (next_parameter()) {
00437 bool ret = XMLRPCValue::get_bool(_pos);
00438
00439 _pos.back();
00440 _pos.back();
00441
00442 return ret;
00443 } else
00444 throw Exception("missing parameter value");
00445 }
00446
00447 string XMLRPCParser::get_string()
00448 {
00449 if (next_parameter()) {
00450 string ret = XMLRPCValue::get_string(_pos);
00451
00452 _pos.back();
00453 _pos.back();
00454
00455 return ret;
00456 } else
00457 throw Exception("missing parameter value");
00458 }
00459
00460 ISODate XMLRPCParser::get_date()
00461 {
00462 if (next_parameter()) {
00463 ISODate ret = XMLRPCValue::get_date(_pos);
00464
00465 _pos.back();
00466 _pos.back();
00467
00468 return ret;
00469 } else
00470 throw Exception("missing parameter value");
00471 }
00472
00473 Binary XMLRPCParser::get_binary()
00474 {
00475 if (next_parameter()) {
00476 Binary ret = XMLRPCValue::get_binary(_pos);
00477
00478 _pos.back();
00479 _pos.back();
00480
00481 return ret;
00482 } else
00483 throw Exception("missing parameter value");
00484 }
00485
00486 XMLRPCArray XMLRPCParser::get_array()
00487 {
00488 if (next_parameter()) {
00489 XMLRPCArray ret = XMLRPCValue::get_array(_pos);
00490
00491 _pos.back();
00492 _pos.back();
00493
00494 return ret;
00495 } else
00496 throw Exception("missing parameter value");
00497 }
00498
00499 XMLRPCStruct XMLRPCParser::get_struct()
00500 {
00501 if (next_parameter()) {
00502 XMLRPCStruct ret = XMLRPCValue::get_struct(_pos);
00503
00504 _pos.back();
00505 _pos.back();
00506
00507 return ret;
00508 } else
00509 throw Exception("missing parameter value");
00510 }
00511
00512
00513 string XMLRPCValue::get_any(const_XMLPos pos)
00514 {
00515 pos.go_down();
00516
00517 return pos->get_content();
00518 }
00519
00520 int XMLRPCValue::get_int(const_XMLPos pos)
00521 {
00522 if (pos.go_down("i4") || pos.go_down("int"))
00523 return XMLInt(pos->get_content());
00524 else
00525 throw Exception("wrong data type");
00526 }
00527
00528 double XMLRPCValue::get_double(const_XMLPos pos)
00529 {
00530 if (pos.go_down("double"))
00531 return XMLDouble(pos->get_content());
00532 else
00533 throw Exception("wrong data type");
00534 }
00535
00536 bool XMLRPCValue::get_bool(const_XMLPos pos)
00537 {
00538 if (pos.go_down("boolean"))
00539 return XMLInt(pos->get_content()) == 1;
00540 else
00541 throw Exception("wrong data type");
00542 }
00543
00544 string XMLRPCValue::get_string(const_XMLPos pos)
00545 {
00546 if (pos.go_down("string"))
00547 return pos->get_content();
00548 else if (pos->get_children().empty())
00549 return pos->get_content();
00550 else
00551 throw Exception("wrong data type");
00552 }
00553
00554 ISODate XMLRPCValue::get_date(const_XMLPos pos)
00555 {
00556 if (pos.go_down("dateTime.iso8601"))
00557 return ISODate(pos->get_content());
00558 else
00559 throw Exception("wrong data type");
00560 }
00561
00562 Binary XMLRPCValue::get_binary(const_XMLPos pos)
00563 {
00564 if (pos.go_down("base64"))
00565 return Binary(pos->get_content());
00566 else
00567 throw Exception("wrong data type");
00568 }
00569
00570 XMLRPCArray XMLRPCValue::get_array(const_XMLPos pos)
00571 {
00572 if (pos.go_down("array"))
00573 return XMLRPCArray(pos);
00574 else
00575 throw Exception("wrong data type");
00576 }
00577
00578 XMLRPCStruct XMLRPCValue::get_struct(const_XMLPos pos)
00579 {
00580 if (pos.go_down("struct"))
00581 return XMLRPCStruct(*pos);
00582 else
00583 throw Exception("wrong data type");
00584 }
00585
00586
00587 }