VirtualBox

Changeset 48797 in vbox for trunk


Ignore:
Timestamp:
Oct 1, 2013 2:43:17 PM (11 years ago)
Author:
vboxsync
Message:

A bit more XAR hacking.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/xml.h

    r48781 r48797  
    529529
    530530/**
     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 */
     541class RT_DECL_CLASS AttributeNode : public Node
     542{
     543public:
     544
     545protected:
     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/**
    531560 *  Node subclass that represents an element.
    532561 *
     
    546575                         const char *pcszMatch = NULL) const;
    547576
    548     const ElementNode* findChildElement(const char *pcszNamespace,
     577    const ElementNode *findChildElement(const char *pcszNamespace,
    549578                                        const char *pcszMatch) const;
    550     const ElementNode* findChildElement(const char *pcszMatch) const
     579    const ElementNode *findChildElement(const char *pcszMatch) const
    551580    {
    552581        return findChildElement(NULL, pcszMatch);
    553582    }
    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
    563669    bool getAttributeValue(const char *pcszMatch, const char *&pcsz) const;
    564670    bool getAttributeValue(const char *pcszMatch, RTCString &str) const;
     
    583689
    584690
    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)
    589695    {
    590696        return addContent(strContent.c_str());
    591697    }
    592698
    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)
    595701    {
    596702        return setAttribute(pcszName, strValue.c_str());
    597703    }
    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);
    605711
    606712protected:
     
    637743};
    638744
    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 nodes
    646  * only through the following factory methods:
    647  *
    648  *  --  ElementNode::setAttribute()
    649  */
    650 class RT_DECL_CLASS AttributeNode : public Node
    651 {
    652 public:
    653 
    654 protected:
    655     // hide the default constructor so people use only our factory methods
    656     AttributeNode(const ElementNode &elmRoot,
    657                   Node *pParent,
    658                   xmlAttr *plibAttr,
    659                   const char **ppcszKey);
    660     AttributeNode(const AttributeNode &x);      // no copying
    661 
    662     RTCString    m_strKey;
    663 
    664     friend class Node;
    665     friend class ElementNode;
    666 };
    667745
    668746/**
  • trunk/include/iprt/err.h

    r48780 r48797  
    18401840/** Bad size element in table of content sub-element. */
    18411841#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)
    18421848/** @} */
    18431849
  • trunk/src/VBox/Runtime/common/zip/xarvfs.cpp

    r48780 r48797  
    7373    /** The TOC XML document. */
    7474    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;
    7782} RTZIPXARREADER;
    7883/** Pointer to the XAR reader instance data. */
     
    8489typedef struct RTZIPXARBASEOBJ
    8590{
    86     /** The stream offset of the (first) header.  */
    87     RTFOFF                  offHdr;
    8891    /** Pointer to the reader instance data (resides in the filesystem
    8992     * stream).
    9093     * @todo Fix this so it won't go stale... Back ref from this obj to fss? */
    9194    PRTZIPXARREADER         pXarReader;
    92     /** The object info with unix attributes. */
    93     RTFSOBJINFO             ObjInfo;
     95    /** The file TOC element. */
     96    xml::ElementNode const *pFileElem;
    9497} RTZIPXARBASEOBJ;
    9598/** Pointer to a XAR filesystem stream base object. */
     
    98101
    99102/**
     103 * XAR data encoding.
     104 */
     105typedef 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 */
     118typedef 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. */
     138typedef RTZIPXARDATASTREAM *PRTZIPXARDATASTREAM;
     139
     140
     141/**
    100142 * Xar file represented as a VFS I/O stream.
    101143 */
     
    104146    /** The basic XAR object data. */
    105147    RTZIPXARBASEOBJ         BaseObj;
    106     /** The number of bytes in the file. */
    107     RTFOFF                  cbFile;
     148    /** The attributes of the primary data stream. */
     149    RTZIPXARDATASTREAM      Data;
    108150    /** The current file position. */
    109151    RTFOFF                  offFile;
    110     /** The number of padding bytes following the file. */
    111     uint32_t                cbPadding;
     152    /** The input I/O stream. */
     153    RTVFSIOSTREAM           hVfsIos;
    112154    /** Set if we've reached the end of the file. */
    113155    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;
    116164} RTZIPXARIOSTREAM;
    117165/** Pointer to a the private data of a XAR file I/O stream. */
    118166typedef RTZIPXARIOSTREAM *PRTZIPXARIOSTREAM;
     167
     168
     169/**
     170 * Xar file represented as a VFS file.
     171 */
     172typedef 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. */
     180typedef RTZIPXARFILE *PRTZIPXARFILE;
    119181
    120182
     
    184246static int rtZipXarGetOffsetSizeFromElem(xml::ElementNode const *pElement, PRTFOFF poff, uint64_t *pcb)
    185247{
     248    if (pElement)
     249        return VERR_XAR_DATA_NODE_NOT_FOUND;
     250
    186251    /*
    187252     * The offset.
     
    415480
    416481    /* Currently there is nothing we really have to do here. */
    417     pThis->offHdr = -1;
     482    NOREF(pThis);
    418483
    419484    return VINF_SUCCESS;
     
    530595        return pcbRead ? VINF_EOF : VERR_EOF;
    531596
    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);
    534599    if (cbToRead > cbLeft)
    535600    {
     
    547612    int rc = RTVfsIoStrmRead(pThis->hVfsIos, pvBuf, cbToRead, fBlocking, pcbRead);
    548613    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);
    552617        pThis->fEndOfStream = true;
    553         RTVfsIoStrmSkip(pThis->hVfsIos, pThis->cbPadding);
     618        /// @todo RTVfsIoStrmSkip(pThis->hVfsIos, pThis->cbPadding);
    554619    }
    555620
     
    785850    pThis->hVfsIos = NIL_RTVFSIOSTREAM;
    786851
     852    RTVfsFileRelease(pThis->hVfsFile);
     853    pThis->hVfsFile = NIL_RTVFSFILE;
     854
    787855    return VINF_SUCCESS;
    788856}
     
    801869
    802870
     871static 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
    803909/**
    804910 * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext}
     
    816922        {
    817923            pThis->pCurIosData->fEndOfStream = true;
    818             pThis->pCurIosData->offFile      = pThis->pCurIosData->cbFile;
     924/// @todo            pThis->pCurIosData->offFile      = pThis->pCurIosData->cbFile;
    819925            pThis->pCurIosData = NULL;
    820926        }
     
    832938        return pThis->rcFatal;
    833939
     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
    8341035#if 0
    835     /*
    836      * Make sure the input stream is in the right place.
    837      */
    838     RTFOFF offHdr = RTVfsIoStrmTell(pThis->hVfsIos);
    839     while (   offHdr >= 0
    840            && 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 
    8571036    /*
    8581037     * Consume XAR headers.
     
    9131092        case RTFS_TYPE_FILE:
    9141093        {
    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);
    9431094            break;
    9441095        }
     
    10051156    }
    10061157    pThis->hVfsCurObj = hVfsObj;
     1158#endif
    10071159
    10081160    /*
     
    10111163    if (ppszName)
    10121164    {
    1013         rc = RTStrDupEx(ppszName, pThis->XarReader.szName);
     1165        rc = RTStrDupEx(ppszName, pszName); /** @todo fixme */
    10141166        if (RT_FAILURE(rc))
    10151167            return rc;
     
    10241176    if (penmType)
    10251177        *penmType = enmType;
    1026 #endif
    10271178
    10281179    return VINF_SUCCESS;
     
    13541505                        pThis->XarReader.pDoc       = pDoc;
    13551506                        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;
    13571510
    13581511                        /*
  • trunk/src/VBox/Runtime/r3/xml.cpp

    r48785 r48797  
    864864}
    865865
    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
     867const ElementNode *ElementNode::findChildElementP(const char *pcszPath, const char *pcszNamespace /*= NULL*/) const
    875868{
    876869    size_t cchThis = strchr(pcszPath, '/') - pcszPath;
     
    889882            if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis))
    890883            {
    891                 pElm = findChildElementDeep(pcszNamespace, pcszPath + cchThis);
     884                pElm = findChildElementP(pcszPath + cchThis, pcszNamespace);
    892885                if (pElm)
    893886                    return pElm;
     
    904897            if (pElm->nameEqualsN(pcszNamespace, pcszPath, cchThis))
    905898            {
    906                 pElm = findChildElementDeep(pcszNamespace, pcszPath + cchThis);
     899                pElm = findChildElementP(pcszPath + cchThis, pcszNamespace);
    907900                if (pElm)
    908901                    return pElm;
     
    914907    return NULL;
    915908}
     909
     910const 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
     925const 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
     940const 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
     959const 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
    916978
    917979/**
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette