VirtualBox

Changeset 80835 in vbox for trunk/src/VBox/Main/glue


Ignore:
Timestamp:
Sep 16, 2019 8:30:40 PM (5 years ago)
Author:
vboxsync
Message:

Main/glue: Added bstr testcase and fixed printf bugs. Introduced jolt, joltNoThrow, reserve and reserveNoThrow for the low level allocation operations needed by printf.

File:
1 edited

Legend:

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

    r80793 r80835  
    112112                if (cwcAlloc <= cwcBoth)
    113113                    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                 }
     114                pArgs->hrc = pThis->reserveNoThrow(cwcAlloc, true /*fForce*/);
     115                AssertMsgReturn(pArgs->hrc == S_OK, ("cwcAlloc=%#zx\n", cwcAlloc), 0);
    123116                pArgs->cwcAlloc = cwcAlloc;
    124117            }
     
    134127        rc = ::RTStrToUtf16Ex(pachChars, cbChars, &pwszDst, pArgs->cwcAlloc - pArgs->offDst, &cwcAppend);
    135128        AssertRCReturnStmt(rc, pArgs->hrc = E_UNEXPECTED, 0);
     129        pArgs->offDst += cwcAppend;
    136130    }
    137131    return cbChars;
     
    142136    cleanup();
    143137    BSTRNOTHROW Args = { this, 0, 0, S_OK };
    144     RTStrFormatV(printfOutputCallbackNoThrow, this, NULL, NULL, pszFormat, va);
     138    RTStrFormatV(printfOutputCallbackNoThrow, &Args, NULL, NULL, pszFormat, va);
    145139    if (Args.hrc == S_OK)
    146140    {
    147 #ifdef RT_OS_WINDOWS
    148         if (Args.offDst + 1 == Args.cwcAlloc)
     141        Args.hrc = joltNoThrow(Args.offDst);
     142        if (Args.hrc == S_OK)
    149143            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
    159144    }
    160145    cleanup();
     
    244229
    245230
     231#ifndef VBOX_WITH_XPCOM
     232
     233HRESULT Bstr::joltNoThrow(ssize_t cwcNew /* = -1*/)
     234{
     235    if (m_bstr)
     236    {
     237        size_t const cwcAlloc  = ::SysStringLen(m_bstr);
     238        size_t const cwcActual = cwcNew < 0 ? ::RTUtf16Len(m_bstr) : (size_t)cwcNew;
     239        Assert(cwcNew < 0 || cwcActual == ::RTUtf16Len(m_bstr));
     240        if (cwcActual != cwcAlloc)
     241        {
     242            Assert(cwcActual <= cwcAlloc);
     243            Assert((unsigned int)cwcActual == cwcActual);
     244
     245            /* Official way: Reallocate the string.   We could of course just update the size-prefix if we dared... */
     246            if (!::SysReAllocStringLen(&m_bstr, NULL, (unsigned int)cwcActual))
     247            {
     248                AssertFailed();
     249                return E_OUTOFMEMORY;
     250            }
     251        }
     252    }
     253    else
     254        Assert(cwcNew <= 0);
     255    return S_OK;
     256}
     257
     258
     259void Bstr::jolt(ssize_t cwcNew /* = -1*/)
     260{
     261    HRESULT hrc = joltNoThrow(cwcNew);
     262    if (hrc != S_OK)
     263        throw std::bad_alloc();
     264}
     265
     266#endif /* !VBOX_WITH_XPCOM */
     267
     268
     269HRESULT Bstr::reserveNoThrow(size_t cwcMin, bool fForce /*= false*/) RT_NOEXCEPT
     270{
     271    /* If not forcing the string to the cwcMin length, check cwcMin against the
     272       current string length: */
     273    if (!fForce)
     274    {
     275        size_t cwcCur = m_bstr ? ::SysStringLen(m_bstr) : 0;
     276        if (cwcCur >= cwcMin)
     277            return S_OK;
     278    }
     279
     280    /* The documentation for SysReAllocStringLen hints about it being allergic
     281       to NULL in some way or another, so we call SysAllocStringLen directly
     282       when appropriate: */
     283    if (m_bstr)
     284        AssertReturn(::SysReAllocStringLen(&m_bstr, NULL, (unsigned int)cwcMin) != FALSE, E_OUTOFMEMORY);
     285    else if (cwcMin > 0)
     286    {
     287        m_bstr = ::SysAllocStringLen(NULL, (unsigned int)cwcMin);
     288        AssertReturn(m_bstr, E_OUTOFMEMORY);
     289    }
     290
     291    return S_OK;
     292}
     293
     294
     295void Bstr::reserve(size_t cwcMin, bool fForce /*= false*/)
     296{
     297    HRESULT hrc = reserveNoThrow(cwcMin, fForce);
     298    if (hrc != S_OK)
     299        throw std::bad_alloc();
     300}
     301
     302
    246303/* static */
    247304const Utf8Str Utf8Str::Empty; /* default ctor is OK */
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