VirtualBox

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

A bit more XAR hacking.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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                        /*
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