Changeset 48834 in vbox
- Timestamp:
- Oct 3, 2013 1:28:57 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
include/iprt/cpp/xml.h (modified) (15 diffs)
-
src/VBox/Runtime/r3/xml.cpp (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cpp/xml.h
r48797 r48834 31 31 #endif 32 32 33 /*#define USE_STD_LIST_FOR_CHILDREN*/34 35 33 #include <iprt/list.h> 36 34 #include <iprt/cpp/exception.h> 35 #include <iprt/cpp/utils.h> 37 36 38 37 #include <list> … … 395 394 { 396 395 public: 397 ~Node();396 virtual ~Node(); 398 397 399 398 const char *getName() const; … … 437 436 438 437 int getLineNumber() const; 439 440 438 /** @} */ 441 439 442 #ifndef USE_STD_LIST_FOR_CHILDREN443 440 /** @name General tree enumeration. 444 441 * … … 447 444 * can be of both ContentNode and ElementNode types. 448 445 * 446 * @remarks Attribute node are in the attributes list, while both content and 447 * element nodes are in the list of children. See ElementNode. 448 * 449 449 * @remarks Careful mixing tree walking with node removal! 450 450 * @{ … … 457 457 } 458 458 459 /** Get the first child node.460 * @returns Pointer to the first child node, NULL if no children. */461 const Node *getFirstChild() const462 {463 return RTListGetFirstCpp(&m_children, const Node, m_childEntry);464 }465 466 /** Get the last child node.467 * @returns Pointer to the last child node, NULL if no children. */468 const Node *getLastChild() const469 {470 return RTListGetLastCpp(&m_children, const Node, m_childEntry);471 }472 473 459 /** Get the previous sibling. 474 * @returns Pointer to the previous sibling node, NULL if first child. */ 460 * @returns Pointer to the previous sibling node, NULL if first child. 461 */ 475 462 const Node *getPrevSibiling() const 476 463 { 477 if (!m_pParent )464 if (!m_pParentListAnchor) 478 465 return NULL; 479 return RTListGetPrevCpp( &m_pParent->m_children, this, const Node, m_childEntry);466 return RTListGetPrevCpp(m_pParentListAnchor, this, const Node, m_listEntry); 480 467 } 481 468 … … 484 471 const Node *getNextSibiling() const 485 472 { 486 if (!m_pParent )473 if (!m_pParentListAnchor) 487 474 return NULL; 488 return RTListGetNextCpp( &m_pParent->m_children, this, const Node, m_childEntry);475 return RTListGetNextCpp(m_pParentListAnchor, this, const Node, m_listEntry); 489 476 } 490 477 /** @} */ 491 #endif492 478 493 479 protected: … … 495 481 typedef enum { IsElement, IsAttribute, IsContent } EnumType; 496 482 497 EnumType m_Type; /**< The type of node this is an instance of. */ 498 Node *m_pParent; /**< The parent node, NULL if root. */ 499 xmlNode *m_plibNode; ///< != NULL if this is an element or content node 500 xmlAttr *m_plibAttr; ///< != NULL if this is an attribute node 483 /** The type of node this is an instance of. */ 484 EnumType m_Type; 485 /** The parent node (always an element), NULL if root. */ 486 Node *m_pParent; 487 488 xmlNode *m_pLibNode; ///< != NULL if this is an element or content node 489 xmlAttr *m_pLibAttr; ///< != NULL if this is an attribute node 501 490 const char *m_pcszNamespacePrefix; ///< not always set 502 491 const char *m_pcszNamespaceHref; ///< full http:// spec 503 const char *m_pcszName; ///< element or attribute name, points either into p libNode or plibAttr;492 const char *m_pcszName; ///< element or attribute name, points either into pLibNode or pLibAttr; 504 493 ///< NULL if this is a content node 505 494 506 #ifndef USE_STD_LIST_FOR_CHILDREN507 495 /** Child list entry of this node. (List head m_pParent->m_children.) */ 508 RTLISTNODE m_ childEntry;509 /** Child elements, if this is an element; can be empty. */510 RTLISTANCHOR m_children;511 #endif 496 RTLISTNODE m_listEntry; 497 /** Pointer to the parent list anchor. 498 * This allows us to use m_listEntry both for children and attributes. */ 499 PRTLISTANCHOR m_pParentListAnchor; 512 500 513 501 // hide the default constructor so people use only our factory methods 514 502 Node(EnumType type, 515 503 Node *pParent, 516 xmlNode *plibNode, 517 xmlAttr *plibAttr); 504 PRTLISTANCHOR pListAnchor, 505 xmlNode *pLibNode, 506 xmlAttr *pLibAttr); 518 507 Node(const Node &x); // no copying 519 520 void buildChildren(const ElementNode &elmRoot);521 522 /* Obscure class data */523 struct Data;524 Data *m;525 508 526 509 friend class AttributeNode; … … 545 528 protected: 546 529 // hide the default constructor so people use only our factory methods 547 AttributeNode(const ElementNode &elmRoot,530 AttributeNode(const ElementNode *pElmRoot, 548 531 Node *pParent, 549 xmlAttr *plibAttr,550 const char **ppcszKey);532 PRTLISTANCHOR pListAnchor, 533 xmlAttr *pLibAttr); 551 534 AttributeNode(const AttributeNode &x); // no copying 552 535 536 /** For storing attribute names with namespace prefix. 537 * Only used if with non-default namespace specified. */ 553 538 RTCString m_strKey; 554 539 … … 615 600 } 616 601 617 618 /** @name Element enumeration. 602 /** Combines findChildElementP and findAttributeValue. 603 * 604 * @returns Pointer to attribute string value, NULL if either the element or 605 * the attribute was not found. 606 * @param pcszPath The attribute name. Slashes can be used to make a 607 * simple path to any decendant. 608 * @param pcszAttribute The attribute name. 609 * @param pcszPathNamespace The namespace to match @pcszPath with, NULL 610 * (default) match any namespace. When using a 611 * path, this matches all elements along the way. 612 * @see findChildElementP and findAttributeValue 613 */ 614 const char *findChildElementAttributeValueP(const char *pcszPath, const char *pcszAttribute, 615 const char *pcszPathNamespace = NULL) const 616 { 617 const ElementNode *pElem = findChildElementP(pcszPath, pcszPathNamespace); 618 if (pElem) 619 return pElem->findAttributeValue(pcszAttribute); 620 return NULL; 621 } 622 623 624 /** @name Tree enumeration. 619 625 * @{ */ 626 627 /** Get the next tree element in a full tree enumeration. 628 * 629 * By starting with the root node, this can be used to enumerate the entire tree 630 * (or sub-tree if @a pElmRoot is used). 631 * 632 * @returns Pointer to the next element in the tree, NULL if we're done. 633 * @param pElmRoot The root of the tree we're enumerating. NULL if 634 * it's the entire tree. 635 */ 636 ElementNode const *getNextTreeElement(ElementNode const *pElmRoot = NULL) const; 637 RT_CPP_GETTER_UNCONST_RET(ElementNode *, ElementNode, getNextTreeElement, (const ElementNode *pElmRoot = NULL), (pElmRoot)) 638 639 /** Get the first child node. 640 * @returns Pointer to the first child node, NULL if no children. */ 641 const Node *getFirstChild() const 642 { 643 return RTListGetFirstCpp(&m_children, const Node, m_listEntry); 644 } 645 RT_CPP_GETTER_UNCONST_RET(Node *, ElementNode, getFirstChild,(),()) 646 647 /** Get the last child node. 648 * @returns Pointer to the last child node, NULL if no children. */ 649 const Node *getLastChild() const 650 { 651 return RTListGetLastCpp(&m_children, const Node, m_listEntry); 652 } 653 654 /** Get the first child node. 655 * @returns Pointer to the first child node, NULL if no children. */ 656 const ElementNode *getFirstChildElement() const; 657 658 /** Get the last child node. 659 * @returns Pointer to the last child node, NULL if no children. */ 660 const ElementNode *getLastChildElement() const; 661 620 662 /** Get the previous sibling element. 621 663 * @returns Pointer to the previous sibling element, NULL if first child … … 667 709 } 668 710 669 bool getAttributeValue(const char *pcszMatch, const char *&pcsz) const ;711 bool getAttributeValue(const char *pcszMatch, const char *&pcsz) const { return getAttributeValue(pcszMatch, &pcsz); } 670 712 bool getAttributeValue(const char *pcszMatch, RTCString &str) const; 671 713 bool getAttributeValuePath(const char *pcszMatch, RTCString &str) const; 672 714 bool getAttributeValue(const char *pcszMatch, int32_t &i) const; 673 715 bool getAttributeValue(const char *pcszMatch, uint32_t &i) const; 674 bool getAttributeValue(const char *pcszMatch, int64_t &i) const ;716 bool getAttributeValue(const char *pcszMatch, int64_t &i) const { return getAttributeValue(pcszMatch, &i); } 675 717 bool getAttributeValue(const char *pcszMatch, uint64_t &i) const; 676 718 bool getAttributeValue(const char *pcszMatch, bool &f) const; … … 678 720 /** @name Variants that for clarity does not use references for output params. 679 721 * @{ */ 680 bool getAttributeValue(const char *pcszMatch, const char **ppcsz) const { return getAttributeValue(pcszMatch, *ppcsz); }722 bool getAttributeValue(const char *pcszMatch, const char **ppcsz) const; 681 723 bool getAttributeValue(const char *pcszMatch, RTCString *pStr) const { return getAttributeValue(pcszMatch, *pStr); } 682 724 bool getAttributeValuePath(const char *pcszMatch, RTCString *pStr) const { return getAttributeValuePath(pcszMatch, *pStr); } 683 725 bool getAttributeValue(const char *pcszMatch, int32_t *pi) const { return getAttributeValue(pcszMatch, *pi); } 684 726 bool getAttributeValue(const char *pcszMatch, uint32_t *pu) const { return getAttributeValue(pcszMatch, *pu); } 685 bool getAttributeValue(const char *pcszMatch, int64_t *pi ) const { return getAttributeValue(pcszMatch, *pi); }727 bool getAttributeValue(const char *pcszMatch, int64_t *piValue) const; 686 728 bool getAttributeValue(const char *pcszMatch, uint64_t *pu) const { return getAttributeValue(pcszMatch, *pu); } 687 729 bool getAttributeValue(const char *pcszMatch, bool *pf) const { return getAttributeValue(pcszMatch, *pf); } 688 730 /** @} */ 689 731 732 /** @name Convenience methods for convering the element value. 733 * @{ */ 734 bool getElementValue(int32_t *piValue) const; 735 bool getElementValue(uint32_t *puValue) const; 736 bool getElementValue(int64_t *piValue) const; 737 bool getElementValue(uint64_t *puValue) const; 738 bool getElementValue(bool *pfValue) const; 739 /** @} */ 740 741 /** @name Convenience findChildElementAttributeValueP and getElementValue. 742 * @{ */ 743 bool getChildElementValueP(const char *pcszPath, int32_t *piValue, const char *pcszNamespace = NULL) const 744 { 745 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 746 return pElem && pElem->getElementValue(piValue); 747 } 748 bool getChildElementValueP(const char *pcszPath, uint32_t *puValue, const char *pcszNamespace = NULL) const 749 { 750 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 751 return pElem && pElem->getElementValue(puValue); 752 } 753 bool getChildElementValueP(const char *pcszPath, int64_t *piValue, const char *pcszNamespace = NULL) const 754 { 755 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 756 return pElem && pElem->getElementValue(piValue); 757 } 758 bool getChildElementValueP(const char *pcszPath, uint64_t *puValue, const char *pcszNamespace = NULL) const 759 { 760 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 761 return pElem && pElem->getElementValue(puValue); 762 } 763 bool getChildElementValueP(const char *pcszPath, bool *pfValue, const char *pcszNamespace = NULL) const 764 { 765 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 766 return pElem && pElem->getElementValue(pfValue); 767 } 768 769 /** @} */ 770 771 /** @name Convenience findChildElementAttributeValueP and getElementValue with a 772 * default value being return if the child element isn't present. 773 * 774 * @remarks These will return false on conversion errors. 775 * @{ */ 776 bool getChildElementValueDefP(const char *pcszPath, int32_t iDefault, int32_t *piValue, const char *pcszNamespace = NULL) const 777 { 778 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 779 if (pElem) 780 return pElem->getElementValue(piValue); 781 *piValue = iDefault; 782 return true; 783 } 784 bool getChildElementValueDefP(const char *pcszPath, uint32_t uDefault, uint32_t *puValue, const char *pcszNamespace = NULL) const 785 { 786 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 787 if (pElem) 788 return pElem->getElementValue(puValue); 789 *puValue = uDefault; 790 return true; 791 } 792 bool getChildElementValueDefP(const char *pcszPath, int64_t iDefault, int64_t *piValue, const char *pcszNamespace = NULL) const 793 { 794 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 795 if (pElem) 796 return pElem->getElementValue(piValue); 797 *piValue = iDefault; 798 return true; 799 } 800 bool getChildElementValueDefP(const char *pcszPath, uint64_t uDefault, uint64_t *puValue, const char *pcszNamespace = NULL) const 801 { 802 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 803 if (pElem) 804 return pElem->getElementValue(puValue); 805 *puValue = uDefault; 806 return true; 807 } 808 bool getChildElementValueDefP(const char *pcszPath, bool fDefault, bool *pfValue, const char *pcszNamespace = NULL) const 809 { 810 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 811 if (pElem) 812 return pElem->getElementValue(pfValue); 813 *pfValue = fDefault; 814 return true; 815 } 816 /** @} */ 690 817 691 818 ElementNode *createChild(const char *pcszElementName); … … 712 839 protected: 713 840 // hide the default constructor so people use only our factory methods 714 ElementNode(const ElementNode *p elmRoot, Node *pParent, xmlNode *plibNode);841 ElementNode(const ElementNode *pElmRoot, Node *pParent, PRTLISTANCHOR pListAnchor, xmlNode *pLibNode); 715 842 ElementNode(const ElementNode &x); // no copying 716 717 const ElementNode *m_pelmRoot; 843 virtual ElementNode::~ElementNode(); 844 845 /** We keep a pointer to the root element for attribute namespace handling. */ 846 const ElementNode *m_pElmRoot; 847 848 /** List of child elements and content nodes. */ 849 RTLISTANCHOR m_children; 850 /** List of attributes nodes. */ 851 RTLISTANCHOR m_attributes; 852 853 static void buildChildren(ElementNode *pElmRoot); 718 854 719 855 friend class Node; … … 736 872 protected: 737 873 // hide the default constructor so people use only our factory methods 738 ContentNode(Node *pParent, xmlNode *plibNode);874 ContentNode(Node *pParent, PRTLISTANCHOR pListAnchor, xmlNode *pLibNode); 739 875 ContentNode(const ContentNode &x); // no copying 740 876 … … 772 908 XmlFileParser parser; 773 909 parser.read("file.xml", doc); 774 Element *p elmRoot = doc.getRootElement();910 Element *pElmRoot = doc.getRootElement(); 775 911 @endcode 776 912 * … … 780 916 * @code 781 917 Document doc; 782 Element *p elmRoot = doc.createRootElement();918 Element *pElmRoot = doc.createRootElement(); 783 919 // add children 784 920 xml::XmlFileWriter writer(doc); -
trunk/src/VBox/Runtime/r3/xml.cpp
r48797 r48834 47 47 48 48 #include <map> 49 #include <boost/shared_ptr.hpp> /* This is the ONLY use of boost. */50 49 51 50 … … 156 155 RTStrAPrintfV(&pszContext2, pcszContext, args); 157 156 char *newMsg; 158 RTStrAPrintf(&newMsg, "%s: %d (%s)", pszContext2, aRC, RTErrGetShort(aRC));157 RTStrAPrintf(&newMsg, "%s: %d(%s)", pszContext2, aRC, RTErrGetShort(aRC)); 159 158 setWhat(newMsg); 160 159 RTStrFree(newMsg); … … 241 240 } 242 241 243 const char *File::uri() const242 const char *File::uri() const 244 243 { 245 244 return m->strFileName.c_str(); … … 291 290 { 292 291 size_t len = aLen; 293 int vrc = RTFileWrite (m->handle, aBuf, len, &len);294 if (RT_SUCCESS (vrc))292 int vrc = RTFileWrite(m->handle, aBuf, len, &len); 293 if (RT_SUCCESS(vrc)) 295 294 return (int)len; 296 295 297 296 throw EIPRTFailure(vrc, "Runtime error writing to file '%s'", m->strFileName.c_str()); 298 299 return -1 /* failure */;300 297 } 301 298 302 299 void File::truncate() 303 300 { 304 int vrc = RTFileSetSize (m->handle, pos());305 if (RT_SUCCESS (vrc))301 int vrc = RTFileSetSize(m->handle, pos()); 302 if (RT_SUCCESS(vrc)) 306 303 return; 307 304 … … 318 315 { 319 316 Data() 320 : buf (NULL), len (0), uri (NULL), pos(0) {}317 : buf(NULL), len(0), uri(NULL), pos(0) {} 321 318 322 319 const char *buf; … … 327 324 }; 328 325 329 MemoryBuf::MemoryBuf (const char *aBuf, size_t aLen, const char *aURI /* = NULL */)330 : m (new Data())326 MemoryBuf::MemoryBuf(const char *aBuf, size_t aLen, const char *aURI /* = NULL */) 327 : m(new Data()) 331 328 { 332 329 if (aBuf == NULL) 333 throw EInvalidArg (RT_SRC_POS);330 throw EInvalidArg(RT_SRC_POS); 334 331 335 332 m->buf = aBuf; 336 333 m->len = aLen; 337 m->uri = RTStrDup (aURI);334 m->uri = RTStrDup(aURI); 338 335 } 339 336 340 337 MemoryBuf::~MemoryBuf() 341 338 { 342 RTStrFree (m->uri);339 RTStrFree(m->uri); 343 340 } 344 341 … … 353 350 } 354 351 355 void MemoryBuf::setPos (uint64_t aPos)356 { 357 size_t off = (size_t) aPos;352 void MemoryBuf::setPos(uint64_t aPos) 353 { 354 size_t off = (size_t)aPos; 358 355 if ((uint64_t) off != aPos) 359 356 throw EInvalidArg(); … … 365 362 } 366 363 367 int MemoryBuf::read (char *aBuf, int aLen)364 int MemoryBuf::read(char *aBuf, int aLen) 368 365 { 369 366 if (m->pos >= m->len) … … 371 368 372 369 size_t len = m->pos + aLen < m->len ? aLen : m->len - m->pos; 373 memcpy (aBuf, m->buf + m->pos, len);370 memcpy(aBuf, m->buf + m->pos, len); 374 371 m->pos += len; 375 372 … … 422 419 } 423 420 421 422 424 423 //////////////////////////////////////////////////////////////////////////////// 425 424 // … … 427 426 // 428 427 //////////////////////////////////////////////////////////////////////////////// 429 430 struct Node::Data431 {432 struct compare_const_char433 {434 bool operator()(const char* s1, const char* s2) const435 {436 return strcmp(s1, s2) < 0;437 }438 };439 440 // attributes, if this is an element; can be empty441 typedef std::map<const char*, boost::shared_ptr<AttributeNode>, compare_const_char > AttributesMap;442 AttributesMap attribs;443 444 #ifdef USE_STD_LIST_FOR_CHILDREN445 // child elements, if this is an element; can be empty446 typedef std::list< boost::shared_ptr<Node> > InternalNodesList;447 InternalNodesList children;448 #endif449 };450 428 451 429 Node::Node(EnumType type, 452 430 Node *pParent, 453 xmlNode *plibNode, 454 xmlAttr *plibAttr) 431 PRTLISTANCHOR pListAnchor, 432 xmlNode *pLibNode, 433 xmlAttr *pLibAttr) 455 434 : m_Type(type) 456 435 , m_pParent(pParent) 457 , m_p libNode(plibNode)458 , m_p libAttr(plibAttr)436 , m_pLibNode(pLibNode) 437 , m_pLibAttr(pLibAttr) 459 438 , m_pcszNamespacePrefix(NULL) 460 439 , m_pcszNamespaceHref(NULL) 461 440 , m_pcszName(NULL) 462 , m(new Data) 463 { 464 #ifndef USE_STD_LIST_FOR_CHILDREN 465 RTListInit(&m_childEntry); 466 RTListInit(&m_children); 467 #endif 441 , m_pParentListAnchor(pListAnchor) 442 { 443 RTListInit(&m_listEntry); 468 444 } 469 445 470 446 Node::~Node() 471 447 { 472 #ifndef USE_STD_LIST_FOR_CHILDREN473 Node *pCur, *pNext;474 RTListForEachSafeCpp(&m_children, pCur, pNext, Node, m_childEntry)475 {476 delete pCur;477 }478 RTListInit(&m_children);479 #endif480 delete m;481 }482 483 /**484 * Private implementation.485 * @param elmRoot486 */487 void Node::buildChildren(const ElementNode &elmRoot) // private488 {489 // go thru this element's attributes490 xmlAttr *plibAttr = m_plibNode->properties;491 while (plibAttr)492 {493 const char *pcszKey;494 boost::shared_ptr<AttributeNode> pNew(new AttributeNode(elmRoot, this, plibAttr, &pcszKey));495 // store496 m->attribs[pcszKey] = pNew;497 498 plibAttr = plibAttr->next;499 }500 501 // go thru this element's child elements502 for (xmlNodePtr plibNode = m_plibNode->children; plibNode; plibNode = plibNode->next)503 {504 #ifndef USE_STD_LIST_FOR_CHILDREN505 Node *pNew;506 if (plibNode->type == XML_ELEMENT_NODE)507 pNew = new ElementNode(&elmRoot, this, plibNode);508 else if (plibNode->type == XML_TEXT_NODE)509 pNew = new ContentNode(this, plibNode);510 else511 continue;512 RTListAppend(&m_children, &pNew->m_childEntry);513 514 /* Recurse for this child element to get its own children. */515 pNew->buildChildren(elmRoot);516 #else517 boost::shared_ptr<Node> pNew;518 519 if (plibNode->type == XML_ELEMENT_NODE)520 pNew = boost::shared_ptr<Node>(new ElementNode(&elmRoot, this, plibNode));521 else if (plibNode->type == XML_TEXT_NODE)522 pNew = boost::shared_ptr<Node>(new ContentNode(this, plibNode));523 if (pNew)524 {525 // store526 m->children.push_back(pNew);527 528 // recurse for this child element to get its own children529 pNew->buildChildren(elmRoot);530 }531 #endif532 }533 448 } 534 449 … … 538 453 * @return 539 454 */ 540 const char *Node::getName() const455 const char *Node::getName() const 541 456 { 542 457 return m_pcszName; … … 548 463 * @return 549 464 */ 550 const char *Node::getPrefix() const465 const char *Node::getPrefix() const 551 466 { 552 467 return m_pcszNamespacePrefix; … … 558 473 * @return 559 474 */ 560 const char *Node::getNamespaceURI() const475 const char *Node::getNamespaceURI() const 561 476 { 562 477 return m_pcszNamespaceHref; … … 627 542 const char *Node::getValue() const 628 543 { 629 if ( m_p libAttr630 && m_p libAttr->children544 if ( m_pLibAttr 545 && m_pLibAttr->children 631 546 ) 632 547 // libxml hides attribute values in another node created as a 633 548 // single child of the attribute node, and it's in the content field 634 return (const char *)m_p libAttr->children->content;635 636 if ( m_p libNode637 && m_p libNode->children)638 return (const char *)m_p libNode->children->content;549 return (const char *)m_pLibAttr->children->content; 550 551 if ( m_pLibNode 552 && m_pLibNode->children) 553 return (const char *)m_pLibNode->children->content; 639 554 640 555 return NULL; … … 716 631 int Node::getLineNumber() const 717 632 { 718 if (m_p libAttr)719 return m_pParent->m_p libNode->line;720 721 return m_p libNode->line;633 if (m_pLibAttr) 634 return m_pParent->m_pLibNode->line; 635 636 return m_pLibNode->line; 722 637 } 723 638 724 639 /** 725 640 * Private element constructor. 726 * @param pelmRoot 727 * @param pParent 728 * @param plibNode 729 */ 730 ElementNode::ElementNode(const ElementNode *pelmRoot, 641 * 642 * @param pElmRoot Pointer to the root element. 643 * @param pParent Pointer to the parent element (always an ElementNode, 644 * despite the type). NULL for the root node. 645 * @param pListAnchor Pointer to the m_children member of the parent. NULL 646 * for the root node. 647 * @param pLibNode Pointer to the libxml2 node structure. 648 */ 649 ElementNode::ElementNode(const ElementNode *pElmRoot, 731 650 Node *pParent, 732 xmlNode *plibNode) 651 PRTLISTANCHOR pListAnchor, 652 xmlNode *pLibNode) 733 653 : Node(IsElement, 734 654 pParent, 735 plibNode, 655 pListAnchor, 656 pLibNode, 736 657 NULL) 737 658 { 738 if (!(m_pelmRoot = pelmRoot)) 739 // NULL passed, then this is the root element 740 m_pelmRoot = this; 741 742 m_pcszName = (const char*)plibNode->name; 743 744 if (plibNode->ns) 745 { 746 m_pcszNamespacePrefix = (const char*)m_plibNode->ns->prefix; 747 m_pcszNamespaceHref = (const char*)m_plibNode->ns->href; 748 } 749 } 659 m_pElmRoot = pElmRoot ? pElmRoot : this; // If NULL is passed, then this is the root element. 660 m_pcszName = (const char *)pLibNode->name; 661 662 if (pLibNode->ns) 663 { 664 m_pcszNamespacePrefix = (const char *)m_pLibNode->ns->prefix; 665 m_pcszNamespaceHref = (const char *)m_pLibNode->ns->href; 666 } 667 668 RTListInit(&m_children); 669 RTListInit(&m_attributes); 670 } 671 672 ElementNode::~ElementNode() 673 { 674 Node *pCur, *pNext; 675 RTListForEachSafeCpp(&m_children, pCur, pNext, Node, m_listEntry) 676 { 677 delete pCur; 678 } 679 RTListInit(&m_children); 680 681 RTListForEachSafeCpp(&m_attributes, pCur, pNext, Node, m_listEntry) 682 { 683 delete pCur; 684 } 685 RTListInit(&m_attributes); 686 } 687 688 689 /** 690 * Gets the next tree element in a full tree enumeration. 691 * 692 * @returns Pointer to the next element in the tree, NULL if we're done. 693 * @param pElmRoot The root of the tree we're enumerating. NULL if 694 * it's the entire tree. 695 */ 696 ElementNode const *ElementNode::getNextTreeElement(ElementNode const *pElmRoot /*= NULL */) const 697 { 698 /* 699 * Consider children first. 700 */ 701 ElementNode const *pChild = getFirstChildElement(); 702 if (pChild) 703 return pChild; 704 705 /* 706 * Then siblings, aunts and uncles. 707 */ 708 ElementNode const *pCur = this; 709 do 710 { 711 ElementNode const *pSibling = pCur->getNextSibilingElement(); 712 if (pSibling != NULL) 713 return pSibling; 714 715 pCur = static_cast<const xml::ElementNode *>(pCur->m_pParent); 716 Assert(pCur || pCur == pElmRoot); 717 } while (pCur != pElmRoot); 718 719 return NULL; 720 } 721 722 723 /** 724 * Private implementation. 725 * 726 * @param pElmRoot The root element. 727 */ 728 /*static*/ void ElementNode::buildChildren(ElementNode *pElmRoot) // protected 729 { 730 for (ElementNode *pCur = pElmRoot; pCur; pCur = pCur->getNextTreeElement(pElmRoot)) 731 { 732 /* 733 * Go thru this element's attributes creating AttributeNodes for them. 734 */ 735 for (xmlAttr *pLibAttr = pCur->m_pLibNode->properties; pLibAttr; pLibAttr = pLibAttr->next) 736 { 737 AttributeNode *pNew = new AttributeNode(pElmRoot, pCur, &pCur->m_attributes, pLibAttr); 738 RTListAppend(&pCur->m_attributes, &pNew->m_listEntry); 739 } 740 741 /* 742 * Go thru this element's child elements (element and text nodes). 743 */ 744 for (xmlNodePtr pLibNode = pCur->m_pLibNode->children; pLibNode; pLibNode = pLibNode->next) 745 { 746 Node *pNew; 747 if (pLibNode->type == XML_ELEMENT_NODE) 748 pNew = new ElementNode(pElmRoot, pCur, &pCur->m_children, pLibNode); 749 else if (pLibNode->type == XML_TEXT_NODE) 750 pNew = new ContentNode(pCur, &pCur->m_children, pLibNode); 751 else 752 continue; 753 RTListAppend(&pCur->m_children, &pNew->m_listEntry); 754 } 755 } 756 } 757 750 758 751 759 /** … … 762 770 { 763 771 int i = 0; 764 #ifndef USE_STD_LIST_FOR_CHILDREN765 772 Node *p; 766 RTListForEachCpp(&m_children, p, Node, m_childEntry) 767 #else 768 for (Data::InternalNodesList::iterator it = m->children.begin(); 769 it != m->children.end(); 770 ++it) 771 #endif 773 RTListForEachCpp(&m_children, p, Node, m_listEntry) 772 774 { 773 775 // export this child node if ... 774 #ifdef USE_STD_LIST_FOR_CHILDREN775 Node *p = it->get();776 #endif777 776 if (p->isElement()) 778 777 if ( !pcszMatch // ... the caller wants all nodes or ... … … 796 795 const ElementNode *ElementNode::findChildElement(const char *pcszNamespace, const char *pcszMatch) const 797 796 { 798 #ifndef USE_STD_LIST_FOR_CHILDREN799 797 Node *p; 800 RTListForEachCpp(&m_children, p, Node, m_ childEntry)798 RTListForEachCpp(&m_children, p, Node, m_listEntry) 801 799 { 802 800 if (p->isElement()) … … 807 805 } 808 806 } 809 #else810 Data::InternalNodesList::const_iterator811 it,812 last = m->children.end();813 for (it = m->children.begin(); it != last; ++it)814 if ((**it).isElement())815 {816 ElementNode *pelm = static_cast<ElementNode*>((*it).get());817 if (pelm->nameEquals(pcszNamespace, pcszMatch))818 return pelm;819 }820 #endif821 822 807 return NULL; 823 808 } … … 828 813 * @return child element or NULL if not found. 829 814 */ 830 const ElementNode * ElementNode::findChildElementFromId(const char *pcszId) const 831 { 832 #ifndef USE_STD_LIST_FOR_CHILDREN 833 Node *p; 834 RTListForEachCpp(&m_children, p, Node, m_childEntry) 815 const ElementNode *ElementNode::findChildElementFromId(const char *pcszId) const 816 { 817 const Node *p; 818 RTListForEachCpp(&m_children, p, Node, m_listEntry) 835 819 { 836 820 if (p->isElement()) 837 821 { 838 ElementNode *pelm = static_cast<ElementNode*>(p);839 const AttributeNode *pAttr = p elm->findAttribute("id");822 const ElementNode *pElm = static_cast<const ElementNode *>(p); 823 const AttributeNode *pAttr = pElm->findAttribute("id"); 840 824 if (pAttr && !strcmp(pAttr->getValue(), pcszId)) 841 return p elm;825 return pElm; 842 826 } 843 827 } 844 #else845 Data::InternalNodesList::const_iterator846 it,847 last = m->children.end();848 for (it = m->children.begin();849 it != last;850 ++it)851 {852 if ((**it).isElement())853 {854 ElementNode *pelm = static_cast<ElementNode*>((*it).get());855 const AttributeNode *pAttr;856 if ( ((pAttr = pelm->findAttribute("id")))857 && (!strcmp(pAttr->getValue(), pcszId))858 )859 return pelm;860 }861 }862 #endif863 828 return NULL; 864 829 } … … 871 836 return this->findChildElement(pcszNamespace, pcszPath); 872 837 873 #ifndef USE_STD_LIST_FOR_CHILDREN874 838 /** @todo Can be done without recursion as we have both sibling lists and parent 875 839 * pointers in this variant. */ 876 Node *p;877 RTListForEachCpp(&m_children, p, Node, m_ childEntry)840 const Node *p; 841 RTListForEachCpp(&m_children, p, Node, m_listEntry) 878 842 { 879 843 if (p->isElement()) 880 844 { 881 const ElementNode *pElm = static_cast< ElementNode*>(p);845 const ElementNode *pElm = static_cast<const ElementNode *>(p); 882 846 if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis)) 883 847 { … … 888 852 } 889 853 } 890 #else 891 Data::InternalNodesList::const_iterator itLast = m->children.end(); 892 for (Data::InternalNodesList::const_iterator it = m->children.begin(); it != itLast; ++it) 893 { 894 if ((**it).isElement()) 895 { 896 const ElementNode *pElm = static_cast<ElementNode*>((*it).get()); 897 if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis)) 898 { 899 pElm = findChildElementP(pcszPath + cchThis, pcszNamespace); 900 if (pElm) 901 return pElm; 902 } 903 } 904 } 905 #endif 906 854 855 return NULL; 856 } 857 858 const ElementNode *ElementNode::getFirstChildElement() const 859 { 860 const Node *p; 861 RTListForEachCpp(&m_children, p, Node, m_listEntry) 862 { 863 if (p->isElement()) 864 return static_cast<const ElementNode *>(p); 865 } 866 return NULL; 867 } 868 869 const ElementNode *ElementNode::getLastChildElement() const 870 { 871 const Node *p; 872 RTListForEachReverseCpp(&m_children, p, Node, m_listEntry) 873 { 874 if (p->isElement()) 875 return static_cast<const ElementNode *>(p); 876 } 907 877 return NULL; 908 878 } … … 915 885 for (;;) 916 886 { 917 pSibling = RTListGetPrevCpp( &m_pParent->m_children, pSibling, const Node, m_childEntry);887 pSibling = RTListGetPrevCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry); 918 888 if (!pSibling) 919 889 return NULL; … … 930 900 for (;;) 931 901 { 932 pSibling = RTListGetNextCpp( &m_pParent->m_children, pSibling, const Node, m_childEntry);902 pSibling = RTListGetNextCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry); 933 903 if (!pSibling) 934 904 return NULL; … … 945 915 for (;;) 946 916 { 947 pSibling = RTListGetPrevCpp( &m_pParent->m_children, pSibling, const Node, m_childEntry);917 pSibling = RTListGetPrevCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry); 948 918 if (!pSibling) 949 919 return NULL; … … 964 934 for (;;) 965 935 { 966 pSibling = RTListGetNextCpp( &m_pParent->m_children, pSibling, const Node, m_childEntry);936 pSibling = RTListGetNextCpp(m_pParentListAnchor, pSibling, const Node, m_listEntry); 967 937 if (!pSibling) 968 938 return NULL; … … 998 968 * @return 999 969 */ 1000 const AttributeNode *ElementNode::findAttribute(const char *pcszMatch) const1001 { 1002 Data::AttributesMap::const_iterator it;1003 1004 it = m->attribs.find(pcszMatch);1005 if (it != m->attribs.end())1006 return it->second.get();1007 970 const AttributeNode *ElementNode::findAttribute(const char *pcszMatch) const 971 { 972 AttributeNode *p; 973 RTListForEachCpp(&m_attributes, p, AttributeNode, m_listEntry) 974 { 975 if (p->nameEquals(pcszMatch)) 976 return p; 977 } 1008 978 return NULL; 1009 979 } … … 1013 983 * name and returns its value as a string. 1014 984 * 1015 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 1016 * @param ppcsz out: attribute value 1017 * @return TRUE if attribute was found and str was thus updated. 1018 */ 1019 bool ElementNode::getAttributeValue(const char *pcszMatch, const char *&ppcsz) const 1020 { 1021 const Node* pAttr; 1022 if ((pAttr = findAttribute(pcszMatch))) 1023 { 1024 ppcsz = pAttr->getValue(); 985 * @param pcszMatch Name of attribute to find (see findAttribute() for 986 * namespace remarks). 987 * @param ppcsz Where to return the attribute. 988 * @returns Boolean success indicator. 989 */ 990 bool ElementNode::getAttributeValue(const char *pcszMatch, const char **ppcsz) const 991 { 992 const AttributeNode *pAttr = findAttribute(pcszMatch); 993 if (pAttr) 994 { 995 *ppcsz = pAttr->getValue(); 1025 996 return true; 1026 997 } 1027 1028 998 return false; 1029 999 } … … 1033 1003 * name and returns its value as a string. 1034 1004 * 1035 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 1036 * @param str out: attribute value; overwritten only if attribute was found 1037 * @return TRUE if attribute was found and str was thus updated. 1038 */ 1039 bool ElementNode::getAttributeValue(const char *pcszMatch, RTCString &str) const 1040 { 1041 const Node* pAttr; 1042 if ((pAttr = findAttribute(pcszMatch))) 1043 { 1044 str = pAttr->getValue(); 1005 * @param pcszMatch Name of attribute to find (see findAttribute() for 1006 * namespace remarks). 1007 * @param rStr Reference to the string object that should receive the 1008 * attribute value. 1009 * @returns Boolean success indicator. 1010 * 1011 * @throws Whatever the string class may throw on assignment. 1012 */ 1013 bool ElementNode::getAttributeValue(const char *pcszMatch, RTCString &rStr) const 1014 { 1015 const AttributeNode *pAttr = findAttribute(pcszMatch); 1016 if (pAttr) 1017 { 1018 rStr = pAttr->getValue(); 1045 1019 return true; 1046 1020 } … … 1115 1089 * function returns no error. 1116 1090 * 1117 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 1118 * @param i out: attribute value 1119 * @return TRUE if attribute was found and str was thus updated. 1120 */ 1121 bool ElementNode::getAttributeValue(const char *pcszMatch, int64_t &i) const 1122 { 1123 const char *pcsz; 1124 if ( (getAttributeValue(pcszMatch, pcsz)) 1125 && (VINF_SUCCESS == RTStrToInt64Ex(pcsz, NULL, 0, &i)) 1126 ) 1127 return true; 1128 1091 * @param pcszMatch Name of attribute to find (see findAttribute() for 1092 * namespace remarks). 1093 * @param i Where to return the attribute value on success. 1094 * @returns Boolean success indicator. 1095 */ 1096 bool ElementNode::getAttributeValue(const char *pcszMatch, int64_t *piValue) const 1097 { 1098 const char *pcsz = findAttributeValue(pcszMatch); 1099 if (pcsz) 1100 { 1101 int rc = RTStrToInt64Ex(pcsz, NULL, 0, piValue); 1102 if (rc == VINF_SUCCESS) 1103 return true; 1104 } 1129 1105 return false; 1130 1106 } … … 1165 1141 if (getAttributeValue(pcszMatch, pcsz)) 1166 1142 { 1167 if ( (!strcmp(pcsz, "true"))1168 || (!strcmp(pcsz, "yes"))1169 || (!strcmp(pcsz, "1"))1143 if ( !strcmp(pcsz, "true") 1144 || !strcmp(pcsz, "yes") 1145 || !strcmp(pcsz, "1") 1170 1146 ) 1171 1147 { … … 1173 1149 return true; 1174 1150 } 1175 if ( (!strcmp(pcsz, "false"))1176 || (!strcmp(pcsz, "no"))1177 || (!strcmp(pcsz, "0"))1151 if ( !strcmp(pcsz, "false") 1152 || !strcmp(pcsz, "no") 1153 || !strcmp(pcsz, "0") 1178 1154 ) 1179 1155 { … … 1186 1162 } 1187 1163 1164 1165 bool ElementNode::getElementValue(int32_t *piValue) const 1166 { 1167 const char *pszValue = getValue(); 1168 if (pszValue) 1169 { 1170 int rc = RTStrToInt32Ex(pszValue, NULL, 0, piValue); 1171 if (rc == VINF_SUCCESS) 1172 return true; 1173 } 1174 return false; 1175 } 1176 1177 bool ElementNode::getElementValue(uint32_t *puValue) const 1178 { 1179 const char *pszValue = getValue(); 1180 if (pszValue) 1181 { 1182 int rc = RTStrToUInt32Ex(pszValue, NULL, 0, puValue); 1183 if (rc == VINF_SUCCESS) 1184 return true; 1185 } 1186 return false; 1187 } 1188 1189 bool ElementNode::getElementValue(int64_t *piValue) const 1190 { 1191 const char *pszValue = getValue(); 1192 if (pszValue) 1193 { 1194 int rc = RTStrToInt64Ex(pszValue, NULL, 0, piValue); 1195 if (rc == VINF_SUCCESS) 1196 return true; 1197 } 1198 return false; 1199 } 1200 1201 bool ElementNode::getElementValue(uint64_t *puValue) const 1202 { 1203 const char *pszValue = getValue(); 1204 if (pszValue) 1205 { 1206 int rc = RTStrToUInt64Ex(pszValue, NULL, 0, puValue); 1207 if (rc == VINF_SUCCESS) 1208 return true; 1209 } 1210 return false; 1211 } 1212 1213 bool ElementNode::getElementValue(bool *pfValue) const 1214 { 1215 const char *pszValue = getValue(); 1216 if (pszValue) 1217 { 1218 if ( !strcmp(pszValue, "true") 1219 || !strcmp(pszValue, "yes") 1220 || !strcmp(pszValue, "1") 1221 ) 1222 { 1223 *pfValue = true; 1224 return true; 1225 } 1226 if ( !strcmp(pszValue, "false") 1227 || !strcmp(pszValue, "no") 1228 || !strcmp(pszValue, "0") 1229 ) 1230 { 1231 *pfValue = true; 1232 return true; 1233 } 1234 } 1235 return false; 1236 } 1237 1238 1188 1239 /** 1189 1240 * Creates a new child element node and appends it to the list … … 1196 1247 { 1197 1248 // we must be an element, not an attribute 1198 if (!m_p libNode)1249 if (!m_pLibNode) 1199 1250 throw ENodeIsNotElement(RT_SRC_POS); 1200 1251 1201 1252 // libxml side: create new node 1202 xmlNode *p libNode;1203 if (!(p libNode = xmlNewNode(NULL, // namespace1253 xmlNode *pLibNode; 1254 if (!(pLibNode = xmlNewNode(NULL, // namespace 1204 1255 (const xmlChar*)pcszElementName))) 1205 1256 throw std::bad_alloc(); 1206 xmlAddChild(m_p libNode, plibNode);1257 xmlAddChild(m_pLibNode, pLibNode); 1207 1258 1208 1259 // now wrap this in C++ 1209 ElementNode *p = new ElementNode(m_pelmRoot, this, plibNode); 1210 #ifndef USE_STD_LIST_FOR_CHILDREN 1211 RTListAppend(&m_children, &p->m_childEntry); 1212 #else 1213 boost::shared_ptr<ElementNode> pNew(p); 1214 m->children.push_back(pNew); 1215 #endif 1260 ElementNode *p = new ElementNode(m_pElmRoot, this, &m_children, pLibNode); 1261 RTListAppend(&m_children, &p->m_listEntry); 1216 1262 1217 1263 return p; … … 1229 1275 { 1230 1276 // libxml side: create new node 1231 xmlNode *p libNode = xmlNewText((const xmlChar*)pcszContent);1232 if (!p libNode)1277 xmlNode *pLibNode = xmlNewText((const xmlChar*)pcszContent); 1278 if (!pLibNode) 1233 1279 throw std::bad_alloc(); 1234 xmlAddChild(m_p libNode, plibNode);1280 xmlAddChild(m_pLibNode, pLibNode); 1235 1281 1236 1282 // now wrap this in C++ 1237 ContentNode *p = new ContentNode(this, plibNode); 1238 #ifndef USE_STD_LIST_FOR_CHILDREN 1239 RTListAppend(&m_children, &p->m_childEntry); 1240 #else 1241 boost::shared_ptr<ContentNode> pNew(p); 1242 m->children.push_back(pNew); 1243 #endif 1283 ContentNode *p = new ContentNode(this, &m_children, pLibNode); 1284 RTListAppend(&m_children, &p->m_listEntry); 1244 1285 1245 1286 return p; … … 1253 1294 * that was either created or changed. 1254 1295 * 1255 * @param pcszName 1256 * @param pcszValue 1257 * @return 1258 */ 1259 AttributeNode* ElementNode::setAttribute(const char *pcszName, const char *pcszValue) 1260 { 1261 AttributeNode *pattrReturn; 1262 Data::AttributesMap::const_iterator it; 1263 1264 it = m->attribs.find(pcszName); 1265 if (it == m->attribs.end()) 1266 { 1267 // libxml side: xmlNewProp creates an attribute 1268 xmlAttr *plibAttr = xmlNewProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue); 1269 1270 // C++ side: create an attribute node around it 1271 const char *pcszKey; 1272 boost::shared_ptr<AttributeNode> pNew(new AttributeNode(*m_pelmRoot, this, plibAttr, &pcszKey)); 1273 // store 1274 m->attribs[pcszKey] = pNew; 1275 pattrReturn = pNew.get(); 1276 } 1277 else 1278 { 1279 // overwrite existing libxml attribute node 1280 xmlAttrPtr plibAttr = xmlSetProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue); 1281 1282 // and fix our existing C++ side around it 1283 boost::shared_ptr<AttributeNode> pattr = it->second; 1284 pattr->m_plibAttr = plibAttr; // in case the xmlAttrPtr is different, I'm not sure 1285 1286 pattrReturn = pattr.get(); 1287 } 1288 1289 return pattrReturn; 1290 1296 * @param pcszName The attribute name. 1297 * @param pcszValue The attribute value. 1298 * @return Pointer to the attribute node that was created or modified. 1299 */ 1300 AttributeNode *ElementNode::setAttribute(const char *pcszName, const char *pcszValue) 1301 { 1302 /* 1303 * Do we already have an attribute and should we just update it? 1304 */ 1305 AttributeNode *pAttr; 1306 RTListForEachCpp(&m_attributes, pAttr, AttributeNode, m_listEntry) 1307 { 1308 if (pAttr->nameEquals(pcszName)) 1309 { 1310 /* Overwrite existing libxml attribute node ... */ 1311 xmlAttrPtr pLibAttr = xmlSetProp(m_pLibNode, (xmlChar *)pcszName, (xmlChar *)pcszValue); 1312 1313 /* ... and update our C++ wrapper in case the attrib pointer changed. */ 1314 pAttr->m_pLibAttr = pLibAttr; 1315 return pAttr; 1316 } 1317 } 1318 1319 /* 1320 * No existing attribute, create a new one. 1321 */ 1322 /* libxml side: xmlNewProp creates an attribute. */ 1323 xmlAttr *pLibAttr = xmlNewProp(m_pLibNode, (xmlChar *)pcszName, (xmlChar *)pcszValue); 1324 1325 /* C++ side: Create an attribute node around it. */ 1326 pAttr = new AttributeNode(m_pElmRoot, this, &m_attributes, pLibAttr); 1327 RTListAppend(&m_attributes, &pAttr->m_listEntry); 1328 1329 return pAttr; 1291 1330 } 1292 1331 … … 1417 1456 1418 1457 /** 1419 * Private constructor for a new attribute node. This one is special: 1420 * in ppcszKey, it returns a pointer to a string buffer that should be 1421 * used to index the attribute correctly with namespaces. 1422 * 1423 * @param pParent 1424 * @param elmRoot 1425 * @param plibAttr 1426 * @param ppcszKey 1427 */ 1428 AttributeNode::AttributeNode(const ElementNode &elmRoot, 1458 * Private constructor for a new attribute node. 1459 * 1460 * @param pElmRoot Pointer to the root element. Needed for getting the 1461 * default name space. 1462 * @param pParent Pointer to the parent element (always an ElementNode, 1463 * despite the type). NULL for the root node. 1464 * @param pListAnchor Pointer to the m_children member of the parent. NULL 1465 * for the root node. 1466 * @param pLibNode Pointer to the libxml2 node structure. 1467 */ 1468 AttributeNode::AttributeNode(const ElementNode *pElmRoot, 1429 1469 Node *pParent, 1430 xmlAttr *plibAttr,1431 const char **ppcszKey)1470 PRTLISTANCHOR pListAnchor, 1471 xmlAttr *pLibAttr) 1432 1472 : Node(IsAttribute, 1433 1473 pParent, 1474 pListAnchor, 1434 1475 NULL, 1435 plibAttr) 1436 { 1437 m_pcszName = (const char*)plibAttr->name; 1438 1439 *ppcszKey = m_pcszName; 1440 1441 if ( plibAttr->ns 1442 && plibAttr->ns->prefix 1443 ) 1444 { 1445 m_pcszNamespacePrefix = (const char*)plibAttr->ns->prefix; 1446 m_pcszNamespaceHref = (const char*)plibAttr->ns->href; 1447 1448 if ( !elmRoot.m_pcszNamespaceHref 1449 || (strcmp(m_pcszNamespaceHref, elmRoot.m_pcszNamespaceHref)) 1450 ) 1476 pLibAttr) 1477 { 1478 m_pcszName = (const char *)pLibAttr->name; 1479 1480 if ( pLibAttr->ns 1481 && pLibAttr->ns->prefix) 1482 { 1483 m_pcszNamespacePrefix = (const char *)pLibAttr->ns->prefix; 1484 m_pcszNamespaceHref = (const char *)pLibAttr->ns->href; 1485 1486 if ( !pElmRoot->m_pcszNamespaceHref 1487 || strcmp(m_pcszNamespaceHref, pElmRoot->m_pcszNamespaceHref)) 1451 1488 { 1452 1489 // not default namespace: … … 1454 1491 m_strKey.append(':'); 1455 1492 m_strKey.append(m_pcszName); 1456 1457 *ppcszKey = m_strKey.c_str();1458 1493 } 1459 1494 } 1460 1495 } 1461 1496 1462 ContentNode::ContentNode(Node *pParent, xmlNode *plibNode)1497 ContentNode::ContentNode(Node *pParent, PRTLISTANCHOR pListAnchor, xmlNode *pLibNode) 1463 1498 : Node(IsContent, 1464 1499 pParent, 1465 plibNode, 1500 pListAnchor, 1501 pLibNode, 1466 1502 NULL) 1467 1503 { … … 1601 1637 void Document::refreshInternals() // private 1602 1638 { 1603 m->pRootElement = new ElementNode(NULL, NULL, xmlDocGetRootElement(m->plibDocument));1604 1605 m->pRootElement->buildChildren(*m->pRootElement);1639 m->pRootElement = new ElementNode(NULL, NULL, NULL, xmlDocGetRootElement(m->plibDocument)); 1640 1641 ElementNode::buildChildren(m->pRootElement); 1606 1642 } 1607 1643 … … 1611 1647 * @return 1612 1648 */ 1613 const ElementNode *Document::getRootElement() const1649 const ElementNode *Document::getRootElement() const 1614 1650 { 1615 1651 return m->pRootElement; … … 1621 1657 * @return 1622 1658 */ 1623 ElementNode *Document::getRootElement()1659 ElementNode *Document::getRootElement() 1624 1660 { 1625 1661 return m->pRootElement; … … 1627 1663 1628 1664 /** 1629 * Creates a new element node and sets it as the root element. This will 1630 * only work if the document is empty; otherwise EDocumentNotEmpty is thrown. 1631 */ 1632 ElementNode* Document::createRootElement(const char *pcszRootElementName, 1665 * Creates a new element node and sets it as the root element. 1666 * 1667 * This will only work if the document is empty; otherwise EDocumentNotEmpty is 1668 * thrown. 1669 */ 1670 ElementNode *Document::createRootElement(const char *pcszRootElementName, 1633 1671 const char *pcszComment /* = NULL */) 1634 1672 { … … 1637 1675 1638 1676 // libxml side: create document, create root node 1639 m->plibDocument = xmlNewDoc((const xmlChar*)"1.0"); 1640 xmlNode *plibRootNode; 1641 if (!(plibRootNode = xmlNewNode(NULL, // namespace 1642 (const xmlChar*)pcszRootElementName))) 1677 m->plibDocument = xmlNewDoc((const xmlChar *)"1.0"); 1678 xmlNode *plibRootNode = xmlNewNode(NULL /*namespace*/ , (const xmlChar *)pcszRootElementName); 1679 if (!plibRootNode) 1643 1680 throw std::bad_alloc(); 1644 1681 xmlDocSetRootElement(m->plibDocument, plibRootNode); 1682 1645 1683 // now wrap this in C++ 1646 m->pRootElement = new ElementNode(NULL, NULL, plibRootNode);1684 m->pRootElement = new ElementNode(NULL, NULL, NULL, plibRootNode); 1647 1685 1648 1686 // add document global comment if specified 1649 1687 if (pcszComment != NULL) 1650 1688 { 1651 xmlNode *pComment; 1652 if (!(pComment = xmlNewDocComment(m->plibDocument, 1653 (const xmlChar *)pcszComment))) 1689 xmlNode *pComment = xmlNewDocComment(m->plibDocument, (const xmlChar *)pcszComment); 1690 if (!pComment) 1654 1691 throw std::bad_alloc(); 1655 1692 xmlAddPrevSibling(plibRootNode, pComment); 1693 1656 1694 // now wrap this in C++ 1657 m->pComment = new ElementNode(NULL, NULL, pComment);1695 m->pComment = new ElementNode(NULL, NULL, NULL, pComment); 1658 1696 } 1659 1697
Note:
See TracChangeset
for help on using the changeset viewer.

