PageRenderTime 91ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llxml/llxmlnode.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2899 lines | 2743 code | 75 blank | 81 comment | 219 complexity | 45bdae29a3554ef9d06b18e382a20d72 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llxmlnode.cpp
  3. * @author Tom Yedwab
  4. * @brief LLXMLNode implementation
  5. *
  6. * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "linden_common.h"
  28. #include <iostream>
  29. #include <map>
  30. #include "llxmlnode.h"
  31. #include "v3color.h"
  32. #include "v4color.h"
  33. #include "v4coloru.h"
  34. #include "v3math.h"
  35. #include "v3dmath.h"
  36. #include "v4math.h"
  37. #include "llquaternion.h"
  38. #include "llstring.h"
  39. #include "lluuid.h"
  40. #include "lldir.h"
  41. const S32 MAX_COLUMN_WIDTH = 80;
  42. // static
  43. BOOL LLXMLNode::sStripEscapedStrings = TRUE;
  44. BOOL LLXMLNode::sStripWhitespaceValues = FALSE;
  45. LLXMLNode::LLXMLNode() :
  46. mID(""),
  47. mParser(NULL),
  48. mIsAttribute(FALSE),
  49. mVersionMajor(0),
  50. mVersionMinor(0),
  51. mLength(0),
  52. mPrecision(64),
  53. mType(TYPE_CONTAINER),
  54. mEncoding(ENCODING_DEFAULT),
  55. mLineNumber(-1),
  56. mParent(NULL),
  57. mChildren(NULL),
  58. mAttributes(),
  59. mPrev(NULL),
  60. mNext(NULL),
  61. mName(NULL),
  62. mValue(""),
  63. mDefault(NULL)
  64. {
  65. }
  66. LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) :
  67. mID(""),
  68. mParser(NULL),
  69. mIsAttribute(is_attribute),
  70. mVersionMajor(0),
  71. mVersionMinor(0),
  72. mLength(0),
  73. mPrecision(64),
  74. mType(TYPE_CONTAINER),
  75. mEncoding(ENCODING_DEFAULT),
  76. mLineNumber(-1),
  77. mParent(NULL),
  78. mChildren(NULL),
  79. mAttributes(),
  80. mPrev(NULL),
  81. mNext(NULL),
  82. mValue(""),
  83. mDefault(NULL)
  84. {
  85. mName = gStringTable.addStringEntry(name);
  86. }
  87. LLXMLNode::LLXMLNode(LLStringTableEntry* name, BOOL is_attribute) :
  88. mID(""),
  89. mParser(NULL),
  90. mIsAttribute(is_attribute),
  91. mVersionMajor(0),
  92. mVersionMinor(0),
  93. mLength(0),
  94. mPrecision(64),
  95. mType(TYPE_CONTAINER),
  96. mEncoding(ENCODING_DEFAULT),
  97. mLineNumber(-1),
  98. mParent(NULL),
  99. mChildren(NULL),
  100. mAttributes(),
  101. mPrev(NULL),
  102. mNext(NULL),
  103. mName(name),
  104. mValue(""),
  105. mDefault(NULL)
  106. {
  107. }
  108. // copy constructor (except for the children)
  109. LLXMLNode::LLXMLNode(const LLXMLNode& rhs) :
  110. mID(rhs.mID),
  111. mIsAttribute(rhs.mIsAttribute),
  112. mVersionMajor(rhs.mVersionMajor),
  113. mVersionMinor(rhs.mVersionMinor),
  114. mLength(rhs.mLength),
  115. mPrecision(rhs.mPrecision),
  116. mType(rhs.mType),
  117. mEncoding(rhs.mEncoding),
  118. mLineNumber(0),
  119. mParser(NULL),
  120. mParent(NULL),
  121. mChildren(NULL),
  122. mAttributes(),
  123. mPrev(NULL),
  124. mNext(NULL),
  125. mName(rhs.mName),
  126. mValue(rhs.mValue),
  127. mDefault(rhs.mDefault)
  128. {
  129. }
  130. // returns a new copy of this node and all its children
  131. LLXMLNodePtr LLXMLNode::deepCopy()
  132. {
  133. LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this));
  134. if (mChildren.notNull())
  135. {
  136. for (LLXMLChildList::iterator iter = mChildren->map.begin();
  137. iter != mChildren->map.end(); ++iter)
  138. {
  139. newnode->addChild(iter->second->deepCopy());
  140. }
  141. }
  142. for (LLXMLAttribList::iterator iter = mAttributes.begin();
  143. iter != mAttributes.end(); ++iter)
  144. {
  145. newnode->addChild(iter->second->deepCopy());
  146. }
  147. return newnode;
  148. }
  149. // virtual
  150. LLXMLNode::~LLXMLNode()
  151. {
  152. // Strictly speaking none of this should be required execept 'delete mChildren'...
  153. // Sadly, that's only true if we hadn't had reference-counted smart pointers linked
  154. // in three different directions. This entire class is a frightening, hard-to-maintain
  155. // mess.
  156. if (mChildren.notNull())
  157. {
  158. for (LLXMLChildList::iterator iter = mChildren->map.begin();
  159. iter != mChildren->map.end(); ++iter)
  160. {
  161. LLXMLNodePtr child = iter->second;
  162. child->mParent = NULL;
  163. child->mNext = NULL;
  164. child->mPrev = NULL;
  165. }
  166. mChildren->map.clear();
  167. mChildren->head = NULL;
  168. mChildren->tail = NULL;
  169. mChildren = NULL;
  170. }
  171. for (LLXMLAttribList::iterator iter = mAttributes.begin();
  172. iter != mAttributes.end(); ++iter)
  173. {
  174. LLXMLNodePtr attr = iter->second;
  175. attr->mParent = NULL;
  176. attr->mNext = NULL;
  177. attr->mPrev = NULL;
  178. }
  179. llassert(mParent == NULL);
  180. mDefault = NULL;
  181. }
  182. BOOL LLXMLNode::isNull()
  183. {
  184. return (mName == NULL);
  185. }
  186. // protected
  187. BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
  188. {
  189. if (!target_child)
  190. {
  191. return FALSE;
  192. }
  193. if (target_child->mIsAttribute)
  194. {
  195. LLXMLAttribList::iterator children_itr = mAttributes.find(target_child->mName);
  196. if (children_itr != mAttributes.end())
  197. {
  198. target_child->mParent = NULL;
  199. mAttributes.erase(children_itr);
  200. return TRUE;
  201. }
  202. }
  203. else if (mChildren.notNull())
  204. {
  205. LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName);
  206. while (children_itr != mChildren->map.end())
  207. {
  208. if (target_child == children_itr->second)
  209. {
  210. if (target_child == mChildren->head)
  211. {
  212. mChildren->head = target_child->mNext;
  213. }
  214. if (target_child == mChildren->tail)
  215. {
  216. mChildren->tail = target_child->mPrev;
  217. }
  218. LLXMLNodePtr prev = target_child->mPrev;
  219. LLXMLNodePtr next = target_child->mNext;
  220. if (prev.notNull()) prev->mNext = next;
  221. if (next.notNull()) next->mPrev = prev;
  222. target_child->mPrev = NULL;
  223. target_child->mNext = NULL;
  224. target_child->mParent = NULL;
  225. mChildren->map.erase(children_itr);
  226. if (mChildren->map.empty())
  227. {
  228. mChildren = NULL;
  229. }
  230. return TRUE;
  231. }
  232. else if (children_itr->first != target_child->mName)
  233. {
  234. break;
  235. }
  236. else
  237. {
  238. ++children_itr;
  239. }
  240. }
  241. }
  242. return FALSE;
  243. }
  244. void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
  245. {
  246. if (new_child->mParent != NULL)
  247. {
  248. if (new_child->mParent == this)
  249. {
  250. return;
  251. }
  252. new_child->mParent->removeChild(new_child);
  253. }
  254. new_child->mParent = this;
  255. if (new_child->mIsAttribute)
  256. {
  257. mAttributes.insert(std::make_pair(new_child->mName, new_child));
  258. }
  259. else
  260. {
  261. if (mChildren.isNull())
  262. {
  263. mChildren = new LLXMLChildren();
  264. mChildren->head = new_child;
  265. mChildren->tail = new_child;
  266. }
  267. mChildren->map.insert(std::make_pair(new_child->mName, new_child));
  268. // if after_child is specified, it damn well better be in the list of children
  269. // for this node. I'm not going to assert that, because it would be expensive,
  270. // but don't specify that parameter if you didn't get the value for it from the
  271. // list of children of this node!
  272. if (after_child.isNull())
  273. {
  274. if (mChildren->tail != new_child)
  275. {
  276. mChildren->tail->mNext = new_child;
  277. new_child->mPrev = mChildren->tail;
  278. mChildren->tail = new_child;
  279. }
  280. }
  281. // if after_child == parent, then put new_child at beginning
  282. else if (after_child == this)
  283. {
  284. // add to front of list
  285. new_child->mNext = mChildren->head;
  286. if (mChildren->head)
  287. {
  288. mChildren->head->mPrev = new_child;
  289. mChildren->head = new_child;
  290. }
  291. else // no children
  292. {
  293. mChildren->head = new_child;
  294. mChildren->tail = new_child;
  295. }
  296. }
  297. else
  298. {
  299. if (after_child->mNext.notNull())
  300. {
  301. // if after_child was not the last item, fix up some pointers
  302. after_child->mNext->mPrev = new_child;
  303. new_child->mNext = after_child->mNext;
  304. }
  305. new_child->mPrev = after_child;
  306. after_child->mNext = new_child;
  307. if (mChildren->tail == after_child)
  308. {
  309. mChildren->tail = new_child;
  310. }
  311. }
  312. }
  313. new_child->updateDefault();
  314. }
  315. // virtual
  316. LLXMLNodePtr LLXMLNode::createChild(const char* name, BOOL is_attribute)
  317. {
  318. return createChild(gStringTable.addStringEntry(name), is_attribute);
  319. }
  320. // virtual
  321. LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, BOOL is_attribute)
  322. {
  323. LLXMLNode* ret = new LLXMLNode(name, is_attribute);
  324. ret->mID.clear();
  325. addChild(ret);
  326. return ret;
  327. }
  328. BOOL LLXMLNode::deleteChild(LLXMLNode *child)
  329. {
  330. if (removeChild(child))
  331. {
  332. return TRUE;
  333. }
  334. return FALSE;
  335. }
  336. void LLXMLNode::setParent(LLXMLNodePtr new_parent)
  337. {
  338. if (new_parent.notNull())
  339. {
  340. new_parent->addChild(this);
  341. }
  342. else
  343. {
  344. if (mParent != NULL)
  345. {
  346. LLXMLNodePtr old_parent = mParent;
  347. mParent = NULL;
  348. old_parent->removeChild(this);
  349. }
  350. }
  351. }
  352. void LLXMLNode::updateDefault()
  353. {
  354. if (mParent != NULL && !mParent->mDefault.isNull())
  355. {
  356. mDefault = NULL;
  357. // Find default value in parent's default tree
  358. if (!mParent->mDefault.isNull())
  359. {
  360. findDefault(mParent->mDefault);
  361. }
  362. }
  363. if (mChildren.notNull())
  364. {
  365. LLXMLChildList::const_iterator children_itr;
  366. LLXMLChildList::const_iterator children_end = mChildren->map.end();
  367. for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr)
  368. {
  369. LLXMLNodePtr child = (*children_itr).second;
  370. child->updateDefault();
  371. }
  372. }
  373. }
  374. void XMLCALL StartXMLNode(void *userData,
  375. const XML_Char *name,
  376. const XML_Char **atts)
  377. {
  378. // Create a new node
  379. LLXMLNode *new_node_ptr = new LLXMLNode(name, FALSE);
  380. LLXMLNodePtr new_node = new_node_ptr;
  381. new_node->mID.clear();
  382. LLXMLNodePtr ptr_new_node = new_node;
  383. // Set the parent-child relationship with the current active node
  384. LLXMLNode* parent = (LLXMLNode *)userData;
  385. if (NULL == parent)
  386. {
  387. llwarns << "parent (userData) is NULL; aborting function" << llendl;
  388. return;
  389. }
  390. new_node_ptr->mParser = parent->mParser;
  391. new_node_ptr->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser));
  392. // Set the current active node to the new node
  393. XML_Parser *parser = parent->mParser;
  394. XML_SetUserData(*parser, (void *)new_node_ptr);
  395. // Parse attributes
  396. U32 pos = 0;
  397. while (atts[pos] != NULL)
  398. {
  399. std::string attr_name = atts[pos];
  400. std::string attr_value = atts[pos+1];
  401. // Special cases
  402. if ('i' == attr_name[0] && "id" == attr_name)
  403. {
  404. new_node->mID = attr_value;
  405. }
  406. else if ('v' == attr_name[0] && "version" == attr_name)
  407. {
  408. U32 version_major = 0;
  409. U32 version_minor = 0;
  410. if (sscanf(attr_value.c_str(), "%d.%d", &version_major, &version_minor) > 0)
  411. {
  412. new_node->mVersionMajor = version_major;
  413. new_node->mVersionMinor = version_minor;
  414. }
  415. }
  416. else if (('s' == attr_name[0] && "size" == attr_name) || ('l' == attr_name[0] && "length" == attr_name))
  417. {
  418. U32 length;
  419. if (sscanf(attr_value.c_str(), "%d", &length) > 0)
  420. {
  421. new_node->mLength = length;
  422. }
  423. }
  424. else if ('p' == attr_name[0] && "precision" == attr_name)
  425. {
  426. U32 precision;
  427. if (sscanf(attr_value.c_str(), "%d", &precision) > 0)
  428. {
  429. new_node->mPrecision = precision;
  430. }
  431. }
  432. else if ('t' == attr_name[0] && "type" == attr_name)
  433. {
  434. if ("boolean" == attr_value)
  435. {
  436. new_node->mType = LLXMLNode::TYPE_BOOLEAN;
  437. }
  438. else if ("integer" == attr_value)
  439. {
  440. new_node->mType = LLXMLNode::TYPE_INTEGER;
  441. }
  442. else if ("float" == attr_value)
  443. {
  444. new_node->mType = LLXMLNode::TYPE_FLOAT;
  445. }
  446. else if ("string" == attr_value)
  447. {
  448. new_node->mType = LLXMLNode::TYPE_STRING;
  449. }
  450. else if ("uuid" == attr_value)
  451. {
  452. new_node->mType = LLXMLNode::TYPE_UUID;
  453. }
  454. else if ("noderef" == attr_value)
  455. {
  456. new_node->mType = LLXMLNode::TYPE_NODEREF;
  457. }
  458. }
  459. else if ('e' == attr_name[0] && "encoding" == attr_name)
  460. {
  461. if ("decimal" == attr_value)
  462. {
  463. new_node->mEncoding = LLXMLNode::ENCODING_DECIMAL;
  464. }
  465. else if ("hex" == attr_value)
  466. {
  467. new_node->mEncoding = LLXMLNode::ENCODING_HEX;
  468. }
  469. /*else if (attr_value == "base32")
  470. {
  471. new_node->mEncoding = LLXMLNode::ENCODING_BASE32;
  472. }*/
  473. }
  474. // only one attribute child per description
  475. LLXMLNodePtr attr_node;
  476. if (!new_node->getAttribute(attr_name.c_str(), attr_node, FALSE))
  477. {
  478. attr_node = new LLXMLNode(attr_name.c_str(), TRUE);
  479. attr_node->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser));
  480. }
  481. attr_node->setValue(attr_value);
  482. new_node->addChild(attr_node);
  483. pos += 2;
  484. }
  485. if (parent)
  486. {
  487. parent->addChild(new_node);
  488. }
  489. }
  490. void XMLCALL EndXMLNode(void *userData,
  491. const XML_Char *name)
  492. {
  493. // [FUGLY] Set the current active node to the current node's parent
  494. LLXMLNode *node = (LLXMLNode *)userData;
  495. XML_Parser *parser = node->mParser;
  496. XML_SetUserData(*parser, (void *)node->mParent);
  497. // SJB: total hack:
  498. if (LLXMLNode::sStripWhitespaceValues)
  499. {
  500. std::string value = node->getValue();
  501. BOOL is_empty = TRUE;
  502. for (std::string::size_type s = 0; s < value.length(); s++)
  503. {
  504. char c = value[s];
  505. if (c != ' ' && c != '\t' && c != '\n')
  506. {
  507. is_empty = FALSE;
  508. break;
  509. }
  510. }
  511. if (is_empty)
  512. {
  513. value.clear();
  514. node->setValue(value);
  515. }
  516. }
  517. }
  518. void XMLCALL XMLData(void *userData,
  519. const XML_Char *s,
  520. int len)
  521. {
  522. LLXMLNode* current_node = (LLXMLNode *)userData;
  523. std::string value = current_node->getValue();
  524. if (LLXMLNode::sStripEscapedStrings)
  525. {
  526. if (s[0] == '\"' && s[len-1] == '\"')
  527. {
  528. // Special-case: Escaped string.
  529. std::string unescaped_string;
  530. for (S32 pos=1; pos<len-1; ++pos)
  531. {
  532. if (s[pos] == '\\' && s[pos+1] == '\\')
  533. {
  534. unescaped_string.append("\\");
  535. ++pos;
  536. }
  537. else if (s[pos] == '\\' && s[pos+1] == '\"')
  538. {
  539. unescaped_string.append("\"");
  540. ++pos;
  541. }
  542. else
  543. {
  544. unescaped_string.append(&s[pos], 1);
  545. }
  546. }
  547. value.append(unescaped_string);
  548. current_node->setValue(value);
  549. return;
  550. }
  551. }
  552. value.append(std::string(s, len));
  553. current_node->setValue(value);
  554. }
  555. // static
  556. bool LLXMLNode::updateNode(
  557. LLXMLNodePtr& node,
  558. LLXMLNodePtr& update_node)
  559. {
  560. if (!node || !update_node)
  561. {
  562. llwarns << "Node invalid" << llendl;
  563. return FALSE;
  564. }
  565. //update the node value
  566. node->mValue = update_node->mValue;
  567. //update all attribute values
  568. LLXMLAttribList::const_iterator itor;
  569. for(itor = update_node->mAttributes.begin(); itor != update_node->mAttributes.end(); ++itor)
  570. {
  571. const LLStringTableEntry* attribNameEntry = (*itor).first;
  572. LLXMLNodePtr updateAttribNode = (*itor).second;
  573. LLXMLNodePtr attribNode;
  574. node->getAttribute(attribNameEntry, attribNode, 0);
  575. if (attribNode)
  576. {
  577. attribNode->mValue = updateAttribNode->mValue;
  578. }
  579. }
  580. //update all of node's children with updateNodes children that match name
  581. LLXMLNodePtr child;
  582. LLXMLNodePtr updateChild;
  583. for (updateChild = update_node->getFirstChild(); updateChild.notNull();
  584. updateChild = updateChild->getNextSibling())
  585. {
  586. for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
  587. {
  588. std::string nodeName;
  589. std::string updateName;
  590. updateChild->getAttributeString("name", updateName);
  591. child->getAttributeString("name", nodeName);
  592. //if it's a combobox there's no name, but there is a value
  593. if (updateName.empty())
  594. {
  595. updateChild->getAttributeString("value", updateName);
  596. child->getAttributeString("value", nodeName);
  597. }
  598. if ((nodeName != "") && (updateName == nodeName))
  599. {
  600. updateNode(child, updateChild);
  601. break;
  602. }
  603. }
  604. }
  605. return TRUE;
  606. }
  607. // static
  608. LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node)
  609. {
  610. if (!node || !update_node)
  611. {
  612. llwarns << "Node invalid" << llendl;
  613. return node;
  614. }
  615. LLXMLNodePtr cloned_node = update_node->deepCopy();
  616. node->mParent->addChild(cloned_node, node); // add after node
  617. LLXMLNodePtr parent = node->mParent;
  618. parent->removeChild(node);
  619. parent->updateDefault();
  620. return cloned_node;
  621. }
  622. // static
  623. bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree)
  624. {
  625. // Read file
  626. LL_DEBUGS("XMLNode") << "parsing XML file: " << filename << LL_ENDL;
  627. LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
  628. if (fp == NULL)
  629. {
  630. node = NULL ;
  631. return false;
  632. }
  633. fseek(fp, 0, SEEK_END);
  634. U32 length = ftell(fp);
  635. fseek(fp, 0, SEEK_SET);
  636. U8* buffer = new U8[length+1];
  637. size_t nread = fread(buffer, 1, length, fp);
  638. buffer[nread] = 0;
  639. fclose(fp);
  640. bool rv = parseBuffer(buffer, nread, node, defaults_tree);
  641. delete [] buffer;
  642. return rv;
  643. }
  644. // static
  645. bool LLXMLNode::parseBuffer(
  646. U8* buffer,
  647. U32 length,
  648. LLXMLNodePtr& node,
  649. LLXMLNode* defaults)
  650. {
  651. // Init
  652. XML_Parser my_parser = XML_ParserCreate(NULL);
  653. XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode);
  654. XML_SetCharacterDataHandler(my_parser, XMLData);
  655. // Create a root node
  656. LLXMLNode *file_node_ptr = new LLXMLNode("XML", FALSE);
  657. LLXMLNodePtr file_node = file_node_ptr;
  658. file_node->mParser = &my_parser;
  659. XML_SetUserData(my_parser, (void *)file_node_ptr);
  660. // Do the parsing
  661. if (XML_Parse(my_parser, (const char *)buffer, length, TRUE) != XML_STATUS_OK)
  662. {
  663. llwarns << "Error parsing xml error code: "
  664. << XML_ErrorString(XML_GetErrorCode(my_parser))
  665. << " on line " << XML_GetCurrentLineNumber(my_parser)
  666. << llendl;
  667. }
  668. // Deinit
  669. XML_ParserFree(my_parser);
  670. if (!file_node->mChildren || file_node->mChildren->map.size() != 1)
  671. {
  672. llwarns << "Parse failure - wrong number of top-level nodes xml."
  673. << llendl;
  674. node = NULL ;
  675. return false;
  676. }
  677. LLXMLNode *return_node = file_node->mChildren->map.begin()->second;
  678. return_node->setDefault(defaults);
  679. return_node->updateDefault();
  680. node = return_node;
  681. return true;
  682. }
  683. // static
  684. bool LLXMLNode::parseStream(
  685. std::istream& str,
  686. LLXMLNodePtr& node,
  687. LLXMLNode* defaults)
  688. {
  689. // Init
  690. XML_Parser my_parser = XML_ParserCreate(NULL);
  691. XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode);
  692. XML_SetCharacterDataHandler(my_parser, XMLData);
  693. // Create a root node
  694. LLXMLNode *file_node_ptr = new LLXMLNode("XML", FALSE);
  695. LLXMLNodePtr file_node = file_node_ptr;
  696. file_node->mParser = &my_parser;
  697. XML_SetUserData(my_parser, (void *)file_node_ptr);
  698. const int BUFSIZE = 1024;
  699. U8* buffer = new U8[BUFSIZE];
  700. while(str.good())
  701. {
  702. str.read((char*)buffer, BUFSIZE);
  703. int count = str.gcount();
  704. if (XML_Parse(my_parser, (const char *)buffer, count, !str.good()) != XML_STATUS_OK)
  705. {
  706. llwarns << "Error parsing xml error code: "
  707. << XML_ErrorString(XML_GetErrorCode(my_parser))
  708. << " on lne " << XML_GetCurrentLineNumber(my_parser)
  709. << llendl;
  710. break;
  711. }
  712. }
  713. delete [] buffer;
  714. // Deinit
  715. XML_ParserFree(my_parser);
  716. if (!file_node->mChildren || file_node->mChildren->map.size() != 1)
  717. {
  718. llwarns << "Parse failure - wrong number of top-level nodes xml."
  719. << llendl;
  720. node = NULL;
  721. return false;
  722. }
  723. LLXMLNode *return_node = file_node->mChildren->map.begin()->second;
  724. return_node->setDefault(defaults);
  725. return_node->updateDefault();
  726. node = return_node;
  727. return true;
  728. }
  729. BOOL LLXMLNode::isFullyDefault()
  730. {
  731. if (mDefault.isNull())
  732. {
  733. return FALSE;
  734. }
  735. BOOL has_default_value = (mValue == mDefault->mValue);
  736. BOOL has_default_attribute = (mIsAttribute == mDefault->mIsAttribute);
  737. BOOL has_default_type = mIsAttribute || (mType == mDefault->mType);
  738. BOOL has_default_encoding = mIsAttribute || (mEncoding == mDefault->mEncoding);
  739. BOOL has_default_precision = mIsAttribute || (mPrecision == mDefault->mPrecision);
  740. BOOL has_default_length = mIsAttribute || (mLength == mDefault->mLength);
  741. if (has_default_value
  742. && has_default_type
  743. && has_default_encoding
  744. && has_default_precision
  745. && has_default_length
  746. && has_default_attribute)
  747. {
  748. if (mChildren.notNull())
  749. {
  750. LLXMLChildList::const_iterator children_itr;
  751. LLXMLChildList::const_iterator children_end = mChildren->map.end();
  752. for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr)
  753. {
  754. LLXMLNodePtr child = (*children_itr).second;
  755. if (!child->isFullyDefault())
  756. {
  757. return FALSE;
  758. }
  759. }
  760. }
  761. return TRUE;
  762. }
  763. return FALSE;
  764. }
  765. // static
  766. bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root,
  767. const std::vector<std::string>& paths)
  768. {
  769. if (paths.empty()) return false;
  770. std::string filename = paths.front();
  771. if (filename.empty())
  772. {
  773. return false;
  774. }
  775. if (!LLXMLNode::parseFile(filename, root, NULL))
  776. {
  777. llwarns << "Problem reading UI description file: " << filename << llendl;
  778. return false;
  779. }
  780. LLXMLNodePtr updateRoot;
  781. std::vector<std::string>::const_iterator itor;
  782. for (itor = paths.begin(), ++itor; itor != paths.end(); ++itor)
  783. {
  784. std::string nodeName;
  785. std::string updateName;
  786. std::string layer_filename = *itor;
  787. if(layer_filename.empty())
  788. {
  789. // no localized version of this file, that's ok, keep looking
  790. continue;
  791. }
  792. if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL))
  793. {
  794. llwarns << "Problem reading localized UI description file: " << layer_filename << llendl;
  795. return false;
  796. }
  797. updateRoot->getAttributeString("name", updateName);
  798. root->getAttributeString("name", nodeName);
  799. if (updateName == nodeName)
  800. {
  801. LLXMLNode::updateNode(root, updateRoot);
  802. }
  803. }
  804. return true;
  805. }
  806. // static
  807. void LLXMLNode::writeHeaderToFile(LLFILE *out_file)
  808. {
  809. fprintf(out_file, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n");
  810. }
  811. void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations)
  812. {
  813. if (isFullyDefault())
  814. {
  815. // Don't write out nodes that are an exact match to defaults
  816. return;
  817. }
  818. std::ostringstream ostream;
  819. writeToOstream(ostream, indent, use_type_decorations);
  820. std::string outstring = ostream.str();
  821. size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file);
  822. if (written != outstring.length())
  823. {
  824. llwarns << "Short write" << llendl;
  825. }
  826. }
  827. void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations)
  828. {
  829. if (isFullyDefault())
  830. {
  831. // Don't write out nodes that are an exact match to defaults
  832. return;
  833. }
  834. BOOL has_default_type = mDefault.isNull()?FALSE:(mType == mDefault->mType);
  835. BOOL has_default_encoding = mDefault.isNull()?FALSE:(mEncoding == mDefault->mEncoding);
  836. BOOL has_default_precision = mDefault.isNull()?FALSE:(mPrecision == mDefault->mPrecision);
  837. BOOL has_default_length = mDefault.isNull()?FALSE:(mLength == mDefault->mLength);
  838. // stream the name
  839. output_stream << indent << "<" << mName->mString << "\n";
  840. if (use_type_decorations)
  841. {
  842. // ID
  843. if (mID != "")
  844. {
  845. output_stream << indent << " id=\"" << mID << "\"\n";
  846. }
  847. // Type
  848. if (!has_default_type)
  849. {
  850. switch (mType)
  851. {
  852. case TYPE_BOOLEAN:
  853. output_stream << indent << " type=\"boolean\"\n";
  854. break;
  855. case TYPE_INTEGER:
  856. output_stream << indent << " type=\"integer\"\n";
  857. break;
  858. case TYPE_FLOAT:
  859. output_stream << indent << " type=\"float\"\n";
  860. break;
  861. case TYPE_STRING:
  862. output_stream << indent << " type=\"string\"\n";
  863. break;
  864. case TYPE_UUID:
  865. output_stream << indent << " type=\"uuid\"\n";
  866. break;
  867. case TYPE_NODEREF:
  868. output_stream << indent << " type=\"noderef\"\n";
  869. break;
  870. default:
  871. // default on switch(enum) eliminates a warning on linux
  872. break;
  873. };
  874. }
  875. // Encoding
  876. if (!has_default_encoding)
  877. {
  878. switch (mEncoding)
  879. {
  880. case ENCODING_DECIMAL:
  881. output_stream << indent << " encoding=\"decimal\"\n";
  882. break;
  883. case ENCODING_HEX:
  884. output_stream << indent << " encoding=\"hex\"\n";
  885. break;
  886. /*case ENCODING_BASE32:
  887. output_stream << indent << " encoding=\"base32\"\n";
  888. break;*/
  889. default:
  890. // default on switch(enum) eliminates a warning on linux
  891. break;
  892. };
  893. }
  894. // Precision
  895. if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT))
  896. {
  897. output_stream << indent << " precision=\"" << mPrecision << "\"\n";
  898. }
  899. // Version
  900. if (mVersionMajor > 0 || mVersionMinor > 0)
  901. {
  902. output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n";
  903. }
  904. // Array length
  905. if (!has_default_length && mLength > 0)
  906. {
  907. output_stream << indent << " length=\"" << mLength << "\"\n";
  908. }
  909. }
  910. {
  911. // Write out attributes
  912. LLXMLAttribList::const_iterator attr_itr;
  913. LLXMLAttribList::const_iterator attr_end = mAttributes.end();
  914. for (attr_itr = mAttributes.begin(); attr_itr != attr_end; ++attr_itr)
  915. {
  916. LLXMLNodePtr child = (*attr_itr).second;
  917. if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue)
  918. {
  919. std::string attr = child->mName->mString;
  920. if (use_type_decorations
  921. && (attr == "id" ||
  922. attr == "type" ||
  923. attr == "encoding" ||
  924. attr == "precision" ||
  925. attr == "version" ||
  926. attr == "length"))
  927. {
  928. continue; // skip built-in attributes
  929. }
  930. std::string attr_str = llformat(" %s=\"%s\"",
  931. attr.c_str(),
  932. escapeXML(child->mValue).c_str());
  933. output_stream << indent << attr_str << "\n";
  934. }
  935. }
  936. }
  937. // erase last \n before attaching final > or />
  938. output_stream.seekp(-1, std::ios::cur);
  939. if (mChildren.isNull() && mValue == "")
  940. {
  941. output_stream << " />\n";
  942. return;
  943. }
  944. else
  945. {
  946. output_stream << ">\n";
  947. if (mChildren.notNull())
  948. {
  949. // stream non-attributes
  950. std::string next_indent = indent + " ";
  951. for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling())
  952. {
  953. child->writeToOstream(output_stream, next_indent, use_type_decorations);
  954. }
  955. }
  956. if (!mValue.empty())
  957. {
  958. std::string contents = getTextContents();
  959. output_stream << indent << " " << escapeXML(contents) << "\n";
  960. }
  961. output_stream << indent << "</" << mName->mString << ">\n";
  962. }
  963. }
  964. void LLXMLNode::findName(const std::string& name, LLXMLNodeList &results)
  965. {
  966. LLStringTableEntry* name_entry = gStringTable.checkStringEntry(name);
  967. if (name_entry == mName)
  968. {
  969. results.insert(std::make_pair(this->mName->mString, this));
  970. return;
  971. }
  972. if (mChildren.notNull())
  973. {
  974. LLXMLChildList::const_iterator children_itr;
  975. LLXMLChildList::const_iterator children_end = mChildren->map.end();
  976. for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr)
  977. {
  978. LLXMLNodePtr child = (*children_itr).second;
  979. child->findName(name_entry, results);
  980. }
  981. }
  982. }
  983. void LLXMLNode::findName(LLStringTableEntry* name, LLXMLNodeList &results)
  984. {
  985. if (name == mName)
  986. {
  987. results.insert(std::make_pair(this->mName->mString, this));
  988. return;
  989. }
  990. if (mChildren.notNull())
  991. {
  992. LLXMLChildList::const_iterator children_itr;
  993. LLXMLChildList::const_iterator children_end = mChildren->map.end();
  994. for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr)
  995. {
  996. LLXMLNodePtr child = (*children_itr).second;
  997. child->findName(name, results);
  998. }
  999. }
  1000. }
  1001. void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results)
  1002. {
  1003. if (id == mID)
  1004. {
  1005. results.insert(std::make_pair(this->mName->mString, this));
  1006. return;
  1007. }
  1008. if (mChildren.notNull())
  1009. {
  1010. LLXMLChildList::const_iterator children_itr;
  1011. LLXMLChildList::const_iterator children_end = mChildren->map.end();
  1012. for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr)
  1013. {
  1014. LLXMLNodePtr child = (*children_itr).second;
  1015. child->findID(id, results);
  1016. }
  1017. }
  1018. }
  1019. void LLXMLNode::scrubToTree(LLXMLNode *tree)
  1020. {
  1021. if (!tree || tree->mChildren.isNull())
  1022. {
  1023. return;
  1024. }
  1025. if (mChildren.notNull())
  1026. {
  1027. std::vector<LLXMLNodePtr> to_delete_list;
  1028. LLXMLChildList::iterator itor = mChildren->map.begin();
  1029. while (itor != mChildren->map.end())
  1030. {
  1031. LLXMLNodePtr child = itor->second;
  1032. LLXMLNodePtr child_tree = NULL;
  1033. // Look for this child in the default's children
  1034. bool found = false;
  1035. LLXMLChildList::iterator itor2 = tree->mChildren->map.begin();
  1036. while (itor2 != tree->mChildren->map.end())
  1037. {
  1038. if (child->mName == itor2->second->mName)
  1039. {
  1040. child_tree = itor2->second;
  1041. found = true;
  1042. }
  1043. ++itor2;
  1044. }
  1045. if (!found)
  1046. {
  1047. to_delete_list.push_back(child);
  1048. }
  1049. else
  1050. {
  1051. child->scrubToTree(child_tree);
  1052. }
  1053. ++itor;
  1054. }
  1055. std::vector<LLXMLNodePtr>::iterator itor3;
  1056. for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3)
  1057. {
  1058. (*itor3)->setParent(NULL);
  1059. }
  1060. }
  1061. }
  1062. bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
  1063. {
  1064. return getChild(gStringTable.checkStringEntry(name), node, use_default_if_missing);
  1065. }
  1066. bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
  1067. {
  1068. if (mChildren.notNull())
  1069. {
  1070. LLXMLChildList::const_iterator child_itr = mChildren->map.find(name);
  1071. if (child_itr != mChildren->map.end())
  1072. {
  1073. node = (*child_itr).second;
  1074. return true;
  1075. }
  1076. }
  1077. if (use_default_if_missing && !mDefault.isNull())
  1078. {
  1079. return mDefault->getChild(name, node, FALSE);
  1080. }
  1081. node = NULL;
  1082. return false;
  1083. }
  1084. void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing) const
  1085. {
  1086. getChildren(gStringTable.checkStringEntry(name), children, use_default_if_missing);
  1087. }
  1088. void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing) const
  1089. {
  1090. if (mChildren.notNull())
  1091. {
  1092. LLXMLChildList::const_iterator child_itr = mChildren->map.find(name);
  1093. if (child_itr != mChildren->map.end())
  1094. {
  1095. LLXMLChildList::const_iterator children_end = mChildren->map.end();
  1096. while (child_itr != children_end)
  1097. {
  1098. LLXMLNodePtr child = (*child_itr).second;
  1099. if (name != child->mName)
  1100. {
  1101. break;
  1102. }
  1103. children.insert(std::make_pair(child->mName->mString, child));
  1104. child_itr++;
  1105. }
  1106. }
  1107. }
  1108. if (children.size() == 0 && use_default_if_missing && !mDefault.isNull())
  1109. {
  1110. mDefault->getChildren(name, children, FALSE);
  1111. }
  1112. }
  1113. // recursively walks the tree and returns all children at all nesting levels matching the name
  1114. void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const
  1115. {
  1116. if (mChildren.notNull())
  1117. {
  1118. for (LLXMLChildList::const_iterator child_itr = mChildren->map.begin();
  1119. child_itr != mChildren->map.end(); ++child_itr)
  1120. {
  1121. LLXMLNodePtr child = (*child_itr).second;
  1122. if (name == child->mName)
  1123. {
  1124. children.insert(std::make_pair(child->mName->mString, child));
  1125. }
  1126. // and check each child as well
  1127. child->getDescendants(name, children);
  1128. }
  1129. }
  1130. }
  1131. bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
  1132. {
  1133. return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing);
  1134. }
  1135. bool LLXMLNode::getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
  1136. {
  1137. LLXMLAttribList::const_iterator child_itr = mAttributes.find(name);
  1138. if (child_itr != mAttributes.end())
  1139. {
  1140. node = (*child_itr).second;
  1141. return true;
  1142. }
  1143. if (use_default_if_missing && !mDefault.isNull())
  1144. {
  1145. return mDefault->getAttribute(name, node, FALSE);
  1146. }
  1147. return false;
  1148. }
  1149. bool LLXMLNode::setAttributeString(const char* attr, const std::string& value)
  1150. {
  1151. LLStringTableEntry* name = gStringTable.checkStringEntry(attr);
  1152. LLXMLAttribList::const_iterator child_itr = mAttributes.find(name);
  1153. if (child_itr != mAttributes.end())
  1154. {
  1155. LLXMLNodePtr node = (*child_itr).second;
  1156. node->setValue(value);
  1157. return true;
  1158. }
  1159. return false;
  1160. }
  1161. BOOL LLXMLNode::hasAttribute(const char* name )
  1162. {
  1163. LLXMLNodePtr node;
  1164. return getAttribute(name, node);
  1165. }
  1166. // the structure of these getAttribute_ functions is ugly, but it's because the
  1167. // underlying system is based on BOOL and LLString; if we change
  1168. // so that they're based on more generic mechanisms, these will be
  1169. // simplified.
  1170. bool LLXMLNode::getAttribute_bool(const char* name, bool& value )
  1171. {
  1172. LLXMLNodePtr node;
  1173. if (!getAttribute(name, node))
  1174. {
  1175. return false;
  1176. }
  1177. BOOL temp;
  1178. bool retval = node->getBoolValue(1, &temp);
  1179. value = temp;
  1180. return retval;
  1181. }
  1182. BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value )
  1183. {
  1184. LLXMLNodePtr node;
  1185. return (getAttribute(name, node) && node->getBoolValue(1, &value));
  1186. }
  1187. BOOL LLXMLNode::getAttributeU8(const char* name, U8& value )
  1188. {
  1189. LLXMLNodePtr node;
  1190. return (getAttribute(name, node) && node->getByteValue(1, &value));
  1191. }
  1192. BOOL LLXMLNode::getAttributeS8(const char* name, S8& value )
  1193. {
  1194. LLXMLNodePtr node;
  1195. S32 val;
  1196. if (!(getAttribute(name, node) && node->getIntValue(1, &val)))
  1197. {
  1198. return false;
  1199. }
  1200. value = val;
  1201. return true;
  1202. }
  1203. BOOL LLXMLNode::getAttributeU16(const char* name, U16& value )
  1204. {
  1205. LLXMLNodePtr node;
  1206. U32 val;
  1207. if (!(getAttribute(name, node) && node->getUnsignedValue(1, &val)))
  1208. {
  1209. return false;
  1210. }
  1211. value = val;
  1212. return true;
  1213. }
  1214. BOOL LLXMLNode::getAttributeS16(const char* name, S16& value )
  1215. {
  1216. LLXMLNodePtr node;
  1217. S32 val;
  1218. if (!(getAttribute(name, node) && node->getIntValue(1, &val)))
  1219. {
  1220. return false;
  1221. }
  1222. value = val;
  1223. return true;
  1224. }
  1225. BOOL LLXMLNode::getAttributeU32(const char* name, U32& value )
  1226. {
  1227. LLXMLNodePtr node;
  1228. return (getAttribute(name, node) && node->getUnsignedValue(1, &value));
  1229. }
  1230. BOOL LLXMLNode::getAttributeS32(const char* name, S32& value )
  1231. {
  1232. LLXMLNodePtr node;
  1233. return (getAttribute(name, node) && node->getIntValue(1, &value));
  1234. }
  1235. BOOL LLXMLNode::getAttributeF32(const char* name, F32& value )
  1236. {
  1237. LLXMLNodePtr node;
  1238. return (getAttribute(name, node) && node->getFloatValue(1, &value));
  1239. }
  1240. BOOL LLXMLNode::getAttributeF64(const char* name, F64& value )
  1241. {
  1242. LLXMLNodePtr node;
  1243. return (getAttribute(name, node) && node->getDoubleValue(1, &value));
  1244. }
  1245. BOOL LLXMLNode::getAttributeColor(const char* name, LLColor4& value )
  1246. {
  1247. LLXMLNodePtr node;
  1248. return (getAttribute(name, node) && node->getFloatValue(4, value.mV));
  1249. }
  1250. BOOL LLXMLNode::getAttributeColor4(const char* name, LLColor4& value )
  1251. {
  1252. LLXMLNodePtr node;
  1253. return (getAttribute(name, node) && node->getFloatValue(4, value.mV));
  1254. }
  1255. BOOL LLXMLNode::getAttributeColor4U(const char* name, LLColor4U& value )
  1256. {
  1257. LLXMLNodePtr node;
  1258. return (getAttribute(name, node) && node->getByteValue(4, value.mV));
  1259. }
  1260. BOOL LLXMLNode::getAttributeVector3(const char* name, LLVector3& value )
  1261. {
  1262. LLXMLNodePtr node;
  1263. return (getAttribute(name, node) && node->getFloatValue(3, value.mV));
  1264. }
  1265. BOOL LLXMLNode::getAttributeVector3d(const char* name, LLVector3d& value )
  1266. {
  1267. LLXMLNodePtr node;
  1268. return (getAttribute(name, node) && node->getDoubleValue(3, value.mdV));
  1269. }
  1270. BOOL LLXMLNode::getAttributeQuat(const char* name, LLQuaternion& value )
  1271. {
  1272. LLXMLNodePtr node;
  1273. return (getAttribute(name, node) && node->getFloatValue(4, value.mQ));
  1274. }
  1275. BOOL LLXMLNode::getAttributeUUID(const char* name, LLUUID& value )
  1276. {
  1277. LLXMLNodePtr node;
  1278. return (getAttribute(name, node) && node->getUUIDValue(1, &value));
  1279. }
  1280. BOOL LLXMLNode::getAttributeString(const char* name, std::string& value )
  1281. {
  1282. LLXMLNodePtr node;
  1283. if (!getAttribute(name, node))
  1284. {
  1285. return false;
  1286. }
  1287. value = node->getValue();
  1288. return true;
  1289. }
  1290. LLXMLNodePtr LLXMLNode::getRoot()
  1291. {
  1292. if (mParent == NULL)
  1293. {
  1294. return this;
  1295. }
  1296. return mParent->getRoot();
  1297. }
  1298. /*static */
  1299. const char *LLXMLNode::skipWhitespace(const char *str)
  1300. {
  1301. // skip whitespace characters
  1302. while (str[0] == ' ' || str[0] == '\t' || str[0] == '\n') ++str;
  1303. return str;
  1304. }
  1305. /*static */
  1306. const char *LLXMLNode::skipNonWhitespace(const char *str)
  1307. {
  1308. // skip non-whitespace characters
  1309. while (str[0] != ' ' && str[0] != '\t' && str[0] != '\n' && str[0] != 0) ++str;
  1310. return str;
  1311. }
  1312. /*static */
  1313. const char *LLXMLNode::parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding)
  1314. {
  1315. *dest = 0;
  1316. *is_negative = FALSE;
  1317. str = skipWhitespace(str);
  1318. if (str[0] == 0) return NULL;
  1319. if (encoding == ENCODING_DECIMAL || encoding == ENCODING_DEFAULT)
  1320. {
  1321. if (str[0] == '+')
  1322. {
  1323. ++str;
  1324. }
  1325. if (str[0] == '-')
  1326. {
  1327. *is_negative = TRUE;
  1328. ++str;
  1329. }
  1330. str = skipWhitespace(str);
  1331. U64 ret = 0;
  1332. while (str[0] >= '0' && str[0] <= '9')
  1333. {
  1334. ret *= 10;
  1335. ret += str[0] - '0';
  1336. ++str;
  1337. }
  1338. if (str[0] == '.')
  1339. {
  1340. // If there is a fractional part, skip it
  1341. str = skipNonWhitespace(str);
  1342. }
  1343. *dest = ret;
  1344. return str;
  1345. }
  1346. if (encoding == ENCODING_HEX)
  1347. {
  1348. U64 ret = 0;
  1349. str = skipWhitespace(str);
  1350. for (U32 pos=0; pos<(precision/4); ++pos)
  1351. {
  1352. ret <<= 4;
  1353. str = skipWhitespace(str);
  1354. if (str[0] >= '0' && str[0] <= '9')
  1355. {
  1356. ret += str[0] - '0';
  1357. }
  1358. else if (str[0] >= 'a' && str[0] <= 'f')
  1359. {
  1360. ret += str[0] - 'a' + 10;
  1361. }
  1362. else if (str[0] >= 'A' && str[0] <= 'F')
  1363. {
  1364. ret += str[0] - 'A' + 10;
  1365. }
  1366. else
  1367. {
  1368. return NULL;
  1369. }
  1370. ++str;
  1371. }
  1372. *dest = ret;
  1373. return str;
  1374. }
  1375. return NULL;
  1376. }
  1377. // 25 elements - decimal expansions of 1/(2^n), multiplied by 10 each iteration
  1378. const U64 float_coeff_table[] =
  1379. { 5, 25, 125, 625, 3125,
  1380. 15625, 78125, 390625, 1953125, 9765625,
  1381. 48828125, 244140625, 1220703125, 6103515625LL, 30517578125LL,
  1382. 152587890625LL, 762939453125LL, 3814697265625LL, 19073486328125LL, 95367431640625LL,
  1383. 476837158203125LL, 2384185791015625LL, 11920928955078125LL, 59604644775390625LL, 298023223876953125LL };
  1384. // 36 elements - decimal expansions of 1/(2^n) after the last 28, truncated, no multiply each iteration
  1385. const U64 float_coeff_table_2[] =
  1386. { 149011611938476562LL,74505805969238281LL,
  1387. 37252902984619140LL, 18626451492309570LL, 9313225746154785LL, 4656612873077392LL,
  1388. 2328306436538696LL, 1164153218269348LL, 582076609134674LL, 291038304567337LL,
  1389. 145519152283668LL, 72759576141834LL, 36379788070917LL, 18189894035458LL,
  1390. 9094947017729LL, 4547473508864LL, 2273736754432LL, 1136868377216LL,
  1391. 568434188608LL, 284217094304LL, 142108547152LL, 71054273576LL,
  1392. 35527136788LL, 17763568394LL, 8881784197LL, 4440892098LL,
  1393. 2220446049LL, 1110223024LL, 555111512LL, 277555756LL,
  1394. 138777878, 69388939, 34694469, 17347234,
  1395. 8673617, 4336808, 2168404, 1084202,
  1396. 542101, 271050, 135525, 67762,
  1397. };
  1398. /*static */
  1399. const char *LLXMLNode::parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding)
  1400. {
  1401. str = skipWhitespace(str);
  1402. if (str[0] == 0) return NULL;
  1403. if (encoding == ENCODING_DECIMAL || encoding == ENCODING_DEFAULT)
  1404. {
  1405. str = skipWhitespace(str);
  1406. if (memcmp(str, "inf", 3) == 0)
  1407. {
  1408. *(U64 *)dest = 0x7FF0000000000000ll;
  1409. return str + 3;
  1410. }
  1411. if (memcmp(str, "-inf", 4) == 0)
  1412. {
  1413. *(U64 *)dest = 0xFFF0000000000000ll;
  1414. return str + 4;
  1415. }
  1416. if (memcmp(str, "1.#INF", 6) == 0)
  1417. {
  1418. *(U64 *)dest = 0x7FF0000000000000ll;
  1419. return str + 6;
  1420. }
  1421. if (memcmp(str, "-1.#INF", 7) == 0)
  1422. {
  1423. *(U64 *)dest = 0xFFF0000000000000ll;
  1424. return str + 7;
  1425. }
  1426. F64 negative = 1.0f;
  1427. if (str[0] == '+')
  1428. {
  1429. ++str;
  1430. }
  1431. if (str[0] == '-')
  1432. {
  1433. negative = -1.0f;
  1434. ++str;
  1435. }
  1436. const char* base_str = str;
  1437. str = skipWhitespace(str);
  1438. // Parse the integer part of the expression
  1439. U64 int_part = 0;
  1440. while (str[0] >= '0' && str[0] <= '9')
  1441. {
  1442. int_part *= 10;
  1443. int_part += U64(str[0] - '0');
  1444. ++str;
  1445. }
  1446. U64 f_part = 0;//, f_decimal = 1;
  1447. if (str[0] == '.')
  1448. {
  1449. ++str;
  1450. U64 remainder = 0;
  1451. U32 pos = 0;
  1452. // Parse the decimal part of the expression
  1453. while (str[0] >= '0' && str[0] <= '9' && pos < 25)
  1454. {
  1455. remainder = (remainder*10) + U64(str[0] - '0');
  1456. f_part <<= 1;
  1457. //f_decimal <<= 1;
  1458. // Check the n'th bit
  1459. if (remainder >= float_coeff_table[pos])
  1460. {
  1461. remainder -= float_coeff_table[pos];
  1462. f_part |= 1;
  1463. }
  1464. ++pos;
  1465. ++str;
  1466. }
  1467. if (pos == 25)
  1468. {
  1469. // Drop any excessive digits
  1470. while (str[0] >= '0' && str[0] <= '9')
  1471. {
  1472. ++str;
  1473. }
  1474. }
  1475. else
  1476. {
  1477. while (pos < 25)
  1478. {
  1479. remainder *= 10;
  1480. f_part <<= 1;
  1481. //f_decimal <<= 1;
  1482. // Check the n'th bit
  1483. if (remainder >= float_coeff_table[pos])
  1484. {
  1485. remainder -= float_coeff_table[pos];
  1486. f_part |= 1;
  1487. }
  1488. ++pos;
  1489. }
  1490. }
  1491. pos = 0;
  1492. while (pos < 36)
  1493. {
  1494. f_part <<= 1;
  1495. //f_decimal <<= 1;
  1496. if (remainder >= float_coeff_table_2[pos])
  1497. {
  1498. remainder -= float_coeff_table_2[pos];
  1499. f_part |= 1;
  1500. }
  1501. ++pos;
  1502. }
  1503. }
  1504. F64 ret = F64(int_part) + (F64(f_part)/F64(1LL<<61));
  1505. F64 exponent = 1.f;
  1506. if (str[0] == 'e')
  1507. {
  1508. // Scientific notation!
  1509. ++str;
  1510. U64 exp;
  1511. BOOL is_negative;
  1512. str = parseInteger(str, &exp, &is_negative, 64, ENCODING_DECIMAL);
  1513. if (str == NULL)
  1514. {
  1515. exp = 1;
  1516. }
  1517. F64 exp_d = F64(exp) * (is_negative?-1:1);
  1518. exponent = pow(10.0, exp_d);
  1519. }
  1520. if (str == base_str)
  1521. {
  1522. // no digits parsed
  1523. return NULL;
  1524. }
  1525. else
  1526. {
  1527. *dest = ret*negative*exponent;
  1528. return str;
  1529. }
  1530. }
  1531. if (encoding == ENCODING_HEX)
  1532. {
  1533. U64 bytes_dest;
  1534. BOOL is_negative;
  1535. str = parseInteger(str, (U64 *)&bytes_dest, &is_negative, precision, ENCODING_HEX);
  1536. // Upcast to F64
  1537. switch (precision)
  1538. {
  1539. case 32:
  1540. {
  1541. U32 short_dest = (U32)bytes_dest;
  1542. F32 ret_val = *(F32 *)&short_dest;
  1543. *dest = ret_val;
  1544. }
  1545. break;
  1546. case 64:
  1547. *dest = *(F64 *)&bytes_dest;
  1548. break;
  1549. default:
  1550. return NULL;
  1551. }
  1552. return str;
  1553. }
  1554. return NULL;
  1555. }
  1556. U32 LLXMLNode::getBoolValue(U32 expected_length, BOOL *array)
  1557. {
  1558. llassert(array);
  1559. // Check type - accept booleans or strings
  1560. if (mType != TYPE_BOOLEAN && mType != TYPE_STRING && mType != TYPE_UNKNOWN)
  1561. {
  1562. return 0;
  1563. }
  1564. std::string *str_array = new std::string[expected_length];
  1565. U32 length = getStringValue(expected_length, str_array);
  1566. U32 ret_length = 0;
  1567. for (U32 i=0; i<length; ++i)
  1568. {
  1569. LLStringUtil::toLower(str_array[i]);
  1570. if (str_array[i] == "false")
  1571. {
  1572. array[ret_length++] = FALSE;
  1573. }
  1574. else if (str_array[i] == "true")
  1575. {
  1576. array[ret_length++] = TRUE;
  1577. }
  1578. }
  1579. delete[] str_array;
  1580. #if LL_DEBUG
  1581. if (ret_length != expected_length)
  1582. {
  1583. lldebugs << "LLXMLNode::getBoolValue() failed for node named '"
  1584. << mName->mString << "' -- expected " << expected_length << " but "
  1585. << "only found " << ret_length << llendl;
  1586. }
  1587. #endif
  1588. return ret_length;
  1589. }
  1590. U32 LLXMLNode::getByteValue(U32 expected_length, U8 *array, Encoding encoding)
  1591. {
  1592. llassert(array);
  1593. // Check type - accept bytes or integers (below 256 only)
  1594. if (mType != TYPE_INTEGER
  1595. && mType != TYPE_UNKNOWN)
  1596. {
  1597. return 0;
  1598. }
  1599. if (mLength > 0 && mLength != expected_length)
  1600. {
  1601. llwarns << "XMLNode::getByteValue asked for " << expected_length
  1602. << " elements, while node has " << mLength << llendl;
  1603. return 0;
  1604. }
  1605. if (encoding == ENCODING_DEFAULT)
  1606. {
  1607. encoding = mEncoding;
  1608. }
  1609. const char *value_string = mValue.c_str();
  1610. U32 i;
  1611. for (i=0; i<expected_length; ++i)
  1612. {
  1613. U64 value;
  1614. BOOL is_negative;
  1615. value_string = parseInteger(value_string, &value, &is_negative, 8, encoding);
  1616. if (value_string == NULL)
  1617. {
  1618. break;
  1619. }
  1620. if (value > 255 || is_negative)
  1621. {
  1622. llwarns << "getByteValue: Value outside of valid range." << llendl;
  1623. break;
  1624. }
  1625. array[i] = U8(value);
  1626. }
  1627. #if LL_DEBUG
  1628. if (i != expected_length)
  1629. {
  1630. lldebugs << "LLXMLNode::getByteValue() failed for node named '"
  1631. << mName->mString << "' -- expected " << expected_length << " but "
  1632. << "only found " << i << llendl;
  1633. }
  1634. #endif
  1635. return i;
  1636. }
  1637. U32 LLXMLNode::getIntValue(U32 expected_length, S32 *array, Encoding encoding)
  1638. {
  1639. llassert(array);
  1640. // Check type - accept bytes or integers
  1641. if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN)
  1642. {
  1643. return 0;
  1644. }
  1645. if (mLength > 0 && mLength != expected_length)
  1646. {
  1647. llwarns << "XMLNode::getIntValue asked for " << expected_length
  1648. << " elements, while node has " << mLength << llendl;
  1649. return 0;
  1650. }
  1651. if (encoding == ENCODING_DEFAULT)
  1652. {
  1653. encoding = mEncoding;
  1654. }
  1655. const char *value_string = mValue.c_str();
  1656. U32 i = 0;
  1657. for (i=0; i<expected_length; ++i)
  1658. {
  1659. U64 value;
  1660. BOOL is_negative;
  1661. value_string = parseInteger(value_string, &value, &is_negative, 32, encoding);
  1662. if (value_string == NULL)
  1663. {
  1664. break;
  1665. }
  1666. if (value > 0x7fffffff)
  1667. {
  1668. llwarns << "getIntValue: Value outside of valid range." << llendl;
  1669. break;
  1670. }
  1671. array[i] = S32(value) * (is_negative?-1:1);
  1672. }
  1673. #if LL_DEBUG
  1674. if (i != expected_length)
  1675. {
  1676. lldebugs << "LLXMLNode::getIntValue() failed for node named '"
  1677. << mName->mString << "' -- expected " << expected_length << " but "
  1678. << "only found " << i << llendl;
  1679. }
  1680. #endif
  1681. return i;
  1682. }
  1683. U32 LLXMLNode::getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding)
  1684. {
  1685. llassert(array);
  1686. // Check type - accept bytes or integers
  1687. if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN)
  1688. {
  1689. return 0;
  1690. }
  1691. if (mLength > 0 && mLength != expected_length)
  1692. {
  1693. llwarns << "XMLNode::getUnsignedValue asked for " << expected_length
  1694. << " elements, while node has " << mLength << llendl;
  1695. return 0;
  1696. }
  1697. if (encoding == ENCODING_DEFAULT)
  1698. {
  1699. encoding = mEncoding;
  1700. }
  1701. const char *value_string = mValue.c_str();
  1702. U32 i = 0;
  1703. // Int type
  1704. for (i=0; i<expected_length; ++i)
  1705. {
  1706. U64 value;
  1707. BOOL is_negative;
  1708. value_string = parseInteger(value_string, &value, &is_negative, 32, encoding);
  1709. if (value_string == NULL)
  1710. {
  1711. break;
  1712. }
  1713. if (is_negative || value > 0xffffffff)
  1714. {
  1715. llwarns << "getUnsignedValue: Value outside of valid range." << llendl;
  1716. break;
  1717. }
  1718. array[i] = U32(value);
  1719. }
  1720. #if LL_DEBUG
  1721. if (i != expected_length)
  1722. {
  1723. lldebugs << "LLXMLNode::getUnsignedValue() failed for node named '"
  1724. << mName->mString << "' -- expected " << expected_length << " but "
  1725. << "only found " << i << llendl;
  1726. }
  1727. #endif
  1728. return i;
  1729. }
  1730. U32 LLXMLNode::getLongValue(U32 expected_length, U64 *array, Encoding encoding)
  1731. {
  1732. llassert(array);
  1733. // Check type - accept bytes or integers
  1734. if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN)
  1735. {
  1736. return 0;
  1737. }
  1738. if (mLength > 0 && mLength != expected_length)
  1739. {
  1740. llwarns << "XMLNode::getLongValue asked for " << expected_length << " elements, while node has " << mLength << llendl;
  1741. return 0;
  1742. }
  1743. if (encoding == ENCODING_DEFAULT)
  1744. {
  1745. encoding = mEncoding;
  1746. }
  1747. const char *value_string = mValue.c_str();
  1748. U32 i = 0;
  1749. // Int type
  1750. for (i=0; i<expected_length; ++i)
  1751. {
  1752. U64 value;
  1753. BOOL is_negative;
  1754. value_string = parseInteger(value_string, &value, &is_negative, 64, encoding);
  1755. if (value_string == NULL)
  1756. {
  1757. break;
  1758. }
  1759. if (is_negative)
  1760. {
  1761. llwarns << "getLongValue: Value outside of valid range." << llendl;
  1762. break;
  1763. }
  1764. array[i] = value;
  1765. }
  1766. #if LL_DEBUG
  1767. if (i != expected_length)
  1768. {
  1769. lldebugs << "LLXMLNode::getLongValue() failed for node named '"
  1770. << mName->mString << "' -- expected " << expected_length << " but "
  1771. << "only found " << i << llendl;
  1772. }
  1773. #endif
  1774. return i;
  1775. }
  1776. U32 LLXMLNode::getFloatValue(U32 expected_length, F32 *array, Encoding encoding)
  1777. {
  1778. llassert(array);
  1779. // Check type - accept only floats or doubles
  1780. if (mType != TYPE_FLOAT && mType != TYPE_UNKNOWN)
  1781. {
  1782. return 0;
  1783. }
  1784. if (mLength > 0 && mLength != expected_length)
  1785. {
  1786. llwarns << "XMLNode::getFloatValue asked for " << expected_length << " elements, while node has " << mLength << llendl;
  1787. return 0;
  1788. }
  1789. if (encoding == ENCODING_DEFAULT)
  1790. {
  1791. encoding = mEncoding;
  1792. }
  1793. const char *value_string = mValue.c_str();
  1794. U32 i;
  1795. for (i=0; i<expected_length; ++i)
  1796. {
  1797. F64 value;
  1798. value_string = parseFloat(value_string, &value, 32, encoding);
  1799. if (value_string == NULL)
  1800. {
  1801. break;
  1802. }
  1803. array[i] = F32(value);
  1804. }
  1805. #if LL_DEBUG
  1806. if (i != expected_length)
  1807. {
  1808. lldebugs << "LLXMLNode::getFloatValue() failed for node named '"
  1809. << mName->mString << "' -- expected " << expected_length << " but "
  1810. << "only found " << i << llendl;
  1811. }
  1812. #endif
  1813. return i;
  1814. }
  1815. U32 LLXMLNode::getDoubleValue(U32 expected_length, F64 *array, Encoding encoding)
  1816. {
  1817. llassert(array);
  1818. // Check type - accept only floats or doubles
  1819. if (mType != TYPE_FLOAT && mType != TYPE_UNKNOWN)
  1820. {
  1821. return 0;
  1822. }
  1823. if (mLength > 0 && mLength != expected_length)
  1824. {
  1825. llwarns << "XMLNode::getDoubleValue asked for " << expected_length << " elements, while node has " << mLength << llendl;
  1826. return 0;
  1827. }
  1828. if (encoding == ENCODING_DEFAULT)
  1829. {
  1830. encoding = mEncoding;
  1831. }
  1832. const char *value_string = mValue.c_str();
  1833. U32 i;
  1834. for (i=0; i<expected_length; ++i)
  1835. {
  1836. F64 value;
  1837. value_string = parseFloat(value_string, &value, 64, encoding);
  1838. if (value_string == NULL)
  1839. {
  1840. break;
  1841. }
  1842. array[i] = value;
  1843. }
  1844. #if LL_DEBUG
  1845. if (i != expected_length)
  1846. {
  1847. lldebugs << "LLXMLNode::getDoubleValue() failed for node named '"
  1848. << mName->mString << "' -- expected " << expected_length << " but "
  1849. << "only found " << i << llendl;
  1850. }
  1851. #endif
  1852. return i;
  1853. }
  1854. U32 LLXMLNode::getStringValue(U32 expected_length, std::string *array)
  1855. {
  1856. llassert(array);
  1857. // Can always return any value as a string
  1858. if (mLength > 0 && mLength != expected_length)
  1859. {
  1860. llwarns << "XMLNode::getStringValue asked for " << expected_length << " elements, while node has " << mLength << llendl;
  1861. return 0;
  1862. }
  1863. U32 num_returned_strings = 0;
  1864. // Array of strings is whitespace-separated
  1865. const std::string sep(" \n\t");
  1866. std::string::size_type n = 0;
  1867. std::string::size_type m = 0;
  1868. while(1)
  1869. {
  1870. if (num_returned_strings >= expected_length)
  1871. {
  1872. break;
  1873. }
  1874. n = mValue.find_first_not_of(sep, m);
  1875. m = mValue.find_first_of(sep, n);
  1876. if (m == std::string::npos)
  1877. {
  1878. break;
  1879. }
  1880. array[num_returned_strings++] = mValue.substr(n,m-n);
  1881. }
  1882. if (n != std::string::npos && num_returned_strings < expected_length)
  1883. {
  1884. array[num_returned_strings++] = mValue.substr(n);
  1885. }
  1886. #if LL_DEBUG
  1887. if (num_returned_strings != expected_length)
  1888. {
  1889. lldebugs << "LLXMLNode::getStringValue() failed for node named '"
  1890. << mName->mString << "' -- expected " << expected_length << " but "
  1891. << "only found " << num_returned_strings << llendl;
  1892. }
  1893. #endif
  1894. return num_returned_strings;
  1895. }
  1896. U32 LLXMLNode::getUUIDValue(U32 expected_length, LLUUID *array)
  1897. {
  1898. llassert(array);
  1899. // Check type
  1900. if (mType != TYPE_UUID && mType != TYPE_UNKNOWN)
  1901. {
  1902. return 0;
  1903. }
  1904. const char *value_string = mValue.c_str();
  1905. U32 i;
  1906. for (i=0; i<expected_length; ++i)
  1907. {
  1908. LLUUID uuid_value;
  1909. value_string = skipWhitespace(value_string);
  1910. if (strlen(value_string) < (UUID_STR_LENGTH-1)) /* Flawfinder: ignore */
  1911. {
  1912. break;
  1913. }
  1914. char uuid_string[UUID_STR_LENGTH]; /* Flawfinder: ignore */
  1915. memcpy(uuid_string, value_string, (UUID_STR_LENGTH-1)); /* Flawfinder: ignore */
  1916. uuid_string[(UUID_STR_LENGTH-1)] = 0;
  1917. if (!LLUUID::parseUUID(std::string(uuid_string), &uuid_value))
  1918. {
  1919. break;
  1920. }
  1921. value_string = &value_string[(UUID_STR_LENGTH-1)];
  1922. array[i] = uuid_value;
  1923. }
  1924. #if LL_DEBUG
  1925. if (i != expected_length)
  1926. {
  1927. lldebugs << "LLXMLNode::getUUIDValue() failed for node named '"
  1928. << mName->mString << "' -- expected " << expected_length << " but "
  1929. << "only found " << i << llendl;
  1930. }
  1931. #endif
  1932. return i;
  1933. }
  1934. U32 LLXMLNode::getNodeRefValue(U32 expected_length, LLXMLNode **array)
  1935. {
  1936. llassert(array);
  1937. // Check type
  1938. if (mType != TYPE_NODEREF && mType != TYPE_UNKNOWN)
  1939. {
  1940. return 0;
  1941. }
  1942. std::string *string_array = new std::string[expected_length];
  1943. U32 num_strings = getStringValue(expected_length, string_array);
  1944. U32 num_returned_refs = 0;
  1945. LLXMLNodePtr root = getRoot();
  1946. for (U32 strnum=0; strnum<num_strings; ++strnum)
  1947. {
  1948. LLXMLNodeList node_list;
  1949. root->findID(string_array[strnum], node_list);
  1950. if (node_list.empty())
  1951. {
  1952. llwarns << "XML: Could not find node ID: " << string_array[strnum] << llendl;
  1953. }
  1954. else if (node_list.size() > 1)
  1955. {
  1956. llwarns << "XML: Node ID not unique: " << string_array[strnum] << llendl;
  1957. }
  1958. else
  1959. {
  1960. LLXMLNodeList::const_iterator list_itr = node_list.begin();
  1961. if (list_itr != node_list.end())
  1962. {
  1963. LLXMLNode* child = (*list_itr).second;
  1964. array[num_returned_refs++] = child;
  1965. }
  1966. }
  1967. }
  1968. delete[] string_array;
  1969. return num_returned_refs;
  1970. }
  1971. void LLXMLNode::setBoolValue(U32 length, const BOOL *array)
  1972. {
  1973. if (length == 0) return;
  1974. std::string new_value;
  1975. for (U32 pos=0; pos<length; ++pos)
  1976. {
  1977. if (pos > 0)
  1978. {
  1979. new_value = llformat("%s %s", new_value.c_str(), array[pos]?"true":"false");
  1980. }
  1981. else
  1982. {
  1983. new_value = array[pos]?"true":"false";
  1984. }
  1985. }
  1986. mValue = new_value;
  1987. mEncoding = ENCODING_DEFAULT;
  1988. mLength = length;
  1989. mType = TYPE_BOOLEAN;
  1990. }
  1991. void LLXMLNode::setByteValue(U32 length, const U8* const array, Encoding encoding)
  1992. {
  1993. if (length == 0) return;
  1994. std::string new_value;
  1995. if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL)
  1996. {
  1997. for (U32 pos=0; pos<length; ++pos)
  1998. {
  1999. if (pos > 0)
  2000. {
  2001. new_value.append(llformat(" %u", array[pos]));
  2002. }
  2003. else
  2004. {
  2005. new_value = llformat("%u", array[pos]);
  2006. }
  2007. }
  2008. }
  2009. if (encoding == ENCODING_HEX)
  2010. {
  2011. for (U32 pos=0; pos<length; ++pos)
  2012. {
  2013. if (pos > 0 && pos % 16 == 0)
  2014. {
  2015. new_value.append(llformat(" %02X", array[pos]));
  2016. }
  2017. else
  2018. {
  2019. new_value.append(llformat("%02X", array[pos]));
  2020. }
  2021. }
  2022. }
  2023. // TODO -- Handle Base32
  2024. mValue = new_value;
  2025. mEncoding = encoding;
  2026. mLength = length;
  2027. mType = TYPE_INTEGER;
  2028. mPrecision = 8;
  2029. }
  2030. void LLXMLNode::setIntValue(U32 length, const S32 *array, Encoding encoding)
  2031. {
  2032. if (length == 0) return;
  2033. std::string new_value;
  2034. if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL)
  2035. {
  2036. for (U32 pos=0; pos<length; ++pos)
  2037. {
  2038. if (pos > 0)
  2039. {
  2040. new_value.append(llformat(" %d", array[pos]));
  2041. }
  2042. else
  2043. {
  2044. new_value = llformat("%d", array[pos]);
  2045. }
  2046. }
  2047. mValue = new_value;
  2048. }
  2049. else if (encoding == ENCODING_HEX)
  2050. {
  2051. for (U32 pos=0; pos<length; ++pos)
  2052. {
  2053. if (pos > 0 && pos % 16 == 0)
  2054. {
  2055. new_value.append(llformat(" %08X", ((U32 *)array)[pos]));
  2056. }
  2057. else
  2058. {
  2059. new_value.append(llformat("%08X", ((U32 *)array)[pos]));
  2060. }
  2061. }
  2062. mValue = new_value;
  2063. }
  2064. else
  2065. {
  2066. mValue = new_value;
  2067. }
  2068. // TODO -- Handle Base32
  2069. mEncoding = encoding;
  2070. mLength = length;
  2071. mType = TYPE_INTEGER;
  2072. mPrecision = 32;
  2073. }
  2074. void LLXMLNode::setUnsignedValue(U32 length, const U32* array, Encoding encoding)
  2075. {
  2076. if (length == 0) return;
  2077. std::string new_value;
  2078. if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL)
  2079. {
  2080. for (U32 pos=0; pos<length; ++pos)
  2081. {
  2082. if (pos > 0)
  2083. {
  2084. new_value.append(llformat(" %u", array[pos]));
  2085. }
  2086. else
  2087. {
  2088. new_value = llformat("%u", array[pos]);
  2089. }
  2090. }
  2091. }
  2092. if (encoding == ENCODING_HEX)
  2093. {
  2094. for (U32 pos=0; pos<length; ++pos)
  2095. {
  2096. if (pos > 0 && pos % 16 == 0)
  2097. {
  2098. new_value.append(llformat(" %08X", array[pos]));
  2099. }
  2100. else
  2101. {
  2102. new_value.append(llformat("%08X", array[pos]));
  2103. }
  2104. }
  2105. mValue = new_value;
  2106. }
  2107. // TODO -- Handle Base32
  2108. mValue = new_value;
  2109. mEncoding = encoding;
  2110. mLength = length;
  2111. mType = TYPE_INTEGER;
  2112. mPrecision = 32;
  2113. }
  2114. #if LL_WINDOWS
  2115. #define PU64 "I64u"
  2116. #else
  2117. #define PU64 "llu"
  2118. #endif
  2119. void LLXMLNode::setLongValue(U32 length, const U64* array, Encoding encoding)
  2120. {
  2121. if (length == 0) return;
  2122. std::string new_value;
  2123. if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL)
  2124. {
  2125. for (U32 pos=0; pos<length; ++pos)
  2126. {
  2127. if (pos > 0)
  2128. {
  2129. new_value.append(llformat(" %" PU64, array[pos]));
  2130. }
  2131. else
  2132. {
  2133. new_value = llformat("%" PU64, array[pos]);
  2134. }
  2135. }
  2136. mValue = new_value;
  2137. }
  2138. if (encoding == ENCODING_HEX)
  2139. {
  2140. for (U32 pos=0; pos<length; ++pos)
  2141. {
  2142. U32 upper_32 = U32(array[pos]>>32);
  2143. U32 lower_32 = U32(array[pos]&0xffffffff);
  2144. if (pos > 0 && pos % 8 == 0)
  2145. {
  2146. new_value.append(llformat(" %08X%08X", upper_32, lower_32));
  2147. }
  2148. else
  2149. {
  2150. new_value.append(llformat("%08X%08X", upper_32, lower_32));
  2151. }
  2152. }
  2153. mValue = new_value;
  2154. }
  2155. else
  2156. {
  2157. mValue = new_value;
  2158. }
  2159. // TODO -- Handle Base32
  2160. mEncoding = encoding;
  2161. mLength = length;
  2162. mType = TYPE_INTEGER;
  2163. mPrecision = 64;
  2164. }
  2165. void LLXMLNode::setFloatValue(U32 length, const F32 *array, Encoding encoding, U32 precision)
  2166. {
  2167. if (length == 0) return;
  2168. std::string new_value;
  2169. if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL)
  2170. {
  2171. std::string format_string;
  2172. if (precision > 0)
  2173. {
  2174. if (precision > 25)
  2175. {
  2176. precision = 25;
  2177. }
  2178. format_string = llformat( "%%.%dg", precision);
  2179. }
  2180. else
  2181. {
  2182. format_string = llformat( "%%g");
  2183. }
  2184. for (U32 pos=0; pos<length; ++pos)
  2185. {
  2186. if (pos > 0)
  2187. {
  2188. new_value.append(" ");
  2189. new_value.append(llformat(format_string.c_str(), array[pos]));
  2190. }
  2191. else
  2192. {
  2193. new_value.assign(llformat(format_string.c_str(), array[pos]));
  2194. }
  2195. }
  2196. mValue = new_value;
  2197. }
  2198. else if (encoding == ENCODING_HEX)
  2199. {
  2200. U32 *byte_array = (U32 *)array;
  2201. setUnsignedValue(length, byte_array, ENCODING_HEX);
  2202. }
  2203. else
  2204. {
  2205. mValue = new_value;
  2206. }
  2207. mEncoding = encoding;
  2208. mLength = length;
  2209. mType = TYPE_FLOAT;
  2210. mPrecision = 32;
  2211. }
  2212. void LLXMLNode::setDoubleValue(U32 length, const F64 *array, Encoding encoding, U32 precision)
  2213. {
  2214. if (length == 0) return;
  2215. std::string new_value;
  2216. if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL)
  2217. {
  2218. std::string format_string;
  2219. if (precision > 0)
  2220. {
  2221. if (precision > 25)
  2222. {
  2223. precision = 25;
  2224. }
  2225. format_string = llformat( "%%.%dg", precision);
  2226. }
  2227. else
  2228. {
  2229. format_string = llformat( "%%g");
  2230. }
  2231. for (U32 pos=0; pos<length; ++pos)
  2232. {
  2233. if (pos > 0)
  2234. {
  2235. new_value.append(" ");
  2236. new_value.append(llformat(format_string.c_str(), array[pos]));
  2237. }
  2238. else
  2239. {
  2240. new_value.assign(llformat(format_string.c_str(), array[pos]));
  2241. }
  2242. }
  2243. mValue = new_value;
  2244. }
  2245. if (encoding == ENCODING_HEX)
  2246. {
  2247. U64 *byte_array = (U64 *)array;
  2248. setLongValue(length, byte_array, ENCODING_HEX);
  2249. }
  2250. else
  2251. {
  2252. mValue = new_value;
  2253. }
  2254. // TODO -- Handle Base32
  2255. mEncoding = encoding;
  2256. mLength = length;
  2257. mType = TYPE_FLOAT;
  2258. mPrecision = 64;
  2259. }
  2260. // static
  2261. std::string LLXMLNode::escapeXML(const std::string& xml)
  2262. {
  2263. std::string out;
  2264. for (std::string::size_type i = 0; i < xml.size(); ++i)
  2265. {
  2266. char c = xml[i];
  2267. switch(c)
  2268. {
  2269. case '"': out.append("&quot;"); break;
  2270. case '\'': out.append("&apos;"); break;
  2271. case '&': out.append("&amp;"); break;
  2272. case '<': out.append("&lt;"); break;
  2273. case '>': out.append("&gt;"); break;
  2274. default: out.push_back(c); break;
  2275. }
  2276. }
  2277. return out;
  2278. }
  2279. void LLXMLNode::setStringValue(U32 length, const std::string *strings)
  2280. {
  2281. if (length == 0) return;
  2282. std::string new_value;
  2283. for (U32 pos=0; pos<length; ++pos)
  2284. {
  2285. // *NOTE: Do not escape strings here - do it on output
  2286. new_value.append( strings[pos] );
  2287. if (pos < length-1) new_value.append(" ");
  2288. }
  2289. mValue = new_value;
  2290. mEncoding = ENCODING_DEFAULT;
  2291. mLength = length;
  2292. mType = TYPE_STRING;
  2293. }
  2294. void LLXMLNode::setUUIDValue(U32 length, const LLUUID *array)
  2295. {
  2296. if (length == 0) return;
  2297. std::string new_value;
  2298. for (U32 pos=0; pos<length; ++pos)
  2299. {
  2300. new_value.append(array[pos].asString());
  2301. if (pos < length-1) new_value.append(" ");
  2302. }
  2303. mValue = new_value;
  2304. mEncoding = ENCODING_DEFAULT;
  2305. mLength = length;
  2306. mType = TYPE_UUID;
  2307. }
  2308. void LLXMLNode::setNodeRefValue(U32 length, const LLXMLNode **array)
  2309. {
  2310. if (length == 0) return;
  2311. std::string new_value;
  2312. for (U32 pos=0; pos<length; ++pos)
  2313. {
  2314. if (array[pos]->mID != "")
  2315. {
  2316. new_value.append(array[pos]->mID);
  2317. }
  2318. else
  2319. {
  2320. new_value.append("(null)");
  2321. }
  2322. if (pos < length-1) new_value.append(" ");
  2323. }
  2324. mValue = new_value;
  2325. mEncoding = ENCODING_DEFAULT;
  2326. mLength = length;
  2327. mType = TYPE_NODEREF;
  2328. }
  2329. void LLXMLNode::setValue(const std::string& value)
  2330. {
  2331. if (TYPE_CONTAINER == mType)
  2332. {
  2333. mType = TYPE_UNKNOWN;
  2334. }
  2335. mValue = value;
  2336. }
  2337. void LLXMLNode::setDefault(LLXMLNode *default_node)
  2338. {
  2339. mDefault = default_node;
  2340. }
  2341. void LLXMLNode::findDefault(LLXMLNode *defaults_list)
  2342. {
  2343. if (defaults_list)
  2344. {
  2345. LLXMLNodeList children;
  2346. defaults_list->getChildren(mName->mString, children);
  2347. LLXMLNodeList::const_iterator children_itr;
  2348. LLXMLNodeList::const_iterator children_end = children.end();
  2349. for (children_itr = children.begin(); children_itr != children_end; ++children_itr)
  2350. {
  2351. LLXMLNode* child = (*children_itr).second;
  2352. if (child->mVersionMajor == mVersionMajor &&
  2353. child->mVersionMinor == mVersionMinor)
  2354. {
  2355. mDefault = child;
  2356. return;
  2357. }
  2358. }
  2359. }
  2360. mDefault = NULL;
  2361. }
  2362. BOOL LLXMLNode::deleteChildren(const std::string& name)
  2363. {
  2364. U32 removed_count = 0;
  2365. LLXMLNodeList node_list;
  2366. findName(name, node_list);
  2367. if (!node_list.empty())
  2368. {
  2369. // TODO -- use multimap::find()
  2370. // TODO -- need to watch out for invalid iterators
  2371. LLXMLNodeList::iterator children_itr;
  2372. for (children_itr = node_list.begin(); children_itr != node_list.end(); ++children_itr)
  2373. {
  2374. LLXMLNode* child = (*children_itr).second;
  2375. if (deleteChild(child))
  2376. {
  2377. removed_count++;
  2378. }
  2379. }
  2380. }
  2381. return removed_count > 0 ? TRUE : FALSE;
  2382. }
  2383. BOOL LLXMLNode::deleteChildren(LLStringTableEntry* name)
  2384. {
  2385. U32 removed_count = 0;
  2386. LLXMLNodeList node_list;
  2387. findName(name, node_list);
  2388. if (!node_list.empty())
  2389. {
  2390. // TODO -- use multimap::find()
  2391. // TODO -- need to watch out for invalid iterators
  2392. LLXMLNodeList::iterator children_itr;
  2393. for (children_itr = node_list.begin(); children_itr != node_list.end(); ++children_itr)
  2394. {
  2395. LLXMLNode* child = (*children_itr).second;
  2396. if (deleteChild(child))
  2397. {
  2398. removed_count++;
  2399. }
  2400. }
  2401. }
  2402. return removed_count > 0 ? TRUE : FALSE;
  2403. }
  2404. void LLXMLNode::setAttributes(LLXMLNode::ValueType type, U32 precision, LLXMLNode::Encoding encoding, U32 length)
  2405. {
  2406. mType = type;
  2407. mEncoding = encoding;
  2408. mPrecision = precision;
  2409. mLength = length;
  2410. }
  2411. void LLXMLNode::setName(const std::string& name)
  2412. {
  2413. setName(gStringTable.addStringEntry(name));
  2414. }
  2415. void LLXMLNode::setName(LLStringTableEntry* name)
  2416. {
  2417. LLXMLNode* old_parent = mParent;
  2418. if (mParent)
  2419. {
  2420. // we need to remove and re-add to the parent so that
  2421. // the multimap key agrees with this node's name
  2422. mParent->removeChild(this);
  2423. }
  2424. mName = name;
  2425. if (old_parent)
  2426. {
  2427. old_parent->addChild(this);
  2428. }
  2429. }
  2430. // Unused
  2431. // void LLXMLNode::appendValue(const std::string& value)
  2432. // {
  2433. // mValue.append(value);
  2434. // }
  2435. U32 LLXMLNode::getChildCount() const
  2436. {
  2437. if (mChildren.notNull())
  2438. {
  2439. return mChildren->map.size();
  2440. }
  2441. return 0;
  2442. }
  2443. //***************************************************
  2444. // UNIT TESTING
  2445. //***************************************************
  2446. U32 get_rand(U32 max_value)
  2447. {
  2448. U32 random_num = rand() + ((U32)rand() << 16);
  2449. return (random_num % max_value);
  2450. }
  2451. LLXMLNode *get_rand_node(LLXMLNode *node)
  2452. {
  2453. if (node->mChildren.notNull())
  2454. {
  2455. U32 num_children = node->mChildren->map.size();
  2456. if (get_rand(2) == 0)
  2457. {
  2458. while (true)
  2459. {
  2460. S32 child_num = S32(get_rand(num_children*2)) - num_children;
  2461. LLXMLChildList::iterator itor = node->mChildren->map.begin();
  2462. while (child_num > 0)
  2463. {
  2464. --child_num;
  2465. ++itor;
  2466. }
  2467. if (!itor->second->mIsAttribute)
  2468. {
  2469. return get_rand_node(itor->second);
  2470. }
  2471. }
  2472. }
  2473. }
  2474. return node;
  2475. }
  2476. void LLXMLNode::createUnitTest(S32 max_num_children)
  2477. {
  2478. // Random ID
  2479. std::string rand_id;
  2480. U32 rand_id_len = get_rand(10)+5;
  2481. for (U32 pos = 0; pos<rand_id_len; ++pos)
  2482. {
  2483. char c = 'a' + get_rand(26);
  2484. rand_id.append(1, c);
  2485. }
  2486. mID = rand_id;
  2487. if (max_num_children < 2)
  2488. {
  2489. setStringValue(1, &mID);
  2490. return;
  2491. }
  2492. // Checksums
  2493. U32 integer_checksum = 0;
  2494. U64 long_checksum = 0;
  2495. U32 bool_true_count = 0;
  2496. LLUUID uuid_checksum;
  2497. U32 noderef_checksum = 0;
  2498. U32 float_checksum = 0;
  2499. // Create a random number of children
  2500. U32 num_children = get_rand(max_num_children)+1;
  2501. for (U32 child_num=0; child_num<num_children; ++child_num)
  2502. {
  2503. // Random Name
  2504. std::string child_name;
  2505. U32 child_name_len = get_rand(10)+5;
  2506. for (U32 pos = 0; pos<child_name_len; ++pos)
  2507. {
  2508. char c = 'a' + get_rand(26);
  2509. child_name.append(1, c);
  2510. }
  2511. LLXMLNode *new_child = createChild(child_name.c_str(), FALSE);
  2512. // Random ID
  2513. std::string child_id;
  2514. U32 child_id_len = get_rand(10)+5;
  2515. for (U32 pos=0; pos<child_id_len; ++pos)
  2516. {
  2517. char c = 'a' + get_rand(26);
  2518. child_id.append(1, c);
  2519. }
  2520. new_child->mID = child_id;
  2521. // Random Length
  2522. U32 array_size = get_rand(28)+1;
  2523. // Random Encoding
  2524. Encoding new_encoding = get_rand(2)?ENCODING_DECIMAL:ENCODING_HEX;
  2525. // Random Type
  2526. int type = get_rand(8);
  2527. switch (type)
  2528. {
  2529. case 0: // TYPE_CONTAINER
  2530. new_child->createUnitTest(max_num_children/2);
  2531. break;
  2532. case 1: // TYPE_BOOLEAN
  2533. {
  2534. BOOL random_bool_values[30];
  2535. for (U32 value=0; value<array_size; ++value)
  2536. {
  2537. random_bool_values[value] = get_rand(2);
  2538. if (random_bool_values[value])
  2539. {
  2540. ++bool_true_count;
  2541. }
  2542. }
  2543. new_child->setBoolValue(array_size, random_bool_values);
  2544. }
  2545. break;
  2546. case 2: // TYPE_INTEGER (32-bit)
  2547. {
  2548. U32 random_int_values[30];
  2549. for (U32 value=0; value<array_size; ++value)
  2550. {
  2551. random_int_values[value] = get_rand(0xffffffff);
  2552. integer_checksum ^= random_int_values[value];
  2553. }
  2554. new_child->setUnsignedValue(array_size, random_int_values, new_encoding);
  2555. }
  2556. break;
  2557. case 3: // TYPE_INTEGER (64-bit)
  2558. {
  2559. U64 random_int_values[30];
  2560. for (U64 value=0; value<array_size; ++value)
  2561. {
  2562. random_int_values[value] = (U64(get_rand(0xffffffff)) << 32) + get_rand(0xffffffff);
  2563. long_checksum ^= random_int_values[value];
  2564. }
  2565. new_child->setLongValue(array_size, random_int_values, new_encoding);
  2566. }
  2567. break;
  2568. case 4: // TYPE_FLOAT (32-bit)
  2569. {
  2570. F32 random_float_values[30];
  2571. for (U32 value=0; value<array_size; ++value)
  2572. {
  2573. S32 exponent = get_rand(256) - 128;
  2574. S32 fractional_part = get_rand(0xffffffff);
  2575. S32 sign = get_rand(2) * 2 - 1;
  2576. random_float_values[value] = F32(fractional_part) / F32(0xffffffff) * exp(F32(exponent)) * F32(sign);
  2577. U32 *float_bits = &((U32 *)random_float_values)[value];
  2578. if (*float_bits == 0x80000000)
  2579. {
  2580. *float_bits = 0x00000000;
  2581. }
  2582. float_checksum ^= (*float_bits & 0xfffff000);
  2583. }
  2584. new_child->setFloatValue(array_size, random_float_values, new_encoding, 12);
  2585. }
  2586. break;
  2587. case 5: // TYPE_FLOAT (64-bit)
  2588. {
  2589. F64 random_float_values[30];
  2590. for (U32 value=0; value<array_size; ++value)
  2591. {
  2592. S32 exponent = get_rand(204