soapmessage.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning( disable : 4786)
  14. //Jlib
  15. #include "jexcept.hpp"
  16. //ESP Bindings
  17. #include "SOAP/Platform/soapmessage.hpp"
  18. #include "bindutil.hpp"
  19. #include <memory>
  20. static void serializeAttributes(StringBuffer& outbuf, IProperties* attrs)
  21. {
  22. if (attrs)
  23. {
  24. Owned<IPropertyIterator> it = attrs->getIterator();
  25. for (it->first(); it->isValid(); it->next())
  26. {
  27. const char* k = it->getPropKey();
  28. const char* v = attrs->queryProp(k);
  29. outbuf.append(' ').append(k).append("=\"");
  30. encodeUtf8XML(v,outbuf);
  31. outbuf.append('"');
  32. }
  33. }
  34. }
  35. void CSoapMessage::set_text(const char* text)
  36. {
  37. m_text.clear();
  38. m_text.append(text);
  39. }
  40. const char* CSoapMessage::get_text()
  41. {
  42. return m_text.str();
  43. }
  44. int CSoapMessage::get_text_length()
  45. {
  46. return m_text.length();
  47. }
  48. void CSoapMessage::set_content_type(const char* content_type)
  49. {
  50. m_content_type.set(content_type);
  51. }
  52. const char* CSoapMessage::get_content_type()
  53. {
  54. return m_content_type.get();
  55. }
  56. void CSoapResponse::set_status(int status)
  57. {
  58. m_status = status;
  59. }
  60. int CSoapResponse::get_status()
  61. {
  62. return m_status;
  63. }
  64. void CSoapResponse::set_err(const char* err)
  65. {
  66. m_err.clear();
  67. m_err.append(err);
  68. }
  69. const char* CSoapResponse::get_err()
  70. {
  71. return m_err.str();
  72. }
  73. void CRpcMessage::simple_marshall(StringBuffer& outbuf)
  74. {
  75. outbuf.append("<").append(m_name.get()).append(">");
  76. StringBuffer childrenbuf;
  77. m_params->simple_serializeChildren(childrenbuf);
  78. outbuf.append(childrenbuf);
  79. outbuf.append("</").append(m_name.get()).append(">");
  80. }
  81. void CRpcMessage::marshall(StringBuffer& outbuf, CMimeMultiPart* multipart)
  82. {
  83. if (m_serializedContent.get())
  84. outbuf.append( m_serializedContent );
  85. else
  86. {
  87. outbuf.append("<");
  88. if(m_ns.length() > 0)
  89. {
  90. outbuf.append(m_ns.get());
  91. outbuf.append(":");
  92. }
  93. outbuf.append(m_name.get());
  94. bool no_ns = (m_context && m_context->queryOptions()&ESPCTX_NO_NAMESPACES );
  95. if (!no_ns && m_nsuri.length()>0)
  96. {
  97. outbuf.append(" xmlns");
  98. if (m_ns.length()>0)
  99. {
  100. outbuf.append(":").append(m_ns);
  101. }
  102. outbuf.append("=\"").append(m_nsuri.get()).append("\"");
  103. }
  104. serialize_attributes(outbuf);
  105. outbuf.append(">");
  106. StringBuffer childrenbuf;
  107. m_params->serializeChildren(childrenbuf, multipart);
  108. outbuf.append(childrenbuf);
  109. outbuf.append("</");
  110. if(m_ns.length() > 0)
  111. {
  112. outbuf.append(m_ns.get());
  113. outbuf.append(":");
  114. }
  115. outbuf.append(m_name.get());
  116. outbuf.append(">");
  117. }
  118. }
  119. void CRpcMessage::serialize_attributes(StringBuffer& outbuf)
  120. {
  121. ::serializeAttributes(outbuf,m_attributes);
  122. }
  123. void CRpcMessage::add_attribute(const char* name, const char* value)
  124. {
  125. if (!name || !*name)
  126. return;
  127. if (!m_attributes)
  128. m_attributes.setown(createProperties());
  129. m_attributes->setProp(name, value);
  130. }
  131. void CRpcMessage::add_attr(const char * path, const char * name, const char * value, IProperties & attrs)
  132. {
  133. if ((path && *path) || (name && *name))
  134. {
  135. CSoapValue *par=m_params.get();
  136. if(path)
  137. par = par->get_value(path);
  138. if (name)
  139. par = par->get_value(name);
  140. if (par)
  141. {
  142. Owned<IPropertyIterator> piter = attrs.getIterator();
  143. for (piter->first(); piter->isValid(); piter->next())
  144. {
  145. const char *propkey = piter->getPropKey();
  146. par->add_attribute(propkey, attrs.queryProp(propkey));
  147. }
  148. }
  149. }
  150. else
  151. {
  152. Owned<IPropertyIterator> piter = attrs.getIterator();
  153. for (piter->first(); piter->isValid(); piter->next())
  154. {
  155. const char *propkey = piter->getPropKey();
  156. add_attribute(propkey, attrs.queryProp(propkey));
  157. }
  158. }
  159. }
  160. void CRpcMessage::unmarshall(XmlPullParser* xpp)
  161. {
  162. unmarshall(xpp, m_params, m_name);
  163. }
  164. void CRpcMessage::unmarshall(XmlPullParser* xpp, CSoapValue* soapvalue, const char* tagname)
  165. {
  166. int type;
  167. StartTag stag;
  168. EndTag etag;
  169. while((type = xpp->next()) != XmlPullParser::END_DOCUMENT)
  170. {
  171. if(type == XmlPullParser::END_TAG)
  172. {
  173. xpp->readEndTag(etag);
  174. if(!stricmp(etag.getLocalName(), tagname))
  175. break;
  176. }
  177. else if(type == XmlPullParser::START_TAG)
  178. {
  179. xpp->readStartTag(stag);
  180. StringBuffer ns;
  181. const char* qname = stag.getQName();
  182. //DBGLOG("tag qname=%s", qname);
  183. const char* localname = stag.getLocalName();
  184. const char* valuetype = stag.getValue("SOAP-ENC:type");
  185. if(strlen(qname) > strlen(localname))
  186. {
  187. const char* semcol = strchr(qname, ':');
  188. if(semcol != NULL)
  189. {
  190. ns.append(qname, 0, semcol - qname);
  191. }
  192. }
  193. CSoapValue* childsoapval = new CSoapValue(ns.str(), localname, valuetype, (const char*)NULL,m_encode_xml);
  194. soapvalue->add_child(childsoapval);
  195. // attributes
  196. for(int i = 0; ; ++i) {
  197. const char* name = stag.getRawName(i);
  198. if (!name)
  199. break;
  200. childsoapval->add_attribute(name, stag.getValue(i));
  201. }
  202. unmarshall(xpp, childsoapval, localname);
  203. }
  204. else if(type == XmlPullParser::CONTENT)
  205. {
  206. const char* value = xpp->readContent();
  207. soapvalue->set_value(value);
  208. }
  209. }
  210. }
  211. void CRpcMessage::unmarshall(XmlPullParser* xpp, CMimeMultiPart* multipart)
  212. {
  213. unmarshall(xpp, m_params, m_name, multipart);
  214. }
  215. void CRpcMessage::unmarshall(XmlPullParser* xpp, CSoapValue* soapvalue, const char* tagname, CMimeMultiPart* multipart)
  216. {
  217. int type;
  218. while((type = xpp->next()) != XmlPullParser::END_DOCUMENT)
  219. {
  220. if(type == XmlPullParser::END_TAG)
  221. {
  222. EndTag etag;
  223. xpp->readEndTag(etag);
  224. if(!stricmp(etag.getLocalName(), tagname))
  225. break;
  226. }
  227. else if(type == XmlPullParser::START_TAG)
  228. {
  229. StartTag stag;
  230. xpp->readStartTag(stag);
  231. StringBuffer ns;
  232. const char* qname = stag.getQName();
  233. //DBGLOG("tag qname=%s", qname);
  234. const char* localname = stag.getLocalName();
  235. const char* valuetype = stag.getValue("SOAP-ENC:type");
  236. if(strlen(qname) > strlen(localname))
  237. {
  238. const char* semcol = strchr(qname, ':');
  239. if(semcol != NULL)
  240. {
  241. ns.append(qname, 0, semcol - qname);
  242. }
  243. }
  244. CSoapValue* childsoapval = new CSoapValue(ns.str(), localname, valuetype, (const char*)NULL,m_encode_xml);
  245. soapvalue->add_child(childsoapval);
  246. // attributes
  247. for(int i = 0; ; ++i) {
  248. const char* name = stag.getRawName(i);
  249. if (!name)
  250. break;
  251. childsoapval->add_attribute(name, stag.getValue(i));
  252. }
  253. const char* href = stag.getValue("href");
  254. if(href != NULL)
  255. {
  256. if(multipart != NULL)
  257. {
  258. Owned<CMimeBodyPart> bodypart = multipart->getBodyPart(href+4);
  259. if(bodypart)
  260. {
  261. StringBuffer val;
  262. bodypart->getContent(val);
  263. if(val.length() > 0)
  264. {
  265. childsoapval->set_value(val.str());
  266. }
  267. }
  268. }
  269. }
  270. else
  271. {
  272. unmarshall(xpp, childsoapval, localname);
  273. }
  274. }
  275. else if(type == XmlPullParser::CONTENT)
  276. {
  277. const char* value = xpp->readContent();
  278. soapvalue->set_value(value);
  279. }
  280. }
  281. }
  282. IRpcMessage* createRpcMessage(const char* rootTag, StringBuffer& xml)
  283. {
  284. CRpcMessage* rpc = new CRpcMessage(rootTag);
  285. auto_ptr<XmlPullParser> xpp(new XmlPullParser(xml.str(), xml.length()));
  286. xpp->setSupportNamespaces(true);
  287. rpc->unmarshall(xpp.get());
  288. return rpc;
  289. }
  290. bool CRpcResponse::handleExceptions(IXslProcessor *xslp, IMultiException *me, const char *serv, const char *meth, const char *errorXslt)
  291. {
  292. IEspContext *context=queryContext();
  293. if (me->ordinality()>0)
  294. {
  295. StringBuffer text;
  296. me->errorMessage(text);
  297. text.append('\n');
  298. WARNLOG("Exception(s) in %s::%s - %s", serv, meth, text.str());
  299. if (errorXslt)
  300. {
  301. me->serialize(text.clear());
  302. StringBuffer theOutput;
  303. xslTransformHelper(xslp, text.str(), errorXslt, theOutput, context->queryXslParameters());
  304. set_text(theOutput.str());
  305. }
  306. }
  307. return false;
  308. }
  309. void CBody::nextRpcMessage(IRpcMessage* rpcmessage)
  310. {
  311. if(!rpcmessage || !m_xpp)
  312. return;
  313. int type;
  314. StartTag stag;
  315. EndTag etag;
  316. while((type = m_xpp->next()) != XmlPullParser::END_DOCUMENT)
  317. {
  318. if(type == XmlPullParser::START_TAG)
  319. {
  320. m_xpp->readStartTag(stag);
  321. const char* localname = stag.getLocalName();
  322. rpcmessage->set_name(localname);
  323. StringBuffer ns;
  324. const char* qname = stag.getQName();
  325. if(strlen(qname) > strlen(localname))
  326. {
  327. const char* semcol = strchr(qname, ':');
  328. if(semcol != NULL)
  329. {
  330. ns.append(qname, 0, semcol - qname);
  331. }
  332. }
  333. const char* nsuri = stag.getUri();
  334. rpcmessage->set_ns(ns.str());
  335. rpcmessage->set_nsuri(nsuri);
  336. //DBGLOG("ns=%s nsuri=%s", ns.str(), nsuri);
  337. return;
  338. }
  339. }
  340. }
  341. void CHeader::addHeaderBlock(IRpcMessage* block)
  342. {
  343. m_headerblocks.append(*block);
  344. }
  345. int CHeader::getNumBlocks()
  346. {
  347. return m_headerblocks.ordinality();
  348. }
  349. IRpcMessage* CHeader::getHeaderBlock(int seq)
  350. {
  351. if(seq >= m_headerblocks.ordinality())
  352. return NULL;
  353. else
  354. return &(m_headerblocks.item(seq));
  355. }
  356. IRpcMessage* CHeader::getHeaderBlock(const char* name)
  357. {
  358. ForEachItemIn(x, m_headerblocks)
  359. {
  360. IRpcMessage* oneblock = &(m_headerblocks.item(x));
  361. if(oneblock != NULL && (strcmp(oneblock->get_name(), name) == 0))
  362. {
  363. return oneblock;
  364. }
  365. }
  366. return NULL;
  367. }
  368. StringBuffer& CHeader::marshall(StringBuffer& str, CMimeMultiPart* multipart)
  369. {
  370. // comment this out to workaround a roxy bug that can not handle soap:Header
  371. str.append("<soap:Header>");
  372. ForEachItemIn(x, m_headerblocks)
  373. {
  374. IRpcMessage* oneblock = &(m_headerblocks.item(x));
  375. if(oneblock != NULL)
  376. {
  377. StringBuffer onebuf;
  378. oneblock->marshall(onebuf, multipart);;
  379. str.append(onebuf.str());
  380. }
  381. }
  382. str.append("</soap:Header>");
  383. return str;
  384. }
  385. void CHeader::unmarshall(XmlPullParser* xpp)
  386. {
  387. int type;
  388. StartTag stag;
  389. EndTag etag;
  390. while((type = xpp->next()) != XmlPullParser::END_DOCUMENT)
  391. {
  392. if(type == XmlPullParser::END_TAG)
  393. {
  394. xpp->readEndTag(etag);
  395. if(!stricmp(etag.getLocalName(), SOAP_HEADER_NAME))
  396. break;
  397. }
  398. else if(type == XmlPullParser::START_TAG) {
  399. xpp->readStartTag(stag);
  400. CRpcMessage *oneblock = new CRpcMessage(stag.getLocalName());
  401. StringBuffer ns;
  402. const char* qname = stag.getQName();
  403. const char* localname = stag.getLocalName();
  404. if(strlen(qname) > strlen(localname))
  405. {
  406. const char* semcol = strchr(qname, ':');
  407. if(semcol != NULL)
  408. {
  409. ns.append(qname, 0, semcol - qname);
  410. }
  411. }
  412. oneblock->set_ns(ns.str());
  413. oneblock->unmarshall(xpp);
  414. m_headerblocks.append(*oneblock);
  415. }
  416. }
  417. }
  418. void CEnvelope::unmarshall(XmlPullParser* xpp)
  419. {
  420. int type;
  421. StartTag stag;
  422. EndTag etag;
  423. while((type = xpp->next()) != XmlPullParser::END_DOCUMENT)
  424. {
  425. if(type == XmlPullParser::START_TAG) {
  426. xpp->readStartTag(stag);
  427. if(!stricmp(stag.getLocalName(), SOAP_HEADER_NAME))
  428. {
  429. m_header->unmarshall(xpp);
  430. /*
  431. IRpcMessage* oneblock = m_header->getHeaderBlock("Security");
  432. if(oneblock != NULL)
  433. {
  434. StringBuffer tmpbuf;
  435. oneblock->marshall(tmpbuf);
  436. DBGLOG("OK, we've got header - \n%s", tmpbuf.str());
  437. }
  438. else
  439. {
  440. DBGLOG("Not found!!!!");
  441. }
  442. */
  443. }
  444. else if(!stricmp(stag.getLocalName(), SOAP_BODY_NAME))
  445. {
  446. m_body->set_xpp(xpp);
  447. break;
  448. }
  449. }
  450. }
  451. }
  452. /*****************************************************************
  453. CSoapValue Implementation
  454. ******************************************************************/
  455. CSoapValue::CSoapValue(CSoapValue* soapvalue)
  456. {
  457. m_encode_xml=true;
  458. if(soapvalue != NULL)
  459. {
  460. m_ns.set(soapvalue->m_ns.get());
  461. m_name.set(soapvalue->m_name.get());
  462. m_type.set(soapvalue->m_type.get());
  463. m_value.append(soapvalue->m_value);
  464. ForEachItemIn(x, soapvalue->m_children)
  465. {
  466. CSoapValue& onechild = soapvalue->m_children.item(x);
  467. m_children.append(*LINK(&onechild));
  468. }
  469. IProperties* attrs = soapvalue->m_attributes;
  470. if (attrs)
  471. {
  472. m_attributes.setown(createProperties());
  473. Owned<IPropertyIterator> it = attrs->getIterator();
  474. for (it->first(); it->isValid(); it->next())
  475. m_attributes->setProp(it->getPropKey(), attrs->queryProp(it->getPropKey()));
  476. }
  477. m_is_array_element = soapvalue->m_is_array_element;
  478. }
  479. }
  480. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, const char* value, bool encode)
  481. {
  482. init(ns,name,type,value);
  483. m_encode_xml=encode;
  484. }
  485. void CSoapValue::init(const char* ns, const char* name, const char* type, const char* value)
  486. {
  487. m_ns.set(ns);
  488. m_name.set(name);
  489. m_type.set(type);
  490. m_value.append(value);
  491. m_is_array_element = false;
  492. }
  493. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, int value)
  494. {
  495. StringBuffer valstr;
  496. valstr.append(value);
  497. init(ns, name, type, valstr.str());
  498. }
  499. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, unsigned long value)
  500. {
  501. StringBuffer valstr;
  502. valstr.appendlong(value);
  503. init(ns, name, type, valstr.str());
  504. }
  505. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, __int64 value)
  506. {
  507. StringBuffer valstr;
  508. valstr.append(value);
  509. init(ns, name, type, valstr.str());
  510. }
  511. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, unsigned int value)
  512. {
  513. StringBuffer valstr;
  514. valstr.append(value);
  515. init(ns, name, type, valstr.str());
  516. }
  517. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, unsigned short value)
  518. {
  519. StringBuffer valstr;
  520. valstr.append(value);
  521. init(ns, name, type, valstr.str());
  522. }
  523. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, double value)
  524. {
  525. StringBuffer valstr;
  526. valstr.append(value);
  527. init(ns, name, type, valstr.str());
  528. }
  529. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, float value)
  530. {
  531. StringBuffer valstr;
  532. valstr.append(value);
  533. init(ns, name, type, valstr.str());
  534. }
  535. CSoapValue::CSoapValue(const char* ns, const char* name, const char* type, bool value)
  536. {
  537. StringBuffer valstr;
  538. valstr.append(value);
  539. init(ns, name, type, valstr.str());
  540. }
  541. const char* CSoapValue::query_attr_value(const char *path)
  542. {
  543. if (*path=='@')
  544. {
  545. if (!m_attributes)
  546. return NULL;
  547. return m_attributes->queryProp(path+1);
  548. }
  549. return NULL;
  550. }
  551. const char* CSoapValue::query_value(const char* path)
  552. {
  553. if(!path || !*path || *path=='.')
  554. return m_value.str();
  555. StringBuffer attrname;
  556. CSoapValue *elem = get_element(path, &attrname);
  557. if (!elem)
  558. return NULL;
  559. if (attrname.length())
  560. return elem->query_attr_value(attrname.str());
  561. return elem->query_value(NULL);
  562. }
  563. CSoapValue* CSoapValue::get_value(const char* path)
  564. {
  565. return get_element(path, NULL);
  566. }
  567. CSoapValue* CSoapValue::get_element(const char* path, StringBuffer *attrname)
  568. {
  569. if(!path || !*path || *path=='.')
  570. return this;
  571. if (*path=='@')
  572. {
  573. if (!attrname)
  574. return NULL;
  575. attrname->append(path);
  576. return this;
  577. }
  578. if(m_children.ordinality() == 0)
  579. return NULL;
  580. const char* slash = strchr(path, '/');
  581. StringBuffer childname;
  582. const char* nextname = NULL;
  583. int childind = -1;
  584. if(slash == NULL)
  585. {
  586. const char* lbracket = strchr(path, '[');
  587. if(lbracket == NULL)
  588. {
  589. childname.append(path);
  590. }
  591. else
  592. {
  593. const char* rbracket = strchr(path, ']');
  594. char* indexbuf = new char[rbracket - lbracket];
  595. int i = 0;
  596. for(i = 0; i < rbracket - lbracket - 1; i++)
  597. indexbuf[i] = lbracket[i + 1];
  598. indexbuf[i] = 0;
  599. childind = atoi(indexbuf);
  600. delete[] indexbuf;
  601. childname.append(path, 0, lbracket - path);
  602. }
  603. }
  604. else
  605. {
  606. const char* lbracket = strchr(path, '[');
  607. if(lbracket != NULL && lbracket < slash)
  608. {
  609. const char* rbracket = strchr(path, ']');
  610. char* indexbuf = new char[rbracket - lbracket];
  611. int len = rbracket - lbracket - 1;
  612. for(int i = 0; i < len; i++)
  613. indexbuf[i] = lbracket[i+1];
  614. indexbuf[len] = 0;
  615. childind = atoi(indexbuf);
  616. delete[] indexbuf;
  617. childname.append(path, 0, lbracket - path);
  618. }
  619. else
  620. {
  621. childname.append(path, 0, slash - path);
  622. }
  623. nextname = slash + 1;
  624. }
  625. int n_onechild = 0;
  626. ForEachItemIn(x, m_children)
  627. {
  628. CSoapValue& onechild = m_children.item(x);
  629. if(!strcmp(onechild.m_name.get(), childname.str()))
  630. {
  631. if(childind == -1 || ++n_onechild == childind)
  632. return onechild.get_element(nextname, attrname);
  633. }
  634. }
  635. return NULL;
  636. }
  637. SoapValueArray* CSoapValue::get_valuearray(const char* path)
  638. {
  639. CSoapValue* sv = get_value(path);
  640. if(sv != NULL)
  641. return &(sv->m_children);
  642. return NULL;
  643. }
  644. bool CSoapValue::get_value(const char* path, StringAttr& value)
  645. {
  646. const char *csval=query_value(path);
  647. value.set(csval);
  648. return csval!=NULL;
  649. }
  650. bool CSoapValue::get_value(const char* path, StringBuffer& value)
  651. {
  652. StringBuffer attrname;
  653. CSoapValue* sv = get_element(path, &attrname);
  654. if(sv != NULL)
  655. {
  656. //Yanrui - change it to return the whole content instead of just the value
  657. // please report if it's not desirable for any circumstances.
  658. //value.append(sv->m_value.str());
  659. if (attrname.length())
  660. {
  661. value.append(sv->query_value(attrname.str()));
  662. }
  663. else
  664. {
  665. sv->setEncodeXml(m_encode_xml);
  666. sv->serializeContent(value, NULL);
  667. }
  668. }
  669. return (sv != NULL);
  670. }
  671. bool CSoapValue::get_value_str(const char* path, StringBuffer& value)
  672. {
  673. const char *csval=query_value(path);
  674. value.append(csval);
  675. return csval!=NULL;
  676. }
  677. bool CSoapValue::get_value(const char* path, int& value)
  678. {
  679. const char *csval=query_value(path);
  680. if (csval && *csval)
  681. {
  682. value = atol(csval);
  683. return true;
  684. }
  685. return false;
  686. }
  687. bool CSoapValue::get_value(const char* path, unsigned long& value)
  688. {
  689. const char *csval=query_value(path);
  690. if (csval && *csval)
  691. {
  692. value = atol(csval);
  693. return true;
  694. }
  695. return false;
  696. }
  697. bool CSoapValue::get_value(const char* path, unsigned char& value)
  698. {
  699. const char *csval=query_value(path);
  700. if (csval && *csval)
  701. {
  702. value = (unsigned char)atol(csval);
  703. return true;
  704. }
  705. return false;
  706. }
  707. bool CSoapValue::get_value(const char* path, long& value)
  708. {
  709. const char *csval=query_value(path);
  710. if (csval && *csval)
  711. {
  712. value = atol(csval);
  713. return true;
  714. }
  715. return false;
  716. }
  717. bool CSoapValue::get_value(const char* path, __int64& value)
  718. {
  719. const char *csval=query_value(path);
  720. if (csval && *csval)
  721. {
  722. value = _atoi64(csval);
  723. return true;
  724. }
  725. return false;
  726. }
  727. bool CSoapValue::get_value(const char* path, unsigned int& value)
  728. {
  729. const char *csval=query_value(path);
  730. if (csval && *csval)
  731. {
  732. value = atoi(csval);
  733. return true;
  734. }
  735. return false;
  736. }
  737. bool CSoapValue::get_value(const char* path, unsigned short& value)
  738. {
  739. const char *csval=query_value(path);
  740. if (csval && *csval)
  741. {
  742. value = atoi(csval);
  743. return true;
  744. }
  745. return false;
  746. }
  747. bool CSoapValue::get_value(const char* path, short& value)
  748. {
  749. const char *csval=query_value(path);
  750. if (csval && *csval)
  751. {
  752. value = (short)atoi(csval);
  753. return true;
  754. }
  755. return false;
  756. }
  757. bool CSoapValue::get_value(const char* path, double& value)
  758. {
  759. const char *csval=query_value(path);
  760. if (csval && *csval)
  761. {
  762. value = atof(csval);
  763. return true;
  764. }
  765. return false;
  766. }
  767. bool CSoapValue::get_value(const char* path, float& value)
  768. {
  769. const char *csval=query_value(path);
  770. if (csval && *csval)
  771. {
  772. value = (float)atof(csval);
  773. return true;
  774. }
  775. return false;
  776. }
  777. bool CSoapValue::get_value(const char* path, bool& value)
  778. {
  779. const char *csval=query_value(path);
  780. if (csval && *csval)
  781. {
  782. value = streq(csval, "1") || strieq(csval, "true");
  783. return true;
  784. }
  785. return false;
  786. }
  787. bool CSoapValue::get_value(const char* path, StringArray& value, bool simpleXml)
  788. {
  789. CSoapValue* sv = get_value(path);
  790. if(sv != NULL)
  791. {
  792. ForEachItemIn(x, sv->m_children)
  793. {
  794. CSoapValue& onechild = sv->m_children.item(x);
  795. onechild.setEncodeXml(m_encode_xml);
  796. StringBuffer tmpval;
  797. if (simpleXml)
  798. onechild.simple_serializeChildren(tmpval);
  799. else
  800. onechild.serializeContent(tmpval, NULL);
  801. value.append(tmpval.str());
  802. }
  803. }
  804. return (sv != NULL);
  805. }
  806. bool CSoapValue::get_value(const char* path, IntArray& value)
  807. {
  808. CSoapValue* sv = get_value(path);
  809. if(sv != NULL)
  810. {
  811. ForEachItemIn(x, sv->m_children)
  812. {
  813. CSoapValue& onechild = sv->m_children.item(x);
  814. onechild.setEncodeXml(m_encode_xml);
  815. StringBuffer tmpval;
  816. onechild.serializeContent(tmpval, NULL);
  817. value.append(atoi(tmpval));
  818. }
  819. }
  820. return (sv != NULL);
  821. }
  822. bool CSoapValue::get_value(const char* path, ShortArray& value)
  823. {
  824. CSoapValue* sv = get_value(path);
  825. if(sv != NULL)
  826. {
  827. ForEachItemIn(x, sv->m_children)
  828. {
  829. CSoapValue& onechild = sv->m_children.item(x);
  830. onechild.setEncodeXml(m_encode_xml);
  831. StringBuffer tmpval;
  832. onechild.serializeContent(tmpval, NULL);
  833. value.append(atoi(tmpval));
  834. }
  835. }
  836. return (sv != NULL);
  837. }
  838. bool CSoapValue::get_value(const char* path, Int64Array& value)
  839. {
  840. CSoapValue* sv = get_value(path);
  841. if(sv != NULL)
  842. {
  843. ForEachItemIn(x, sv->m_children)
  844. {
  845. CSoapValue& onechild = sv->m_children.item(x);
  846. onechild.setEncodeXml(m_encode_xml);
  847. StringBuffer tmpval;
  848. onechild.serializeContent(tmpval, NULL);
  849. value.append(atoi64(tmpval));
  850. }
  851. }
  852. return (sv != NULL);
  853. }
  854. bool CSoapValue::get_value(const char* path, BoolArray& value)
  855. {
  856. CSoapValue* sv = get_value(path);
  857. if(sv != NULL)
  858. {
  859. ForEachItemIn(x, sv->m_children)
  860. {
  861. CSoapValue& onechild = sv->m_children.item(x);
  862. onechild.setEncodeXml(m_encode_xml);
  863. StringBuffer tmpval;
  864. onechild.serializeContent(tmpval, NULL);
  865. value.append( (strcmp(tmpval,"true")==0||strcmp(tmpval,"1")==0) ? true : false);
  866. }
  867. }
  868. return (sv != NULL);
  869. }
  870. bool CSoapValue::get_value(const char* path, FloatArray& value)
  871. {
  872. CSoapValue* sv = get_value(path);
  873. if(sv != NULL)
  874. {
  875. ForEachItemIn(x, sv->m_children)
  876. {
  877. CSoapValue& onechild = sv->m_children.item(x);
  878. onechild.setEncodeXml(m_encode_xml);
  879. StringBuffer tmpval;
  880. onechild.serializeContent(tmpval, NULL);
  881. value.append((float)atof(tmpval));
  882. }
  883. }
  884. return (sv != NULL);
  885. }
  886. bool CSoapValue::get_value(const char* path, DoubleArray& value)
  887. {
  888. CSoapValue* sv = get_value(path);
  889. if(sv != NULL)
  890. {
  891. ForEachItemIn(x, sv->m_children)
  892. {
  893. CSoapValue& onechild = sv->m_children.item(x);
  894. onechild.setEncodeXml(m_encode_xml);
  895. StringBuffer tmpval;
  896. onechild.serializeContent(tmpval, NULL);
  897. value.append(atof(tmpval));
  898. }
  899. }
  900. return (sv != NULL);
  901. }
  902. bool CSoapValue::get_value(const char* path, StringBuffer& value, bool simpleXml)
  903. {
  904. CSoapValue* sv = get_value(path);
  905. if(sv != NULL)
  906. {
  907. sv->setEncodeXml(m_encode_xml);
  908. if (simpleXml)
  909. sv->simple_serialize(value);
  910. else
  911. sv->serializeContent(value, NULL);
  912. }
  913. return (sv != NULL);
  914. }
  915. CSoapValue* CSoapValue::ensure(const char* ns, const char* path)
  916. {
  917. CSoapValue* sv = get_value(path);
  918. if(sv != NULL)
  919. return sv;
  920. if(path == NULL || strlen(path) == 0)
  921. return this;
  922. const char* rslash = strrchr(path, '/');
  923. if(rslash == NULL)
  924. {
  925. const char* pEnd = strchr(path, '[');
  926. if (!pEnd)
  927. pEnd = path + strlen(path);
  928. StringBuffer name(pEnd - path, path);
  929. CSoapValue* child = new CSoapValue(ns, name.str(), "", "",m_encode_xml);
  930. this->add_child(child);
  931. return child;
  932. }
  933. else
  934. {
  935. StringBuffer parentpath;
  936. parentpath.append(path, 0, rslash - path);
  937. CSoapValue* parent = ensure(ns, parentpath.str());
  938. if(parent != NULL)
  939. {
  940. const char* pEnd = strchr(++rslash, '[');
  941. if (!pEnd)
  942. pEnd = rslash + strlen(rslash);
  943. StringBuffer name(pEnd - rslash, rslash);
  944. CSoapValue* child = new CSoapValue(ns, name.str(), "", "",m_encode_xml);
  945. parent->add_child(child);
  946. return child;
  947. }
  948. }
  949. return NULL;
  950. }
  951. void CSoapValue::add_child(CSoapValue* child)
  952. {
  953. if(child)
  954. m_children.append(*child);
  955. }
  956. //Note: value is now owned by the current SoapValue, so shouldn't be freed outside.
  957. void CSoapValue::add_value(const char* path, const char* ns, CSoapValue* value)
  958. {
  959. CSoapValue* sv = ensure(ns, path);
  960. if(sv != NULL)
  961. {
  962. sv->add_child(value);
  963. }
  964. }
  965. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, SoapValueArray& valuearray)
  966. {
  967. CSoapValue* sv = ensure(ns, path);
  968. if(sv != NULL)
  969. {
  970. int len = valuearray.length();
  971. StringBuffer typestr;
  972. if(type != NULL && strlen(type) > 0)
  973. {
  974. typestr.append(type);
  975. typestr.append("[");
  976. typestr.append(len);
  977. typestr.append("]");
  978. }
  979. CSoapValue* child = new CSoapValue(ns, name, typestr.str(), (const char*) NULL,m_encode_xml);
  980. ForEachItemIn(x, valuearray)
  981. {
  982. CSoapValue& onechild = valuearray.item(x);
  983. child->m_children.append(*LINK(&onechild));
  984. }
  985. sv->add_child(child);
  986. }
  987. }
  988. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, const char* value, bool encodeXml)
  989. {
  990. CSoapValue* sv = ensure(ns, path);
  991. if(sv != NULL)
  992. {
  993. sv->add_child(new CSoapValue(ns, name, type, value, encodeXml));
  994. }
  995. }
  996. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, const char* value, IProperties& attrs)
  997. {
  998. CSoapValue* sv = ensure(ns, path);
  999. if(sv != NULL)
  1000. {
  1001. if (name && *name)
  1002. {
  1003. CSoapValue* child = new CSoapValue(ns, name, type, value, false);
  1004. sv->add_child(child);
  1005. sv = child;
  1006. }
  1007. Owned<IPropertyIterator> piter = attrs.getIterator();
  1008. for (piter->first(); piter->isValid(); piter->next())
  1009. {
  1010. const char *propkey = piter->getPropKey();
  1011. sv->add_attribute(propkey, attrs.queryProp(propkey));
  1012. }
  1013. }
  1014. }
  1015. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, const char* value)
  1016. {
  1017. CSoapValue* sv = ensure(ns, path);
  1018. if(sv != NULL)
  1019. {
  1020. if (name && *name)
  1021. sv->add_child(new CSoapValue(ns, name, type, value, m_encode_xml));
  1022. else
  1023. sv->m_value.append(value);
  1024. }
  1025. }
  1026. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, int value)
  1027. {
  1028. CSoapValue* sv = ensure(ns, path);
  1029. if(sv != NULL)
  1030. {
  1031. StringBuffer longstr;
  1032. longstr.append(value);
  1033. if (name && *name)
  1034. sv->add_child(new CSoapValue(ns, name, type, longstr.str(), m_encode_xml));
  1035. else
  1036. sv->m_value.append(longstr);
  1037. }
  1038. }
  1039. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, double value)
  1040. {
  1041. CSoapValue* sv = ensure(ns, path);
  1042. if(sv != NULL)
  1043. {
  1044. StringBuffer longstr;
  1045. longstr.append(value);
  1046. if (name && *name)
  1047. sv->add_child(new CSoapValue(ns, name, type, longstr.str(), m_encode_xml));
  1048. else
  1049. sv->m_value.append(longstr);
  1050. }
  1051. }
  1052. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, float value)
  1053. {
  1054. CSoapValue* sv = ensure(ns, path);
  1055. if(sv != NULL)
  1056. {
  1057. StringBuffer longstr;
  1058. longstr.append(value);
  1059. if (name && *name)
  1060. sv->add_child(new CSoapValue(ns, name, type, longstr.str(), m_encode_xml));
  1061. else
  1062. sv->m_value.append(longstr);
  1063. }
  1064. }
  1065. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, unsigned long value)
  1066. {
  1067. CSoapValue* sv = ensure(ns, path);
  1068. if(sv != NULL)
  1069. {
  1070. StringBuffer longstr;
  1071. longstr.appendulong(value);
  1072. if (name && *name)
  1073. sv->add_child(new CSoapValue(ns, name, type, longstr.str(), m_encode_xml));
  1074. else
  1075. sv->m_value.append(longstr);
  1076. }
  1077. }
  1078. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, long value)
  1079. {
  1080. CSoapValue* sv = ensure(ns, path);
  1081. if(sv != NULL)
  1082. {
  1083. StringBuffer longstr;
  1084. longstr.appendlong(value);
  1085. if (name && *name)
  1086. sv->add_child(new CSoapValue(ns, name, type, longstr.str(), m_encode_xml));
  1087. else
  1088. sv->m_value.append(longstr);
  1089. }
  1090. }
  1091. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, __int64 value)
  1092. {
  1093. CSoapValue* sv = ensure(ns, path);
  1094. if(sv != NULL)
  1095. {
  1096. StringBuffer longstr;
  1097. longstr.append(value);
  1098. if (name && *name)
  1099. sv->add_child(new CSoapValue(ns, name, type, longstr.str(), m_encode_xml));
  1100. else
  1101. sv->m_value.append(longstr);
  1102. }
  1103. }
  1104. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, unsigned int value)
  1105. {
  1106. CSoapValue* sv = ensure(ns, path);
  1107. if(sv != NULL)
  1108. {
  1109. StringBuffer valstr;
  1110. valstr.append(value);
  1111. if (name && *name)
  1112. sv->add_child(new CSoapValue(ns, name, type, valstr.str(), m_encode_xml));
  1113. else
  1114. sv->m_value.append(valstr);
  1115. }
  1116. }
  1117. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, unsigned short value)
  1118. {
  1119. CSoapValue* sv = ensure(ns, path);
  1120. if(sv != NULL)
  1121. {
  1122. StringBuffer valstr;
  1123. valstr.append(value);
  1124. if (name && *name)
  1125. sv->add_child(new CSoapValue(ns, name, type, valstr.str(), m_encode_xml));
  1126. else
  1127. sv->m_value.append(valstr);
  1128. }
  1129. }
  1130. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* type, bool value)
  1131. {
  1132. CSoapValue* sv = ensure(ns, path);
  1133. if(sv != NULL)
  1134. {
  1135. StringBuffer valstr(value ? "1" : "0");
  1136. if (name && *name)
  1137. sv->add_child(new CSoapValue(ns, name, type, valstr.str(), m_encode_xml));
  1138. else
  1139. sv->m_value.append(valstr);
  1140. }
  1141. }
  1142. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1143. const char* childname, const char* childtype, StringArray& value)
  1144. {
  1145. CSoapValue* sv = ensure(ns, path);
  1146. if(sv != NULL)
  1147. {
  1148. int len = value.length();
  1149. StringBuffer typestr;
  1150. typestr.append("string[");
  1151. typestr.append(len);
  1152. typestr.append("]");
  1153. CSoapValue* child = new CSoapValue(ns, name, typestr.str(), (const char*) NULL, m_encode_xml);
  1154. ForEachItemIn(x, value)
  1155. {
  1156. const char* oneelem = (const char*)value.item(x);
  1157. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem, m_encode_xml);
  1158. onechild->m_is_array_element = true;
  1159. child->add_child(onechild);
  1160. }
  1161. sv->add_child(child);
  1162. }
  1163. }
  1164. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1165. const char* childname, const char* childtype, IntArray& value)
  1166. {
  1167. CSoapValue* sv = ensure(ns, path);
  1168. if(sv != NULL)
  1169. {
  1170. CSoapValue* child = new CSoapValue(ns, name, "int", (const char*) NULL, m_encode_xml);
  1171. ForEachItemIn(x, value)
  1172. {
  1173. int oneelem = value.item(x);
  1174. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem);
  1175. onechild->m_is_array_element = true;
  1176. child->add_child(onechild);
  1177. }
  1178. sv->add_child(child);
  1179. }
  1180. }
  1181. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1182. const char* childname, const char* childtype, ShortArray& value)
  1183. {
  1184. CSoapValue* sv = ensure(ns, path);
  1185. if(sv != NULL)
  1186. {
  1187. CSoapValue* child = new CSoapValue(ns, name, "int", (const char*) NULL, m_encode_xml);
  1188. ForEachItemIn(x, value)
  1189. {
  1190. short oneelem = value.item(x);
  1191. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem);
  1192. onechild->m_is_array_element = true;
  1193. child->add_child(onechild);
  1194. }
  1195. sv->add_child(child);
  1196. }
  1197. }
  1198. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1199. const char* childname, const char* childtype, Int64Array& value)
  1200. {
  1201. CSoapValue* sv = ensure(ns, path);
  1202. if(sv != NULL)
  1203. {
  1204. CSoapValue* child = new CSoapValue(ns, name, "int", (const char*) NULL, m_encode_xml);
  1205. ForEachItemIn(x, value)
  1206. {
  1207. __int64 oneelem = value.item(x);
  1208. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem);
  1209. onechild->m_is_array_element = true;
  1210. child->add_child(onechild);
  1211. }
  1212. sv->add_child(child);
  1213. }
  1214. }
  1215. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1216. const char* childname, const char* childtype, BoolArray& value)
  1217. {
  1218. CSoapValue* sv = ensure(ns, path);
  1219. if(sv != NULL)
  1220. {
  1221. CSoapValue* child = new CSoapValue(ns, name, "int", (const char*) NULL, m_encode_xml);
  1222. ForEachItemIn(x, value)
  1223. {
  1224. bool oneelem = value.item(x);
  1225. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem);
  1226. onechild->m_is_array_element = true;
  1227. child->add_child(onechild);
  1228. }
  1229. sv->add_child(child);
  1230. }
  1231. }
  1232. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1233. const char* childname, const char* childtype, FloatArray& value)
  1234. {
  1235. CSoapValue* sv = ensure(ns, path);
  1236. if(sv != NULL)
  1237. {
  1238. CSoapValue* child = new CSoapValue(ns, name, "int", (const char*) NULL, m_encode_xml);
  1239. ForEachItemIn(x, value)
  1240. {
  1241. float oneelem = value.item(x);
  1242. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem);
  1243. onechild->m_is_array_element = true;
  1244. child->add_child(onechild);
  1245. }
  1246. sv->add_child(child);
  1247. }
  1248. }
  1249. void CSoapValue::add_value(const char* path, const char* ns, const char* name, const char* childns,
  1250. const char* childname, const char* childtype, DoubleArray& value)
  1251. {
  1252. CSoapValue* sv = ensure(ns, path);
  1253. if(sv != NULL)
  1254. {
  1255. CSoapValue* child = new CSoapValue(ns, name, "int", (const char*) NULL, m_encode_xml);
  1256. ForEachItemIn(x, value)
  1257. {
  1258. double oneelem = value.item(x);
  1259. CSoapValue* onechild = new CSoapValue(childns, childname, childtype, oneelem);
  1260. onechild->m_is_array_element = true;
  1261. child->add_child(onechild);
  1262. }
  1263. sv->add_child(child);
  1264. }
  1265. }
  1266. void CSoapValue::add_attribute(const char* name, const char* value)
  1267. {
  1268. if (!name || !*name)
  1269. return;
  1270. if (!m_attributes)
  1271. m_attributes.setown(createProperties());
  1272. m_attributes->setProp(name, value);
  1273. }
  1274. void CSoapValue::serializeChildren(StringBuffer& outbuf, CMimeMultiPart* multipart)
  1275. {
  1276. ForEachItemIn(x, m_children)
  1277. {
  1278. CSoapValue& onechild = m_children.item(x);
  1279. onechild.serialize(outbuf, multipart);
  1280. }
  1281. }
  1282. void CSoapValue::serialize(StringBuffer& outbuf, CMimeMultiPart* multipart)
  1283. {
  1284. outbuf.append("<");
  1285. if(m_ns.length() > 0)
  1286. {
  1287. outbuf.append(m_ns.get());
  1288. outbuf.append(":");
  1289. }
  1290. outbuf.append(m_name.get());
  1291. if(m_type.length() > 0 && !stricmp(m_type.get(), "Attachment"))
  1292. {
  1293. if(m_value.length() > 0)
  1294. {
  1295. outbuf.append(" href=\"cid:").append(m_name.get()).append("\"/>");
  1296. CMimeBodyPart* onepart = new CMimeBodyPart("text/xml", "8bit", m_name.get(), "", &m_value);
  1297. multipart->addBodyPart(onepart);
  1298. }
  1299. else
  1300. {
  1301. outbuf.append("/>");
  1302. }
  1303. }
  1304. else
  1305. {
  1306. /* // we don't serialize type else where
  1307. if(m_type.length() > 0)
  1308. {
  1309. const char* lbracket = strchr(m_type.get(), '[');
  1310. const char* type_ns;
  1311. if(!m_is_array_element)
  1312. type_ns = "SOAP-ENC";
  1313. else
  1314. type_ns = "xsi";
  1315. if(lbracket != NULL)
  1316. {
  1317. outbuf.append(" ").append(type_ns).append(":arrayType=\"xsd:");
  1318. }
  1319. else
  1320. {
  1321. outbuf.append(" ").append(type_ns).append(":type=\"xsd:");
  1322. }
  1323. outbuf.append(m_type.get()).append("\"");
  1324. }
  1325. */
  1326. serialize_attributes(outbuf);
  1327. outbuf.append(">");
  1328. if(m_value.length() > 0)
  1329. {
  1330. if (m_encode_xml)
  1331. encodeUtf8XML(m_value.str(), outbuf);
  1332. else
  1333. outbuf.append(m_value.str());
  1334. }
  1335. StringBuffer childrenbuf;
  1336. serializeChildren(childrenbuf, multipart);
  1337. outbuf.append(childrenbuf);
  1338. outbuf.append("</");
  1339. if(m_ns.length() > 0)
  1340. {
  1341. outbuf.append(m_ns.get());
  1342. outbuf.append(":");
  1343. }
  1344. outbuf.append(m_name.get());
  1345. outbuf.append(">");
  1346. }
  1347. }
  1348. void CSoapValue::serializeContent(StringBuffer& outbuf, CMimeMultiPart* multipart)
  1349. {
  1350. if(m_value.length() > 0)
  1351. {
  1352. if (m_encode_xml)
  1353. {
  1354. StringBuffer encoded_value;
  1355. encodeUtf8XML(m_value.str(), encoded_value);
  1356. outbuf.append(encoded_value.str());
  1357. }
  1358. else
  1359. {
  1360. outbuf.append(m_value.str());
  1361. }
  1362. }
  1363. StringBuffer childrenbuf;
  1364. serializeChildren(childrenbuf, multipart);
  1365. outbuf.append(childrenbuf);
  1366. }
  1367. void CSoapValue::simple_serializeChildren(StringBuffer& outbuf)
  1368. {
  1369. ForEachItemIn(x, m_children)
  1370. {
  1371. CSoapValue& onechild = m_children.item(x);
  1372. onechild.simple_serialize(outbuf);
  1373. }
  1374. }
  1375. inline bool isWhiteSpace(const char ch){return (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r');}
  1376. void CSoapValue::serialize_attributes(StringBuffer& outbuf)
  1377. {
  1378. ::serializeAttributes(outbuf,m_attributes);
  1379. }
  1380. void CSoapValue::simple_serialize(StringBuffer& outbuf)
  1381. {
  1382. outbuf.append("<").append(m_name.get()).append(">");
  1383. serialize_attributes(outbuf);
  1384. if(m_value.length() > 0)
  1385. {
  1386. bool allwhite=true;
  1387. for(const char *finger=m_value.str(); *finger && allwhite; finger++)
  1388. allwhite = isWhiteSpace(*finger);
  1389. if (!allwhite)
  1390. encodeUtf8XML(m_value.str(), outbuf);
  1391. }
  1392. StringBuffer childrenbuf;
  1393. simple_serializeChildren(childrenbuf);
  1394. outbuf.append(childrenbuf);
  1395. outbuf.append("</").append(m_name.get()).append(">");
  1396. }