- Timestamp:
- Oct 1, 2013 2:43:17 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cpp/xml.h
r48781 r48797 529 529 530 530 /** 531 * Node subclass that represents an attribute of an element. 532 * 533 * For attributes, Node::getName() returns the attribute name, and Node::getValue() 534 * returns the attribute value, if any. 535 * 536 * Since the Node constructor is private, one can create new attribute nodes 537 * only through the following factory methods: 538 * 539 * -- ElementNode::setAttribute() 540 */ 541 class RT_DECL_CLASS AttributeNode : public Node 542 { 543 public: 544 545 protected: 546 // hide the default constructor so people use only our factory methods 547 AttributeNode(const ElementNode &elmRoot, 548 Node *pParent, 549 xmlAttr *plibAttr, 550 const char **ppcszKey); 551 AttributeNode(const AttributeNode &x); // no copying 552 553 RTCString m_strKey; 554 555 friend class Node; 556 friend class ElementNode; 557 }; 558 559 /** 531 560 * Node subclass that represents an element. 532 561 * … … 546 575 const char *pcszMatch = NULL) const; 547 576 548 const ElementNode *findChildElement(const char *pcszNamespace,577 const ElementNode *findChildElement(const char *pcszNamespace, 549 578 const char *pcszMatch) const; 550 const ElementNode *findChildElement(const char *pcszMatch) const579 const ElementNode *findChildElement(const char *pcszMatch) const 551 580 { 552 581 return findChildElement(NULL, pcszMatch); 553 582 } 554 const ElementNode* findChildElementFromId(const char *pcszId) const; 555 556 const ElementNode *findChildElementDeep(const char *pcszNamespace, const char *pcszPath) const; 557 const ElementNode *findChildElementDeep(const char *pcszPath) const 558 { 559 return findChildElementDeep(NULL, pcszPath); 560 } 561 562 const AttributeNode* findAttribute(const char *pcszMatch) const; 583 const ElementNode *findChildElementFromId(const char *pcszId) const; 584 585 /** Finds the first decendant matching the name at the end of @a pcszPath and 586 * optionally namespace. 587 * 588 * @returns Pointer to the child string value, NULL if not found or no value. 589 * @param pcszPath The attribute name. Slashes can be used to make a 590 * simple path to any decendant. 591 * @param pcszNamespace The namespace to match, NULL (default) match any 592 * namespace. When using a path, this matches all 593 * elements along the way. 594 * @see findChildElement, findChildElementP 595 */ 596 const ElementNode *findChildElementP(const char *pcszPath, const char *pcszNamespace = NULL) const; 597 598 /** Finds the first child with matching the give name and optionally namspace, 599 * returning its value. 600 * 601 * @returns Pointer to the child string value, NULL if not found or no value. 602 * @param pcszPath The attribute name. Slashes can be used to make a 603 * simple path to any decendant. 604 * @param pcszNamespace The namespace to match, NULL (default) match any 605 * namespace. When using a path, this matches all 606 * elements along the way. 607 * @see findChildElement, findChildElementP 608 */ 609 const char *findChildElementValueP(const char *pcszPath, const char *pcszNamespace = NULL) const 610 { 611 const ElementNode *pElem = findChildElementP(pcszPath, pcszNamespace); 612 if (pElem) 613 return pElem->getValue(); 614 return NULL; 615 } 616 617 618 /** @name Element enumeration. 619 * @{ */ 620 /** Get the previous sibling element. 621 * @returns Pointer to the previous sibling element, NULL if first child 622 * element. 623 * @see getNextSibilingElement, getPrevSibling 624 */ 625 const ElementNode *getPrevSibilingElement() const; 626 627 /** Get the next sibling element. 628 * @returns Pointer to the next sibling element, NULL if last child element. 629 * @see getPrevSibilingElement, getNextSibling 630 */ 631 const ElementNode *getNextSibilingElement() const; 632 633 /** Find the previous element matching the given name and namespace (optionally). 634 * @returns Pointer to the previous sibling element, NULL if first child 635 * element. 636 * @param pcszName The element name to match. 637 * @param pcszNamespace The namespace name, default is NULL which means 638 * anything goes. 639 * @note Changed the order of the arguments. 640 */ 641 const ElementNode *findPrevSibilingElement(const char *pcszName, const char *pcszNamespace = NULL) const; 642 643 /** Find the next element matching the given name and namespace (optionally). 644 * @returns Pointer to the previous sibling element, NULL if first child 645 * element. 646 * @param pcszName The element name to match. 647 * @param pcszNamespace The namespace name, default is NULL which means 648 * anything goes. 649 * @note Changed the order of the arguments. 650 */ 651 const ElementNode *findNextSibilingElement(const char *pcszName, const char *pcszNamespace = NULL) const; 652 /** @} */ 653 654 655 const AttributeNode *findAttribute(const char *pcszMatch) const; 656 /** Find the first attribute with the given name, returning its value string. 657 * @returns Pointer to the attribute string value. 658 * @param pcszName The attribute name. 659 * @see getAttributeValue 660 */ 661 const char *findAttributeValue(const char *pcszName) const 662 { 663 const AttributeNode *pAttr = findAttribute(pcszName); 664 if (pAttr) 665 return pAttr->getValue(); 666 return NULL; 667 } 668 563 669 bool getAttributeValue(const char *pcszMatch, const char *&pcsz) const; 564 670 bool getAttributeValue(const char *pcszMatch, RTCString &str) const; … … 583 689 584 690 585 ElementNode *createChild(const char *pcszElementName);586 587 ContentNode *addContent(const char *pcszContent);588 ContentNode *addContent(const RTCString &strContent)691 ElementNode *createChild(const char *pcszElementName); 692 693 ContentNode *addContent(const char *pcszContent); 694 ContentNode *addContent(const RTCString &strContent) 589 695 { 590 696 return addContent(strContent.c_str()); 591 697 } 592 698 593 AttributeNode *setAttribute(const char *pcszName, const char *pcszValue);594 AttributeNode *setAttribute(const char *pcszName, const RTCString &strValue)699 AttributeNode *setAttribute(const char *pcszName, const char *pcszValue); 700 AttributeNode *setAttribute(const char *pcszName, const RTCString &strValue) 595 701 { 596 702 return setAttribute(pcszName, strValue.c_str()); 597 703 } 598 AttributeNode *setAttributePath(const char *pcszName, const RTCString &strValue);599 AttributeNode *setAttribute(const char *pcszName, int32_t i);600 AttributeNode *setAttribute(const char *pcszName, uint32_t i);601 AttributeNode *setAttribute(const char *pcszName, int64_t i);602 AttributeNode *setAttribute(const char *pcszName, uint64_t i);603 AttributeNode *setAttributeHex(const char *pcszName, uint32_t i);604 AttributeNode *setAttribute(const char *pcszName, bool f);704 AttributeNode *setAttributePath(const char *pcszName, const RTCString &strValue); 705 AttributeNode *setAttribute(const char *pcszName, int32_t i); 706 AttributeNode *setAttribute(const char *pcszName, uint32_t i); 707 AttributeNode *setAttribute(const char *pcszName, int64_t i); 708 AttributeNode *setAttribute(const char *pcszName, uint64_t i); 709 AttributeNode *setAttributeHex(const char *pcszName, uint32_t i); 710 AttributeNode *setAttribute(const char *pcszName, bool f); 605 711 606 712 protected: … … 637 743 }; 638 744 639 /**640 * Node subclass that represents an attribute of an element.641 *642 * For attributes, Node::getName() returns the attribute name, and Node::getValue()643 * returns the attribute value, if any.644 *645 * Since the Node constructor is private, one can create new attribute nodes646 * only through the following factory methods:647 *648 * -- ElementNode::setAttribute()649 */650 class RT_DECL_CLASS AttributeNode : public Node651 {652 public:653 654 protected:655 // hide the default constructor so people use only our factory methods656 AttributeNode(const ElementNode &elmRoot,657 Node *pParent,658 xmlAttr *plibAttr,659 const char **ppcszKey);660 AttributeNode(const AttributeNode &x); // no copying661 662 RTCString m_strKey;663 664 friend class Node;665 friend class ElementNode;666 };667 745 668 746 /** -
trunk/include/iprt/err.h
r48780 r48797 1840 1840 /** Bad size element in table of content sub-element. */ 1841 1841 #define VERR_XAR_BAD_SIZE_ELEMENT (-22721) 1842 /** Bad file element in XAR table of content. */ 1843 #define VERR_XAR_BAD_FILE_ELEMENT (-22722) 1844 /** An data element is expected for XAR file of type file. */ 1845 #define VERR_XAR_DATA_NODE_NOT_FOUND (-22723) 1846 /** Unknown XAR file type value. */ 1847 #define VERR_XAR_BAD_UNKNOWN_FILE_TYPE (-22724) 1842 1848 /** @} */ 1843 1849 -
trunk/src/VBox/Runtime/common/zip/xarvfs.cpp
r48780 r48797 73 73 /** The TOC XML document. */ 74 74 xml::Document *pDoc; 75 /** The current file ID. */ 76 uint32_t idCurFile; 75 76 /** The current file. */ 77 xml::ElementNode const *pCurFile; 78 /** The depth of the current file, with 0 being the root level. */ 79 uint32_t cCurDepth; 80 /** Set if it's the first file. */ 81 bool fFirstFile; 77 82 } RTZIPXARREADER; 78 83 /** Pointer to the XAR reader instance data. */ … … 84 89 typedef struct RTZIPXARBASEOBJ 85 90 { 86 /** The stream offset of the (first) header. */87 RTFOFF offHdr;88 91 /** Pointer to the reader instance data (resides in the filesystem 89 92 * stream). 90 93 * @todo Fix this so it won't go stale... Back ref from this obj to fss? */ 91 94 PRTZIPXARREADER pXarReader; 92 /** The object info with unix attributes. */93 RTFSOBJINFO ObjInfo;95 /** The file TOC element. */ 96 xml::ElementNode const *pFileElem; 94 97 } RTZIPXARBASEOBJ; 95 98 /** Pointer to a XAR filesystem stream base object. */ … … 98 101 99 102 /** 103 * XAR data encoding. 104 */ 105 typedef enum RTZIPXARENCODING 106 { 107 RTZIPXARENCODING_INVALID = 0, 108 RTZIPXARENCODING_STORE, 109 RTZIPXARENCODING_GZIP, 110 RTZIPXARENCODING_UNSUPPORTED, 111 RTZIPXARENCODING_END 112 } RTZIPXARENCODING; 113 114 115 /** 116 * Data stream attributes. 117 */ 118 typedef struct RTZIPXARDATASTREAM 119 { 120 /** Offset of the data in the stream, relative to XARREADER::offZero. */ 121 RTFOFF offData; 122 /** The size of the archived data. */ 123 RTFOFF cbDataArchived; 124 /** The size of the extracted data. */ 125 RTFOFF cbDataExtracted; 126 /** The encoding of the archived ata. */ 127 RTZIPXARENCODING enmEncoding; 128 /** The hash function used for the archived data. */ 129 uint8_t uHashFunArchived; 130 /** The hash function used for the extracted data. */ 131 uint8_t uHashFunExtracted; 132 /** The digest of the archived data. */ 133 RTZIPXARHASHDIGEST DigestArchived; 134 /** The digest of the extracted data. */ 135 RTZIPXARHASHDIGEST DigestExtracted; 136 } RTZIPXARDATASTREAM; 137 /** Pointer to XAR data stream attributes. */ 138 typedef RTZIPXARDATASTREAM *PRTZIPXARDATASTREAM; 139 140 141 /** 100 142 * Xar file represented as a VFS I/O stream. 101 143 */ … … 104 146 /** The basic XAR object data. */ 105 147 RTZIPXARBASEOBJ BaseObj; 106 /** The number of bytes in the file. */107 RT FOFF cbFile;148 /** The attributes of the primary data stream. */ 149 RTZIPXARDATASTREAM Data; 108 150 /** The current file position. */ 109 151 RTFOFF offFile; 110 /** The number of padding bytes following the file. */111 uint32_t cbPadding;152 /** The input I/O stream. */ 153 RTVFSIOSTREAM hVfsIos; 112 154 /** Set if we've reached the end of the file. */ 113 155 bool fEndOfStream; 114 /** The input I/O stream. */ 115 RTVFSIOSTREAM hVfsIos; 156 /** The size of the file that we've currently hashed. 157 * We use this to check whether the user skips part of the file while reading 158 * and when to compare the digests. */ 159 RTFOFF cbDigested; 160 /** The digest of the archived data. */ 161 RTZIPXARHASHDIGEST DigestArchived; 162 /** The digest of the extracted data. */ 163 RTZIPXARHASHDIGEST DigestExtracted; 116 164 } RTZIPXARIOSTREAM; 117 165 /** Pointer to a the private data of a XAR file I/O stream. */ 118 166 typedef RTZIPXARIOSTREAM *PRTZIPXARIOSTREAM; 167 168 169 /** 170 * Xar file represented as a VFS file. 171 */ 172 typedef struct RTZIPXARFILE 173 { 174 /** The XAR I/O stream object. */ 175 RTZIPXARIOSTREAM IosObj; 176 /** The input file. */ 177 RTVFSFILE hVfsFile; 178 } RTZIPXARFILE; 179 /** Pointer to a the private data of a XAR file. */ 180 typedef RTZIPXARFILE *PRTZIPXARFILE; 119 181 120 182 … … 184 246 static int rtZipXarGetOffsetSizeFromElem(xml::ElementNode const *pElement, PRTFOFF poff, uint64_t *pcb) 185 247 { 248 if (pElement) 249 return VERR_XAR_DATA_NODE_NOT_FOUND; 250 186 251 /* 187 252 * The offset. … … 415 480 416 481 /* Currently there is nothing we really have to do here. */ 417 pThis->offHdr = -1;482 NOREF(pThis); 418 483 419 484 return VINF_SUCCESS; … … 530 595 return pcbRead ? VINF_EOF : VERR_EOF; 531 596 532 Assert(pThis-> cbFile>= pThis->offFile);533 uint64_t cbLeft = (uint64_t)(pThis-> cbFile- pThis->offFile);597 Assert(pThis->Data.cbDataExtracted >= pThis->offFile); 598 uint64_t cbLeft = (uint64_t)(pThis->Data.cbDataExtracted - pThis->offFile); 534 599 if (cbToRead > cbLeft) 535 600 { … … 547 612 int rc = RTVfsIoStrmRead(pThis->hVfsIos, pvBuf, cbToRead, fBlocking, pcbRead); 548 613 pThis->offFile += *pcbRead; 549 if (pThis->offFile >= pThis-> cbFile)550 { 551 Assert(pThis->offFile == pThis-> cbFile);614 if (pThis->offFile >= pThis->Data.cbDataExtracted) 615 { 616 Assert(pThis->offFile == pThis->Data.cbDataExtracted); 552 617 pThis->fEndOfStream = true; 553 RTVfsIoStrmSkip(pThis->hVfsIos, pThis->cbPadding);618 /// @todo RTVfsIoStrmSkip(pThis->hVfsIos, pThis->cbPadding); 554 619 } 555 620 … … 785 850 pThis->hVfsIos = NIL_RTVFSIOSTREAM; 786 851 852 RTVfsFileRelease(pThis->hVfsFile); 853 pThis->hVfsFile = NIL_RTVFSFILE; 854 787 855 return VINF_SUCCESS; 788 856 } … … 801 869 802 870 871 static xml::ElementNode const *rtZipXarGetNextFileElement(xml::ElementNode const *pCurFile, uint32_t *pcCurDepth) 872 { 873 /* 874 * Consider children first. 875 */ 876 xml::ElementNode const *pChild = pCurFile->findChildElement("file"); 877 if (pChild) 878 { 879 *pcCurDepth += 1; 880 return pChild; 881 } 882 883 /* 884 * Then siblings. 885 */ 886 xml::ElementNode const *pSibling = pCurFile->findNextSibilingElement("file"); 887 if (pSibling != NULL) 888 return pSibling; 889 890 /* 891 * Ascend and see if some parent has more siblings. 892 */ 893 while (*pcCurDepth > 0) 894 { 895 pCurFile = static_cast<const xml::ElementNode *>(pCurFile->getParent()); 896 AssertBreak(pCurFile); 897 Assert(pCurFile->nameEquals("file")); 898 *pcCurDepth -= 1; 899 900 pSibling = pCurFile->findNextSibilingElement("file"); 901 if (pSibling != NULL) 902 return pSibling; 903 } 904 905 return NULL; 906 } 907 908 803 909 /** 804 910 * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext} … … 816 922 { 817 923 pThis->pCurIosData->fEndOfStream = true; 818 pThis->pCurIosData->offFile = pThis->pCurIosData->cbFile;924 /// @todo pThis->pCurIosData->offFile = pThis->pCurIosData->cbFile; 819 925 pThis->pCurIosData = NULL; 820 926 } … … 832 938 return pThis->rcFatal; 833 939 940 /* 941 * Get the next file element. 942 */ 943 if (pThis->XarReader.fFirstFile) 944 { 945 pThis->XarReader.pCurFile = pThis->XarReader.pToc->findChildElement("file"); 946 pThis->XarReader.cCurDepth = 0; 947 } 948 else if (pThis->XarReader.pCurFile) 949 pThis->XarReader.pCurFile = rtZipXarGetNextFileElement(pThis->XarReader.pCurFile, &pThis->XarReader.cCurDepth); 950 if (!pThis->XarReader.pCurFile) 951 { 952 pThis->fEndOfStream = true; 953 return VERR_EOF; 954 } 955 956 /* 957 * Retrive the fundamental attributes (elements actually). 958 */ 959 const char *pszName = pThis->XarReader.pCurFile->findChildElementValueP("name"); 960 const char *pszType = pThis->XarReader.pCurFile->findChildElementValueP("type"); 961 if (RT_UNLIKELY(!pszName || !pszType)) 962 return pThis->rcFatal = VERR_XAR_BAD_FILE_ELEMENT; 963 964 /* 965 * Gather any additional attributes that are essential to the file type, 966 * then create the VFS object we're going to return. 967 */ 968 int rc; 969 RTVFSOBJ hVfsObj; 970 RTVFSOBJTYPE enmType; 971 if (!strcmp(pszType, "file")) 972 { 973 #if 0 /// @todo continue hacking here 974 rc = rtZipXarGetDataStreamAttributes(pThis->XarReader.pCurFile, &offData, &cbData); 975 if (RT_FAILURE(rc)) 976 return pThis->rcFatal = rc; 977 978 979 if (pThis->hVfsFile != NIL_RTVFSFILE) 980 { 981 982 } 983 else 984 { 985 RTVFSIOSTREAM hVfsIos; 986 PRTZIPXARIOSTREAM pIosData; 987 rc = RTVfsNewIoStream(&g_rtZipXarFssIosOps, 988 sizeof(*pIosData), 989 RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 990 NIL_RTVFS, 991 NIL_RTVFSLOCK, 992 &hVfsIos, 993 (void **)&pIosData); 994 if (RT_FAILURE(rc)) 995 return pThis->rcFatal = rc; 996 997 pIosData->BaseObj.pXarReader = &pThis->XarReader; 998 pIosData->BaseObj.pFileElem = pThis->XarReader.pCurFile; 999 pIosData->cbFile = cbData; 1000 pIosData->offFile = 0; 1001 pIosData->cbPadding = (uint32_t)(Info.cbAllocated - Info.cbObject); 1002 pIosData->fEndOfStream = false; 1003 pIosData->hVfsIos = pThis->hVfsIos; 1004 RTVfsIoStrmRetain(pThis->hVfsIos); 1005 1006 pThis->pCurIosData = pIosData; 1007 pThis->offNextHdr += pIosData->cbFile + pIosData->cbPadding; 1008 1009 enmType = RTVFSOBJTYPE_IO_STREAM; 1010 hVfsObj = RTVfsObjFromIoStream(hVfsIos); 1011 RTVfsIoStrmRelease(hVfsIos); 1012 } 1013 #endif 1014 } 1015 else if (!strcmp(pszType, "directory")) 1016 { 1017 PRTZIPXARBASEOBJ pBaseObjData; 1018 rc = RTVfsNewBaseObj(&g_rtZipXarFssBaseObjOps, 1019 sizeof(*pBaseObjData), 1020 NIL_RTVFS, 1021 NIL_RTVFSLOCK, 1022 &hVfsObj, 1023 (void **)&pBaseObjData); 1024 if (RT_FAILURE(rc)) 1025 return pThis->rcFatal = rc; 1026 1027 pBaseObjData->pXarReader = &pThis->XarReader; 1028 pBaseObjData->pFileElem = pThis->XarReader.pCurFile; 1029 1030 enmType = RTVFSOBJTYPE_BASE; 1031 } 1032 else 1033 return pThis->rcFatal = VERR_XAR_BAD_UNKNOWN_FILE_TYPE; 1034 834 1035 #if 0 835 /*836 * Make sure the input stream is in the right place.837 */838 RTFOFF offHdr = RTVfsIoStrmTell(pThis->hVfsIos);839 while ( offHdr >= 0840 && offHdr < pThis->offNextHdr)841 {842 int rc = RTVfsIoStrmSkip(pThis->hVfsIos, pThis->offNextHdr - offHdr);843 if (RT_FAILURE(rc))844 {845 /** @todo Ignore if we're at the end of the stream? */846 return pThis->rcFatal = rc;847 }848 849 offHdr = RTVfsIoStrmTell(pThis->hVfsIos);850 }851 852 if (offHdr < 0)853 return pThis->rcFatal = (int)offHdr;854 if (offHdr > pThis->offNextHdr)855 return pThis->rcFatal = VERR_INTERNAL_ERROR_3;856 857 1036 /* 858 1037 * Consume XAR headers. … … 913 1092 case RTFS_TYPE_FILE: 914 1093 { 915 RTVFSIOSTREAM hVfsIos;916 PRTZIPXARIOSTREAM pIosData;917 rc = RTVfsNewIoStream(&g_rtZipXarFssIosOps,918 sizeof(*pIosData),919 RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,920 NIL_RTVFS,921 NIL_RTVFSLOCK,922 &hVfsIos,923 (void **)&pIosData);924 if (RT_FAILURE(rc))925 return pThis->rcFatal = rc;926 927 pIosData->BaseObj.offHdr = offHdr;928 pIosData->BaseObj.pXarReader= &pThis->XarReader;929 pIosData->BaseObj.ObjInfo = Info;930 pIosData->cbFile = Info.cbObject;931 pIosData->offFile = 0;932 pIosData->cbPadding = (uint32_t)(Info.cbAllocated - Info.cbObject);933 pIosData->fEndOfStream = false;934 pIosData->hVfsIos = pThis->hVfsIos;935 RTVfsIoStrmRetain(pThis->hVfsIos);936 937 pThis->pCurIosData = pIosData;938 pThis->offNextHdr += pIosData->cbFile + pIosData->cbPadding;939 940 enmType = RTVFSOBJTYPE_IO_STREAM;941 hVfsObj = RTVfsObjFromIoStream(hVfsIos);942 RTVfsIoStrmRelease(hVfsIos);943 1094 break; 944 1095 } … … 1005 1156 } 1006 1157 pThis->hVfsCurObj = hVfsObj; 1158 #endif 1007 1159 1008 1160 /* … … 1011 1163 if (ppszName) 1012 1164 { 1013 rc = RTStrDupEx(ppszName, p This->XarReader.szName);1165 rc = RTStrDupEx(ppszName, pszName); /** @todo fixme */ 1014 1166 if (RT_FAILURE(rc)) 1015 1167 return rc; … … 1024 1176 if (penmType) 1025 1177 *penmType = enmType; 1026 #endif1027 1178 1028 1179 return VINF_SUCCESS; … … 1354 1505 pThis->XarReader.pDoc = pDoc; 1355 1506 pThis->XarReader.pToc = pTocElem; 1356 pThis->XarReader.idCurFile = 0; /* Assuming the ID numbering is from 1. */ 1507 pThis->XarReader.pCurFile = 0; 1508 pThis->XarReader.cCurDepth = 0; 1509 pThis->XarReader.fFirstFile = true; 1357 1510 1358 1511 /* -
trunk/src/VBox/Runtime/r3/xml.cpp
r48785 r48797 864 864 } 865 865 866 /** 867 * Recursively find the first matching child element. 868 * 869 * @returns child element or NULL if not found. 870 * @param pcszNamespace The Namespace prefix or NULL. 871 * @param pcszPath Simple element path, with parent and child elements 872 * separated by a forward slash ('/'). 873 */ 874 const ElementNode *ElementNode::findChildElementDeep(const char *pcszNamespace, const char *pcszPath) const 866 867 const ElementNode *ElementNode::findChildElementP(const char *pcszPath, const char *pcszNamespace /*= NULL*/) const 875 868 { 876 869 size_t cchThis = strchr(pcszPath, '/') - pcszPath; … … 889 882 if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis)) 890 883 { 891 pElm = findChildElement Deep(pcszNamespace, pcszPath + cchThis);884 pElm = findChildElementP(pcszPath + cchThis, pcszNamespace); 892 885 if (pElm) 893 886 return pElm; … … 904 897 if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis)) 905 898 { 906 pElm = findChildElement Deep(pcszNamespace, pcszPath + cchThis);899 pElm = findChildElementP(pcszPath + cchThis, pcszNamespace); 907 900 if (pElm) 908 901 return pElm; … … 914 907 return NULL; 915 908 } 909 910 const ElementNode *ElementNode::getPrevSibilingElement() const 911 { 912 if (!m_pParent) 913 return NULL; 914 const Node *pSibling = this; 915 for (;;) 916 { 917 pSibling = RTListGetPrevCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry); 918 if (!pSibling) 919 return NULL; 920 if (pSibling->isElement()) 921 return static_cast<const ElementNode *>(pSibling); 922 } 923 } 924 925 const ElementNode *ElementNode::getNextSibilingElement() const 926 { 927 if (!m_pParent) 928 return NULL; 929 const Node *pSibling = this; 930 for (;;) 931 { 932 pSibling = RTListGetNextCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry); 933 if (!pSibling) 934 return NULL; 935 if (pSibling->isElement()) 936 return static_cast<const ElementNode *>(pSibling); 937 } 938 } 939 940 const ElementNode *ElementNode::findPrevSibilingElement(const char *pcszMatch, const char *pcszNamespace /*= NULL*/) const 941 { 942 if (!m_pParent) 943 return NULL; 944 const Node *pSibling = this; 945 for (;;) 946 { 947 pSibling = RTListGetPrevCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry); 948 if (!pSibling) 949 return NULL; 950 if (pSibling->isElement()) 951 { 952 const ElementNode *pElem = static_cast<const ElementNode *>(pSibling); 953 if (pElem->nameEquals(pcszNamespace, pcszMatch)) 954 return pElem; 955 } 956 } 957 } 958 959 const ElementNode *ElementNode::findNextSibilingElement(const char *pcszMatch, const char *pcszNamespace /*= NULL*/) const 960 { 961 if (!m_pParent) 962 return NULL; 963 const Node *pSibling = this; 964 for (;;) 965 { 966 pSibling = RTListGetNextCpp(&m_pParent->m_children, pSibling, const Node, m_childEntry); 967 if (!pSibling) 968 return NULL; 969 if (pSibling->isElement()) 970 { 971 const ElementNode *pElem = static_cast<const ElementNode *>(pSibling); 972 if (pElem->nameEquals(pcszNamespace, pcszMatch)) 973 return pElem; 974 } 975 } 976 } 977 916 978 917 979 /**
Note:
See TracChangeset
for help on using the changeset viewer.