VirtualBox

Changeset 80793 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Sep 15, 2019 11:27:47 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133360
Message:

Bstr: Added printf, printfNoThrow, printfV and printfVNoThrow methods (untested).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/glue/string.cpp

    r78417 r80793  
    3535/* static */
    3636const Bstr Bstr::Empty; /* default ctor is OK */
     37
     38
     39Bstr &Bstr::printf(const char *pszFormat, ...)
     40{
     41    va_list va;
     42    va_start(va, pszFormat);
     43    HRESULT hrc = printfVNoThrow(pszFormat, va);
     44    va_end(va);
     45    if (hrc == S_OK)
     46    { /* likely */ }
     47    else
     48        throw std::bad_alloc();
     49    return *this;
     50}
     51
     52HRESULT Bstr::printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT
     53{
     54    va_list va;
     55    va_start(va, pszFormat);
     56    HRESULT hrc = printfVNoThrow(pszFormat, va);
     57    va_end(va);
     58    return hrc;
     59}
     60
     61
     62Bstr &Bstr::printfV(const char *pszFormat, va_list va)
     63{
     64    HRESULT hrc = printfVNoThrow(pszFormat, va);
     65    if (hrc == S_OK)
     66    { /* likely */ }
     67    else
     68        throw std::bad_alloc();
     69    return *this;
     70}
     71
     72struct BSTRNOTHROW
     73{
     74    Bstr   *pThis;
     75    size_t  cwcAlloc;
     76    size_t  offDst;
     77    HRESULT hrc;
     78};
     79
     80/**
     81 * Callback used with RTStrFormatV by Bstr::printfVNoThrow.
     82 *
     83 * @returns The number of bytes added (not used).
     84 *
     85 * @param   pvArg           Pointer to a BSTRNOTHROW structure.
     86 * @param   pachChars       The characters to append.
     87 * @param   cbChars         The number of characters.  0 on the final callback.
     88 */
     89/*static*/ DECLCALLBACK(size_t)
     90Bstr::printfOutputCallbackNoThrow(void *pvArg, const char *pachChars, size_t cbChars) RT_NOEXCEPT
     91{
     92    BSTRNOTHROW *pArgs = (BSTRNOTHROW *)pvArg;
     93    if (cbChars)
     94    {
     95        size_t cwcAppend;
     96        int rc = ::RTStrCalcUtf16LenEx(pachChars, cbChars, &cwcAppend);
     97        AssertRCReturnStmt(rc, pArgs->hrc = E_UNEXPECTED, 0);
     98
     99        /*
     100         * Ensure we've got sufficient memory.
     101         */
     102        Bstr *pThis = pArgs->pThis;
     103        size_t const cwcBoth = pArgs->offDst + cwcAppend;
     104        if (cwcBoth >= pArgs->cwcAlloc)
     105        {
     106            if (pArgs->hrc == S_OK)
     107            {
     108                /* Double the buffer size, if it's less that _1M. Align sizes like
     109                   for append. */
     110                size_t cwcAlloc = RT_ALIGN_Z(pArgs->cwcAlloc, 128);
     111                cwcAlloc += RT_MIN(cwcAlloc, _1M);
     112                if (cwcAlloc <= cwcBoth)
     113                    cwcAlloc = RT_ALIGN_Z(cwcBoth + 1, 512);
     114                if (pArgs->cwcAlloc)
     115                    AssertMsgReturnStmt(::SysReAllocStringLen(&pThis->m_bstr, NULL, (unsigned)cwcAlloc),
     116                                        ("cwcAlloc=%#zx\n", cwcAlloc), pArgs->hrc = E_OUTOFMEMORY, 0);
     117                else
     118                {
     119                    Assert(pThis->m_bstr == NULL);
     120                    pThis->m_bstr = ::SysAllocStringLen(NULL, (unsigned)cwcAlloc);
     121                    AssertMsgReturnStmt(pThis->m_bstr, ("cwcAlloc=%#zx\n", cwcAlloc), pArgs->hrc = E_OUTOFMEMORY, 0);
     122                }
     123                pArgs->cwcAlloc = cwcAlloc;
     124            }
     125            else
     126                return 0;
     127        }
     128
     129        /*
     130         * Do the conversion.
     131         */
     132        PRTUTF16 pwszDst = pThis->m_bstr + pArgs->offDst;
     133        Assert(pArgs->cwcAlloc > pArgs->offDst);
     134        rc = ::RTStrToUtf16Ex(pachChars, cbChars, &pwszDst, pArgs->cwcAlloc - pArgs->offDst, &cwcAppend);
     135        AssertRCReturnStmt(rc, pArgs->hrc = E_UNEXPECTED, 0);
     136    }
     137    return cbChars;
     138}
     139
     140HRESULT Bstr::printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT
     141{
     142    cleanup();
     143    BSTRNOTHROW Args = { this, 0, 0, S_OK };
     144    RTStrFormatV(printfOutputCallbackNoThrow, this, NULL, NULL, pszFormat, va);
     145    if (Args.hrc == S_OK)
     146    {
     147#ifdef RT_OS_WINDOWS
     148        if (Args.offDst + 1 == Args.cwcAlloc)
     149            return S_OK;
     150
     151        /* Official way: Reallocate the string.   We could of course just update the size-prefix if we dare... */
     152        if (SysReAllocStringLen(&m_bstr, NULL, (unsigned)(Args.offDst + 1)))
     153            return S_OK;
     154        AssertMsgFailed(("offDst=%#zx\n", Args.offDst));
     155        Args.hrc = E_OUTOFMEMORY;
     156#else
     157        return S_OK;
     158#endif
     159    }
     160    cleanup();
     161    return Args.hrc;
     162}
    37163
    38164void Bstr::copyFromN(const char *a_pszSrc, size_t a_cchMax)
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