VirtualBox

Changeset 33903 in vbox


Ignore:
Timestamp:
Nov 9, 2010 2:44:55 PM (14 years ago)
Author:
vboxsync
Message:

iprt: More VFS and gunzip code.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r33887 r33903  
    12941294/** The compression method is unsupported. */
    12951295#define VERR_ZIP_UNSUPPORTED_METHOD             (-954)
     1296/** The compressed data started with a bad header. */
     1297#define VERR_ZIP_BAD_HEADER                     (-955)
    12961298/** @} */
    12971299
  • trunk/include/iprt/vfs.h

    r33859 r33903  
    211211 * @param   pvBuf           Where to store the read bytes.
    212212 * @param   cbToRead        The number of bytes to read.
    213  * @param   pcbRead         Where to store the number of bytes actually read.
    214  *                          If this is NULL, the call will block until @a
    215  *                          cbToRead bytes are available.  If this is non-NULL,
    216  *                          the call will not block and return what is currently
    217  *                          avaiable.
     213 * @param   pcbRead         Where to always store the number of bytes actually
     214 *                          read.  If this is NULL, the call will block until
     215 *                          @a cbToRead bytes are available.  If this is
     216 *                          non-NULL, the call will not block and return what
     217 *                          is currently avaiable.
    218218 * @sa      RTFileRead, RTPipeRead, RTPipeReadBlocking, RTSocketRead
    219219 */
     
    227227 * @param   pvBuf           The bytes to write.
    228228 * @param   cbToWrite       The number of bytes to write.
    229  * @param   pcbWritten      Where to store the number of bytes actually written.
    230  *                          If this is NULL, the call will block until @a
    231  *                          cbToWrite bytes are available.  If this is non-NULL,
    232  *                          the call will not block and return after writing
    233  *                          what is possible.
     229 * @param   pcbWritten      Where to always store the number of bytes actually
     230 *                          written.  If this is NULL, the call will block
     231 *                          until
     232 *                          @a cbToWrite bytes are available.  If this is
     233 *                          non-NULL, the call will not block and return after
     234 *                          writing what is possible.
    234235 * @sa      RTFileWrite, RTPipeWrite, RTPipeWriteBlocking, RTSocketWrite
    235236 */
     
    240241 *
    241242 * @returns IPRT status code.
     243 * @retval  VINF_SUCCESS and the number of bytes read written to @a pcbRead.
     244 * @retval  VINF_TRY_AGAIN if @a fBlocking is @c false, @a pcbRead is not NULL,
     245 *          and no data was available. @a *pcbRead will be set to 0.
     246 * @retval  VINF_EOF when trying to read __beyond__ the end of the stream and
     247 *          @a pcbRead is not NULL (it will be set to the number of bytes read,
     248 *          or 0 if the end of the stream was reached before this call).
     249 *          When the last byte of the read request is the last byte in the
     250 *          stream, this status code will not be used.  However, VINF_EOF is
     251 *          returned when attempting to read 0 bytes while standing at the end
     252 *          of the stream.
     253 * @retval  VERR_EOF when trying to read __beyond__ the end of the stream and
     254 *          @a pcbRead is NULL.
     255 *
    242256 * @param   hVfsIos         The VFS I/O stream handle.
    243257 * @param   pSgBuf          Pointer to a scatter buffer descriptor.  The number
     
    246260 * @param   fBlocking       Whether the call is blocking (@c true) or not.  If
    247261 *                          not, the @a pcbRead parameter must not be NULL.
    248  * @param   pcbRead         Where to store the number of bytes actually read.
    249  *                          This can be NULL if @a fBlocking is true.
    250  * @sa      RTFileSgRead, RTSocketSgRead
     262 * @param   pcbRead         Where to always store the number of bytes actually
     263 *                          read.  This can be NULL if @a fBlocking is true.
     264 * @sa      RTFileSgRead, RTSocketSgRead, RTPipeRead, RTPipeReadBlocking
    251265 */
    252266RTDECL(int)         RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
     
    262276 * @param   fBlocking       Whether the call is blocking (@c true) or not.  If
    263277 *                          not, the @a pcbWritten parameter must not be NULL.
    264  * @param   pcbRead         Where to store the number of bytes actually written.
    265  *                          This can be NULL if @a fBlocking is true.
     278 * @param   pcbRead         Where to always store the number of bytes actually
     279 *                          written.  This can be NULL if @a fBlocking is true.
    266280 * @sa      RTFileSgWrite, RTSocketSgWrite
    267281 */
  • trunk/include/iprt/vfslowlevel.h

    r33887 r33903  
    429429     * Reads from the file/stream.
    430430     *
    431      * @returns IPRT status code.
     431     * @returns IPRT status code. See RTVfsIoStrmRead.
    432432     * @param   pvThis      The implementation specific file data.
    433433     * @param   off         Where to read at, -1 for the current position.
     
    436436     * @param   fBlocking   If @c true, the call is blocking, if @c false it
    437437     *                      should not block.
    438      * @param   pcbRead     Where return the number of bytes actually read.  If
    439      *                      NULL, try read all and fail if incomplete.
    440      * @sa      RTFileRead, RTFileReadAt.
     438     * @param   pcbRead     Where return the number of bytes actually read.
     439     *                      This is set it 0 by the caller.  If NULL, try read
     440     *                      all and fail if incomplete.
     441     * @sa      RTVfsIoStrmRead, RTVfsIoStrmSgRead, RTVfsFileRead,
     442     *          RTVfsFileReadAt, RTFileRead, RTFileReadAt.
    441443     */
    442444    DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
     
    453455     * @param   fBlocking   If @c true, the call is blocking, if @c false it
    454456     *                      should not block.
    455      * @param   pcbWrit  Where to return the number of bytes actually
    456      *                      written.  If  NULL, try write it all and fail if
    457      *                      incomplete.
     457     * @param   pcbWritten  Where to return the number of bytes actually
     458     *                      written.  This is set it 0 by the caller.  If
     459     *                      NULL, try write it all and fail if incomplete.
    458460     * @sa      RTFileWrite, RTFileWriteAt.
    459461     */
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r33867 r33903  
    914914RTDECL(int)         RTVfsIoStrmRead(RTVFSIOSTREAM hVfsIos, void *pvBuf, size_t cbToRead, size_t *pcbRead)
    915915{
     916    AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);
     917    if (pcbRead)
     918        *pcbRead = 0;
    916919    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
    917920    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     
    931934RTDECL(int)         RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
    932935{
     936    AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER);
     937    if (pcbWritten)
     938        *pcbWritten = 0;
    933939    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
    934940    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     
    948954RTDECL(int)         RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
    949955{
     956    AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);
     957    if (pcbRead)
     958        *pcbRead = 0;
    950959    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
    951960    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    952961    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    953962    AssertPtr(pSgBuf);
    954     AssertReturn(fBlocking || VALID_PTR(pcbRead), VERR_INVALID_PARAMETER);
     963    AssertReturn(fBlocking || pcbRead, VERR_INVALID_PARAMETER);
    955964
    956965    RTVFS_WRITE_LOCK(pThis->hSemRW);
     
    963972RTDECL(int)         RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
    964973{
     974    AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER);
     975    if (pcbWritten)
     976        *pcbWritten = 0;
    965977    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
    966978    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    967979    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
    968980    AssertPtr(pSgBuf);
    969     AssertReturn(fBlocking || VALID_PTR(pcbWritten), VERR_INVALID_PARAMETER);
     981    AssertReturn(fBlocking || pcbWritten, VERR_INVALID_PARAMETER);
    970982
    971983    RTVFS_WRITE_LOCK(pThis->hSemRW);
  • trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp

    r33860 r33903  
    8484
    8585/**
     86 * RTFileRead and RTFileReadAt does not return VINF_EOF or VINF_TRY_AGAIN, this
     87 * function tries to fix this as best as it can.
     88 *
     89 * This fixing can be subject to races if some other thread or process is
     90 * modifying the file size between the read and our size query here.
     91 *
     92 * @returns VINF_SUCCESS, VINF_EOF or VINF_TRY_AGAIN.
     93 * @param   pThis               The instance data.
     94 * @param   off                 The offset parameter.
     95 * @param   cbToRead            The number of bytes attempted read .
     96 * @param   cbActuallyRead      The number of bytes actually read.
     97 */
     98DECLINLINE(int) rtVfsStdFile_ReadFixRC(PRTVFSSTDFILE pThis, RTFOFF off, size_t cbToRead, size_t cbActuallyRead)
     99{
     100    /* If the read returned less bytes than requested, it means the end of the
     101       file has been reached. */
     102    if (cbToRead > cbActuallyRead)
     103        return VINF_EOF;
     104
     105    /* The other case here is the very special zero byte read at the end of the
     106       file, where we're supposed to indicate EOF. */
     107    if (cbToRead > 0)
     108        return VINF_SUCCESS;
     109
     110    uint64_t cbFile;
     111    int rc = RTFileGetSize(pThis->hFile, &cbFile);
     112    if (RT_FAILURE(rc))
     113        return rc;
     114
     115    uint64_t off2;
     116    if (off >= 0)
     117        off2 = off;
     118    else
     119    {
     120        rc = RTFileSeek(pThis->hFile, 0, RTFILE_SEEK_CURRENT, &off2);
     121        if (RT_FAILURE(rc))
     122            return rc;
     123    }
     124
     125    return off2 >= cbFile ? VINF_EOF : VINF_SUCCESS;
     126}
     127
     128
     129/**
    86130 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
    87131 */
     
    95139    {
    96140        if (off < 0)
    97             rc = RTFileRead(pThis->hFile, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
     141            rc = RTFileRead(  pThis->hFile,      pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
    98142        else
    99143            rc = RTFileReadAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
     144        if (rc == VINF_SUCCESS && pcbRead)
     145            rc = rtVfsStdFile_ReadFixRC(pThis, off, pSgBuf->paSegs[0].cbSeg, *pcbRead);
    100146    }
    101147    else
    102148    {
     149        size_t  cbSeg      = 0;
    103150        size_t  cbRead     = 0;
    104         size_t  cbReadSeg;
    105         size_t *pcbReadSeg = pcbRead ? &cbReadSeg : NULL;
     151        size_t  cbReadSeg  = 0;
    106152        rc = VINF_SUCCESS;
    107153
    108154        for (uint32_t iSeg = 0; iSeg < pSgBuf->cSegs; iSeg++)
    109155        {
    110             void   *pvSeg = pSgBuf->paSegs[iSeg].pvSeg;
    111             size_t  cbSeg  = pSgBuf->paSegs[iSeg].cbSeg;
    112 
    113             cbReadSeg = 0;
     156            void *pvSeg = pSgBuf->paSegs[iSeg].pvSeg;
     157            cbSeg       = pSgBuf->paSegs[iSeg].cbSeg;
     158
     159            cbReadSeg = cbSeg;
    114160            if (off < 0)
    115                 rc = RTFileRead(pThis->hFile, pvSeg, cbSeg, pcbReadSeg);
     161                rc = RTFileRead(  pThis->hFile,      pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);
    116162            else
    117             {
    118                 rc = RTFileReadAt(pThis->hFile, off, pvSeg, cbSeg, pcbReadSeg);
    119                 off += cbSeg;
    120             }
     163                rc = RTFileReadAt(pThis->hFile, off, pvSeg, cbSeg, pcbRead ? &cbReadSeg : NULL);
    121164            if (RT_FAILURE(rc))
    122165                break;
    123             if (pcbRead)
    124             {
    125                 cbRead += cbReadSeg;
    126                 if (cbReadSeg != cbSeg)
    127                     break;
    128             }
     166            if (off < 0)
     167                off += cbReadSeg;
     168            cbRead  += cbReadSeg;
     169            if ((pcbRead && cbReadSeg != cbSeg) || rc != VINF_SUCCESS)
     170                break;
    129171        }
    130172
    131173        if (pcbRead)
     174        {
    132175            *pcbRead = cbRead;
     176            if (rc == VINF_SUCCESS)
     177                rc = rtVfsStdFile_ReadFixRC(pThis, off, cbSeg, cbReadSeg);
     178        }
    133179    }
    134180
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