VirtualBox

Changeset 96089 in vbox


Ignore:
Timestamp:
Aug 7, 2022 2:12:29 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
152888
Message:

IPRT/RTStream: Added RTStrmSeek, RTStrmTell, RTStrmSetBufferingMode and RTStrmQueryFileHandle. bugref:10261

Location:
trunk
Files:
3 edited

Legend:

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

    r96078 r96089  
    22902290# define RTStrmOpenFV                                   RT_MANGLER(RTStrmOpenFV)
    22912291# define RTStrmOpenFileHandle                           RT_MANGLER(RTStrmOpenFileHandle)
     2292# define RTStrmQueryFileHandle                          RT_MANGLER(RTStrmQueryFileHandle)
    22922293# define RTStrmPrintf                                   RT_MANGLER(RTStrmPrintf)
    22932294# define RTStrmPrintfV                                  RT_MANGLER(RTStrmPrintfV)
     
    22992300# define RTStrmReadEx                                   RT_MANGLER(RTStrmReadEx)
    23002301# define RTStrmRewind                                   RT_MANGLER(RTStrmRewind)
     2302# define RTStrmSetBufferingMode                         RT_MANGLER(RTStrmSetBufferingMode)
    23012303# define RTStrmSetMode                                  RT_MANGLER(RTStrmSetMode)
     2304# define RTStrmSeek                                     RT_MANGLER(RTStrmSeek)
     2305# define RTStrmTell                                     RT_MANGLER(RTStrmTell)
    23022306# define RTStrmWriteEx                                  RT_MANGLER(RTStrmWriteEx)
    23032307# define RTStrmIsTerminal                               RT_MANGLER(RTStrmIsTerminal)
  • trunk/include/iprt/stream.h

    r96077 r96089  
    144144
    145145/**
     146 * Queries the file handle backing the stream.
     147 *
     148 * @returns iprt status code.
     149 * @retval  VERR_NOT_AVAILABLE if the stream has no valid handle associated with
     150 *          it.
     151 *
     152 * @param   pStream         The stream.
     153 * @param   phFile          Where to return the file handle.  This should not be
     154 *                          closed!
     155 */
     156RTR3DECL(int) RTStrmQueryFileHandle(PRTSTREAM pStream, PRTFILE phFile);
     157
     158/**
    146159 * Closes the specified stream.
    147160 *
     
    188201RTR3DECL(int) RTStrmSetMode(PRTSTREAM pStream, int fBinary, int fCurrentCodeSet);
    189202
     203/** Stream buffering modes. */
     204typedef enum RTSTRMBUFMODE
     205{
     206    RTSTRMBUFMODE_INVALID = 0,
     207    RTSTRMBUFMODE_FULL,         /**< Full buffering. */
     208    RTSTRMBUFMODE_LINE,         /**< Line buffering. On Windows this could be the same as RTSTRMBUFMODE_FULL. */
     209    RTSTRMBUFMODE_UNBUFFERED,   /**< No buffering. */
     210    RTSTRMBUFMODE_END,
     211    RTSTRMBUFMODE_32BIT_HACK = 0x7fffffff
     212} RTSTRMBUFMODE;
     213
     214/**
     215 * Changes the stream buffering mode.
     216 *
     217 * @returns iprt status code.
     218 * @param   pStream         The stream.
     219 * @param   enmBufMode      The new buffering mode.
     220 */
     221RTR3DECL(int) RTStrmSetBufferingMode(PRTSTREAM pStream, RTSTRMBUFMODE enmBufMode);
     222
    190223/**
    191224 * Returns the current echo mode.
     225 *
    192226 * This works only for standard input streams.
    193227 *
     
    201235/**
    202236 * Changes the behavior for echoing inpit characters on the command line.
     237 *
    203238 * This works only for standard input streams.
    204239 *
     
    242277 */
    243278RTR3DECL(int) RTStrmRewind(PRTSTREAM pStream);
     279
     280/**
     281 * Changes the file position.
     282 *
     283 * @returns IPRT status code.
     284 *
     285 * @param   pStream         The stream.
     286 * @param   off             The seek offset.
     287 * @param   uMethod         Seek method, i.e. one of the RTFILE_SEEK_* defines.
     288 *
     289 * @remarks Not all streams are seekable and that behavior is currently
     290 *          undefined for those.
     291 */
     292RTR3DECL(int) RTStrmSeek(PRTSTREAM pStream, RTFOFF off, uint32_t uMethod);
     293
     294/**
     295 * Tells the stream position.
     296 *
     297 * @returns Stream position or IPRT error status. Non-negative numbers are
     298 *          stream positions, while negative numbers are IPRT error stauses.
     299 *
     300 * @param   pStream         The stream.
     301 *
     302 * @remarks Not all streams have a position and that behavior is currently
     303 *          undefined for those.
     304 */
     305RTR3DECL(RTFOFF) RTStrmTell(PRTSTREAM pStream);
    244306
    245307/**
  • trunk/src/VBox/Runtime/r3/stream.cpp

    r96077 r96089  
    160160    /** The stream buffer direction.   */
    161161    RTSTREAMBUFDIR      enmBufDir;
    162     /** The buffering style (unbuffered, line, full). */
     162    /** The buffering style (unbuffered, line, full).
     163     * @todo replace by RTSTRMBUFMODE.  */
    163164    RTSTREAMBUFSTYLE    enmBufStyle;
    164165# ifdef RTSTREAM_WITH_TEXT_MODE
     166    /** Bitmap running parallel to each char pchBuf, indicating where a '\\r'
     167     * character have been removed during buffer filling.  This is used to implement
     168     * RTStrmTell in non-binary mode. */
     169    uint32_t           *pbmBuf;
    165170    /** Indicates that we've got a CR ('\\r') beyond the end of official buffer
    166171     * and need to check if there is a LF following it.  This member is ignored
     
    223228    /* .enmBufStyle = */        RTSTREAMBUFSTYLE_UNBUFFERED,
    224229# ifdef RTSTREAM_WITH_TEXT_MODE
     230    /* .pbmBuf = */             NULL,
    225231    /* .fPendingCr = */         false,
    226232# endif
     
    254260    /* .enmBufStyle = */        RTSTREAMBUFSTYLE_UNBUFFERED,
    255261# ifdef RTSTREAM_WITH_TEXT_MODE
     262    /* .pbmBuf = */             NULL,
    256263    /* .fPendingCr = */         false,
    257264# endif
     
    285292    /* .enmBufStyle = */        RTSTREAMBUFSTYLE_LINE,
    286293# ifdef RTSTREAM_WITH_TEXT_MODE
     294    /* .pbmBuf = */             NULL,
    287295    /* .fPendingCr = */         false,
    288296# endif
     
    530538        pStream->enmBufStyle        = RTSTREAMBUFSTYLE_FULL;
    531539# ifdef RTSTREAM_WITH_TEXT_MODE
     540        pStream->pbmBuf             = NULL;
    532541        pStream->fPendingCr         = false,
    533542# endif
     
    771780    pStream->offBufFirst    = 0;
    772781    pStream->offBufEnd      = 0;
     782# ifdef RTSTREAM_WITH_TEXT_MODE
     783    RTMemFree(pStream->pbmBuf);
     784    pStream->pbmBuf         = NULL;
     785# endif
    773786#else
    774787    pStream->pFile          = NULL;
     
    838851}
    839852
     853
     854RTR3DECL(int) RTStrmSetBufferingMode(PRTSTREAM pStream, RTSTRMBUFMODE enmMode)
     855{
     856    AssertPtrReturn(pStream, VERR_INVALID_HANDLE);
     857    AssertReturn(pStream->u32Magic == RTSTREAM_MAGIC, VERR_INVALID_HANDLE);
     858    AssertReturn(enmMode > RTSTRMBUFMODE_INVALID && enmMode < RTSTRMBUFMODE_END, VERR_INVALID_PARAMETER);
     859
     860#ifndef RTSTREAM_STANDALONE
     861    int iCrtMode = enmMode == RTSTRMBUFMODE_FULL ? _IOFBF : enmMode == RTSTRMBUFMODE_LINE ? _IOLBF : _IONBF;
     862    int rc = setvbuf(pStream->pFile, NULL, iCrtMode, 0);
     863    if (rc >= 0)
     864        return VINF_SUCCESS;
     865    return RTErrConvertFromErrno(errno);
     866
     867#else
     868    rtStrmLock(pStream);
     869    pStream->enmBufStyle = enmMode == RTSTRMBUFMODE_FULL ? RTSTREAMBUFSTYLE_FULL
     870                         : enmMode == RTSTRMBUFMODE_LINE ? RTSTREAMBUFSTYLE_LINE : RTSTREAMBUFSTYLE_UNBUFFERED;
     871    rtStrmUnlock(pStream);
     872    return VINF_SUCCESS;
     873#endif
     874}
     875
     876
    840877#ifdef RTSTREAM_STANDALONE
    841878
     
    892929}
    893930
     931
    894932/**
    895933 * For lazily resolving handles for the standard streams.
     
    901939        return hFile;
    902940    return rtStrmGetFileNil(pStream);
     941}
     942
     943
     944RTR3DECL(int) RTStrmQueryFileHandle(PRTSTREAM pStream, PRTFILE phFile)
     945{
     946    AssertPtrReturn(phFile, VERR_INVALID_POINTER);
     947    *phFile = NIL_RTFILE;
     948    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     949    AssertReturn(pStream->u32Magic == RTSTREAM_MAGIC, VERR_INVALID_MAGIC);
     950
     951    rtStrmLock(pStream);
     952    RTFILE hFile = rtStrmGetFile(pStream);
     953    rtStrmUnlock(pStream);
     954    if (hFile != NIL_RTFILE)
     955    {
     956        *phFile = hFile;
     957        return VINF_SUCCESS;
     958    }
     959    return VERR_NOT_AVAILABLE;
    903960}
    904961
     
    11941251        if (RT_LIKELY(pStream->pchBuf))
    11951252        {
    1196             pStream->cbBufAlloc = cbBuf;
    1197             return VINF_SUCCESS;
     1253# ifdef RTSTREAM_WITH_TEXT_MODE
     1254            Assert(RT_ALIGN_Z(cbBuf, 64 / 8) == cbBuf);
     1255            pStream->pbmBuf = (uint32_t *)RTMemAllocZ(cbBuf / 8);
     1256            if (RT_LIKELY(pStream->pbmBuf))
     1257# endif
     1258            {
     1259                pStream->cbBufAlloc = cbBuf;
     1260                return VINF_SUCCESS;
     1261            }
     1262# ifdef RTSTREAM_WITH_TEXT_MODE
     1263            RTMemFree(pStream->pchBuf);
     1264            pStream->pchBuf = NULL;
     1265# endif
    11981266        }
    11991267        cbBuf /= 2;
     
    13131381    AssertPtr(pStream->pchBuf);
    13141382    Assert(pStream->cbBufAlloc  >= 256);
     1383    Assert(RT_ALIGN_Z(pStream->cbBufAlloc, 64) == pStream->cbBufAlloc);
    13151384    Assert(pStream->offBufFirst <= pStream->cbBufAlloc);
    13161385    Assert(pStream->offBufEnd   <= pStream->cbBufAlloc);
    13171386    Assert(pStream->offBufFirst <= pStream->offBufEnd);
    1318 
     1387# ifdef RTSTREAM_WITH_TEXT_MODE
     1388    AssertPtr(pStream->pbmBuf);
     1389# endif
    13191390    /*
    13201391     * If there is data in the buffer, move it up to the start.
     
    13271398        cbInBuffer = pStream->offBufEnd - pStream->offBufFirst;
    13281399        if (cbInBuffer)
     1400        {
    13291401            memmove(pStream->pchBuf, &pStream->pchBuf[pStream->offBufFirst], cbInBuffer);
     1402# ifdef RTSTREAM_WITH_TEXT_MODE
     1403            if (!pStream->fBinary) /** @todo this isn't very efficient, must be a better way of shifting a bitmap. */
     1404                for (size_t off = 0; off < pStream->offBufFirst; off++)
     1405                    if (ASMBitTest(pStream->pbmBuf, (int32_t)off))
     1406                        ASMBitSet(pStream->pbmBuf, (int32_t)off);
     1407                    else
     1408                        ASMBitClear(pStream->pbmBuf, (int32_t)off);
     1409# endif
     1410        }
    13301411        pStream->offBufFirst = 0;
    13311412        pStream->offBufEnd   = cbInBuffer;
     
    13581439        if (cbInBuffer != 0)
    13591440        {
     1441# ifdef RTSTREAM_WITH_TEXT_MODE
    13601442            if (pStream->fBinary)
     1443# endif
    13611444                return VINF_SUCCESS;
    13621445        }
     
    13681451        }
    13691452
     1453# ifdef RTSTREAM_WITH_TEXT_MODE
    13701454        /*
    13711455         * Do CRLF -> LF conversion in the buffer.
    13721456         */
     1457        ASMBitClearRange(pStream->pbmBuf, offCrLfConvStart, RT_ALIGN_Z(cbInBuffer, 64));
    13731458        char  *pchCur = &pStream->pchBuf[offCrLfConvStart];
    13741459        size_t cbLeft = cbInBuffer - offCrLfConvStart;
     
    13901475                        do
    13911476                        {
     1477                            ASMBitSet(pStream->pbmBuf, (int32_t)(pchCur - pStream->pchBuf));
    13921478                            *pchCur++  = '\n'; /* dst */
    13931479                            cbLeft    -= 2;
     
    14161502
    14171503        return VINF_SUCCESS;
     1504# endif
    14181505    }
    14191506
     
    14861573        pStream->offBufFirst = 0;
    14871574        pStream->offBufEnd   = 0;
     1575# ifdef RTSTREAM_WITH_TEXT_MODE
     1576        RTMemFree(pStream->pbmBuf);
     1577        pStream->pbmBuf = NULL;
     1578# endif
    14881579    }
    14891580
     
    15851676#endif
    15861677    return rc;
     1678}
     1679
     1680
     1681/**
     1682 * Changes the file position.
     1683 *
     1684 * @returns IPRT status code.
     1685 *
     1686 * @param   pStream         The stream.
     1687 * @param   off             The seek offset.
     1688 * @param   uMethod         Seek method, i.e. one of the RTFILE_SEEK_* defines.
     1689 *
     1690 * @remarks Not all streams are seekable and that behavior is currently
     1691 *          undefined for those.
     1692 */
     1693RTR3DECL(int) RTStrmSeek(PRTSTREAM pStream, RTFOFF off, uint32_t uMethod)
     1694{
     1695    AssertReturn(uMethod <= RTFILE_SEEK_END, VERR_INVALID_PARAMETER);
     1696#ifdef RTSTREAM_STANDALONE
     1697    rtStrmLock(pStream);
     1698    int rc = rtStrmBufFlushWriteMaybe(pStream, true /*fInvalidate*/);
     1699    if (RT_SUCCESS(rc))
     1700        rc = RTFileSeek(rtStrmGetFile(pStream), off, uMethod, NULL);
     1701    if (RT_FAILURE(rc))
     1702        ASMAtomicWriteS32(&pStream->i32Error, rc);
     1703    rtStrmUnlock(pStream);
     1704#else
     1705    int const iCrtMethod = uMethod == RTFILE_SEEK_BEGIN ? SEEK_SET : uMethod == RTFILE_SEEK_CURRENT ? SEEK_CUR : SEEK_END;
     1706    errno = 0;
     1707    int rc;
     1708# ifdef _MSC_VER
     1709    if (!_fseeki64(pStream->pFile, off, iCrtMethod))
     1710# else
     1711    if (!fseeko(pStream->pFile, off, iCrtMethod))
     1712# endif
     1713        rc = VINF_SUCCESS;
     1714    else
     1715        rc = RTErrConvertFromErrno(errno);
     1716    ASMAtomicWriteS32(&pStream->i32Error, rc);
     1717#endif
     1718    return rc;
     1719}
     1720
     1721
     1722/**
     1723 * Tells the stream position.
     1724 *
     1725 * @returns Stream position or IPRT error status. Non-negative numbers are
     1726 *          stream positions, while negative numbers are IPRT error stauses.
     1727 *
     1728 * @param   pStream         The stream.
     1729 *
     1730 * @remarks Not all streams have a position and that behavior is currently
     1731 *          undefined for those.
     1732 */
     1733RTR3DECL(RTFOFF) RTStrmTell(PRTSTREAM pStream)
     1734{
     1735#ifdef RTSTREAM_STANDALONE
     1736    uint64_t off = 0;
     1737    rtStrmLock(pStream);
     1738    int rc = pStream->i32Error;
     1739    if (RT_SUCCESS(rc))
     1740    {
     1741        rc = RTFileSeek(rtStrmGetFile(pStream), 0, RTFILE_SEEK_CURRENT, &off);
     1742        if (RT_SUCCESS(rc))
     1743        {
     1744            switch (pStream->enmBufDir)
     1745            {
     1746                case RTSTREAMBUFDIR_READ:
     1747                    /* Subtract unconsumed chars and removed '\r' characters. */
     1748                    off -= pStream->offBufEnd - pStream->offBufFirst;
     1749                    if (!pStream->fBinary)
     1750                        for (size_t offBuf = pStream->offBufFirst; offBuf < pStream->offBufEnd; offBuf++)
     1751                            off -= ASMBitTest(pStream->pbmBuf, (int32_t)offBuf);
     1752                    break;
     1753                case RTSTREAMBUFDIR_WRITE:
     1754                    /* Add unwrittend chars in the buffer. */
     1755                    off += pStream->offBufEnd - pStream->offBufFirst;
     1756                    break;
     1757                default:
     1758                    AssertFailed();
     1759                case RTSTREAMBUFDIR_NONE:
     1760                    break;
     1761            }
     1762        }
     1763    }
     1764    if (RT_FAILURE(rc))
     1765    {
     1766        ASMAtomicWriteS32(&pStream->i32Error, rc);
     1767        off = rc;
     1768    }
     1769    rtStrmUnlock(pStream);
     1770#else
     1771# ifdef _MSC_VER
     1772    RTFOFF off = _ftelli64(pStream->pFile);
     1773# else
     1774    RTFOFF off = ftello(pStream->pFile);
     1775# endif
     1776    if (off < 0)
     1777    {
     1778        int rc = RTErrConvertFromErrno(errno);
     1779        ASMAtomicWriteS32(&pStream->i32Error, rc);
     1780        off = rc;
     1781    }
     1782#endif
     1783    return off;
    15871784}
    15881785
Note: See TracChangeset for help on using the changeset viewer.

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