VirtualBox

Changeset 26587 in vbox for trunk/include


Ignore:
Timestamp:
Feb 16, 2010 4:57:09 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
57775
Message:

Main: Bstr makeover (second attempt) -- make Bstr(NULL) and Bstr() behave the same; resulting cleanup; make some more internal methods use Utf8Str instead of Bstr; fix a lot of CheckComArgNotNull?() usage

Location:
trunk/include
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/com/Guid.h

    r26553 r26587  
    9797    {
    9898        ::RTUuidClear (&uuid);
    99         if (!that.isNull())
     99        if (!that.isEmpty())
    100100           ::RTUuidFromUtf16(&uuid, that.raw());
    101101        refresh();
     
    145145    }
    146146
    147     Bstr toUtf16 () const
     147    Bstr toUtf16() const
    148148    {
    149149        if (isEmpty())
  • trunk/include/VBox/com/string.h

    r26553 r26587  
    33/** @file
    44 * MS COM / XPCOM Abstraction Layer:
    5  * Smart string classes declaration
     5 * UTF-8 and UTF-16 string classes
    66 */
    77
     
    5959
    6060/**
    61  *  Helper class that represents the |BSTR| type and hides platform-specific
    62  *  implementation details.
    63  *
    64  *  This class uses COM/XPCOM-provided memory management routines to allocate
    65  *  and free string buffers. This makes it possible to:
    66  *  - use it as a type of member variables of COM/XPCOM components and pass
    67  *    their values to callers through component methods' output parameters
    68  *    using the #cloneTo() operation;
    69  *  - adopt (take ownership of) string buffers returned in output parameters
    70  *    of COM methods using the #asOutParam() operation and correctly free them
    71  *    afterwards.
     61 *  String class used universally in Main for COM-style Utf-16 strings.
     62 *  Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
     63 *  back and forth since most of VirtualBox and our libraries use UTF-8.
     64 *  The Bstr class makes such conversions easier.
     65 *
     66 *  Whereas the BSTR identifier is a typedef for a pointer to a wide character
     67 *  array (const char *uint_16 effectively, depending on the platform),
     68 *  the Bstr class is a fully featured string class with memory management
     69 *  for such strings.
     70 *
     71 *  Bstr uses COM/XPCOM-provided memory management routines (SysAlloc* etc.)
     72 *  to allocate and free string buffers. This makes it possible to use it as
     73 *  a type of member variables of COM/XPCOM components and pass their values
     74 *  to callers through component methods' output parameters using the #cloneTo()
     75 *  operation. Also, the class can adopt (take ownership of) string buffers
     76 *  returned in output parameters of COM methods using the #asOutParam()
     77 *  operation and correctly free them afterwards.
     78 *
     79 *  As opposed to the Ut8Str class, which is very efficient, Bstr does not
     80 *  cache the length of its member string. As a result, copying Bstr's is
     81 *  more expensive, and Bstr really should only be used to capture arguments
     82 *  from and return data to public COM methods.
     83 *
     84 *  Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
     85 *  between NULL strings and empty strings. In other words, Bstr("") and
     86 *  Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
     87 *  reports a zero length and zero allocated bytes for both, and returns an
     88 *  empty C wide string from raw().
    7289 */
    7390class Bstr
     
    7592public:
    7693
    77     typedef BSTR String;
    78     typedef CBSTR ConstString;
    79 
    80     Bstr() : bstr(NULL) {}
    81 
    82     Bstr(const Bstr &that) : bstr(NULL) { raw_copy(bstr, that.bstr); }
    83     Bstr(CBSTR that) : bstr(NULL) { raw_copy(bstr, that); }
     94    /**
     95     * Creates an empty string that has no memory allocated.
     96     */
     97    Bstr()
     98        : m_bstr(NULL)
     99    {
     100    }
     101
     102    /**
     103     * Creates a copy of another Bstr.
     104     *
     105     * This allocates s.length() + 1 wide characters for the new instance, unless s is empty.
     106     *
     107     * @param   s               The source string.
     108     *
     109     * @throws  std::bad_alloc
     110     */
     111    Bstr(const Bstr &s)
     112    {
     113        copyFrom(s);
     114    }
     115
     116    /**
     117     * Creates a copy of a wide char string buffer.
     118     *
     119     * This allocates SysStringLen(pw) + 1 wide characters for the new instance, unless s is empty.
     120     *
     121     * @param   pcsz            The source string.
     122     *
     123     * @throws  std::bad_alloc
     124     */
     125    Bstr(CBSTR pw)
     126    {
     127        copyFrom(pw);
     128    }
    84129
    85130#if defined (VBOX_WITH_XPCOM)
    86     Bstr(const wchar_t *that) : bstr(NULL)
     131    Bstr(const wchar_t *pw)
    87132    {
    88133        AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
    89         raw_copy(bstr, (CBSTR)that);
     134        copyFrom((CBSTR)pw);
    90135    }
    91136#endif
    92137
    93     Bstr(const iprt::MiniString &that);
    94     Bstr(const char *that);
    95 
    96     /** Shortcut that calls #alloc(aSize) right after object creation. */
    97     Bstr(size_t aSize) : bstr(NULL) { alloc(aSize); }
    98 
    99     ~Bstr() { setNull(); }
    100 
    101     Bstr &operator=(const Bstr &that) { safe_assign(that.bstr); return *this; }
    102     Bstr &operator=(CBSTR that) { safe_assign(that); return *this; }
    103 
    104     Bstr &operator=(const Utf8Str &that);
    105     Bstr &operator=(const char *that);
    106 
    107     Bstr &setNull()
    108     {
    109         if (bstr)
    110         {
    111             ::SysFreeString(bstr);
    112             bstr = NULL;
    113         }
    114         return *this;
    115     }
    116 
    117     Bstr &setNullIfEmpty()
    118     {
    119         if (bstr && *bstr == 0)
    120         {
    121             ::SysFreeString(bstr);
    122             bstr = NULL;
    123         }
    124         return *this;
    125     }
    126 
    127     /**
    128      *  Allocates memory for a string capable to store \a aSize - 1 characters;
    129      *  in other words, aSize includes the terminating zero character. If \a aSize
    130      *  is zero, or if a memory allocation error occurs, this object will become null.
    131      */
    132     Bstr &alloc(size_t aSize)
    133     {
    134         setNull();
    135         if (aSize)
    136         {
    137             unsigned int size = (unsigned int) aSize; Assert(size == aSize);
    138             bstr = ::SysAllocStringLen(NULL, size - 1);
    139             if (bstr)
    140                 bstr[0] = 0;
    141         }
    142         return *this;
    143     }
    144 
    145     int compare(CBSTR str) const
    146     {
    147         return ::RTUtf16Cmp((PRTUTF16) bstr, (PRTUTF16) str);
    148     }
    149 
    150     int compare(BSTR str) const
    151     {
    152         return ::RTUtf16Cmp((PRTUTF16) bstr, (PRTUTF16) str);
    153     }
    154 
    155     bool operator==(const Bstr &that) const { return !compare(that.bstr); }
    156     bool operator!=(const Bstr &that) const { return !!compare(that.bstr); }
     138
     139    /**
     140     * Creates a copy of an IPRT MiniString (which includes Utf8Str).
     141     *
     142     * This allocates s.length() + 1 wide characters for the new instance, unless s is empty.
     143     *
     144     * @param   pcsz            The source string.
     145     *
     146     * @throws  std::bad_alloc
     147     */
     148    Bstr(const iprt::MiniString &s)
     149    {
     150        copyFrom(s.c_str());        // @todo the source string length is know, we can probably speed this up
     151    }
     152
     153    /**
     154     * Creates a copy of a C string.
     155     *
     156     * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
     157     *
     158     * @param   pcsz            The source string.
     159     *
     160     * @throws  std::bad_alloc
     161     */
     162    Bstr(const char *pcsz)
     163    {
     164        copyFrom(pcsz);
     165    }
     166
     167    /**
     168     * String length in wide characters.
     169     *
     170     * Returns the length of the member string, which is equal to SysStringLen(raw()).
     171     * In other words, this returns neither bytes nor the number of unicode codepoints.
     172     *
     173     * As opposed to Utf8Str::length(), this is _not_ cached and expensive.
     174     */
     175    size_t length() const
     176    {
     177        return ::SysStringLen(m_bstr);
     178    }
     179
     180    /**
     181     * Deallocates all memory.
     182     */
     183    inline void setNull()
     184    {
     185        cleanup();
     186    }
     187
     188    /**
     189     * Returns a const pointer to the member string. If the member string is empty,
     190     * returns a pointer to a static null character.
     191     * @return
     192     */
     193    CBSTR raw() const
     194    {
     195        return (m_bstr) ? m_bstr : (CBSTR)L"";
     196    }
     197
     198    /**
     199     * Empty string or not?
     200     *
     201     * Returns true if the member string has no length.
     202     *
     203     * @returns true if empty, false if not.
     204     */
     205    bool isEmpty() const
     206    {
     207        return (m_bstr == NULL);
     208    }
     209
     210    operator bool() const
     211    {
     212        return !isEmpty();
     213    }
     214
     215    bool operator!() const
     216    {
     217        return isEmpty();
     218    }
     219
     220    /** Case sensitivity selector. */
     221    enum CaseSensitivity
     222    {
     223        CaseSensitive,
     224        CaseInsensitive
     225    };
     226
     227    int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
     228    {
     229        if (m_bstr == str)
     230            return 0;
     231        if (m_bstr == NULL)
     232            return -1;
     233        if (str == NULL)
     234            return 1;
     235
     236        if (cs == CaseSensitive)
     237            return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
     238        else
     239            return ::RTUtf16ICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
     240    }
     241
     242    int compare(const Bstr &bstr, CaseSensitivity cs = CaseSensitive) const
     243    {
     244        return compare(bstr.raw(), cs);
     245    }
     246
     247    /** @name Comparison operators.
     248     * @{  */
     249    bool operator==(const Bstr &that) const { return !compare(that.raw()); }
     250    bool operator!=(const Bstr &that) const { return !!compare(that.raw()); }
     251    bool operator<( const Bstr &that) const { return compare(that.raw()) < 0; }
     252    bool operator>( const Bstr &that) const { return compare(that.raw()) > 0; }
     253
    157254    bool operator==(CBSTR that) const { return !compare(that); }
    158     bool operator==(BSTR that) const { return !compare(that); }
    159 
    160 #if defined (VBOX_WITH_XPCOM)
    161     bool operator!=(const wchar_t *that) const
    162     {
    163         AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
    164         return !!compare((CBSTR) that);
    165     }
    166     bool operator==(const wchar_t *that) const
    167     {
    168         AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
    169         return !compare((CBSTR) that);
    170     }
    171 #endif
    172 
    173255    bool operator!=(CBSTR that) const { return !!compare(that); }
    174     bool operator!=(BSTR that) const { return !!compare(that); }
    175     bool operator<(const Bstr &that) const { return compare(that.bstr) < 0; }
    176     bool operator<(CBSTR that) const { return compare(that) < 0; }
    177     bool operator<(BSTR that) const { return compare(that) < 0; }
    178 #if defined (VBOX_WITH_XPCOM)
    179     bool operator<(const wchar_t *that) const
    180     {
    181         AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
    182         return compare((CBSTR) that) < 0;
    183     }
    184 #endif
    185 
    186     int compareIgnoreCase(CBSTR str) const
    187     {
    188         return ::RTUtf16LocaleICmp(bstr, str);
    189     }
    190 
    191     bool isNull() const { return bstr == NULL; }
    192     operator bool() const { return !isNull(); }
    193 
    194     bool isEmpty() const { return isNull() || *bstr == 0; }
    195 
    196     size_t length() const { return isNull() ? 0 : ::RTUtf16Len((PRTUTF16) bstr); }
     256    bool operator<( CBSTR that) const { return compare(that) < 0; }
     257    bool operator>( CBSTR that) const { return compare(that) > 0; }
     258
     259    // the following two are necessary or stupid MSVC will complain with "ambiguous operator=="
     260    bool operator==( BSTR that) const { return !compare(that); }
     261    bool operator!=( BSTR that) const { return !!compare(that); }
     262
     263    /** @} */
    197264
    198265    /** Intended to to pass instances as |CBSTR| input parameters to methods. */
    199     operator CBSTR() const { return bstr; }
     266    operator CBSTR() const { return raw(); }
    200267
    201268    /**
     
    204271     * input BSTR parameters of interface methods are not const.
    205272     */
    206     operator BSTR() { return bstr; }
    207 
    208     /**
    209      *  The same as operator CBSTR(), but for situations where the compiler
    210      *  cannot typecast implicitly (for example, in printf() argument list).
    211      */
    212     CBSTR raw() const { return bstr; }
    213 
    214     /**
    215      *  Returns a non-const raw pointer that allows to modify the string directly.
    216      *  @warning
    217      *      Be sure not to modify data beyond the allocated memory! The
    218      *      guaranteed size of the allocated memory is at least #length()
    219      *      bytes after creation and after every assignment operation.
    220      */
    221     BSTR mutableRaw() { return bstr; }
     273    operator BSTR() { return (BSTR)raw(); }
    222274
    223275    /**
     
    225277     *  within the interface method. Transfers the ownership of the duplicated
    226278     *  string to the caller.
    227      */
    228     const Bstr &cloneTo(BSTR *pstr) const
     279     *
     280     *  This allocates a single 0 byte in the target if the member string is empty.
     281     */
     282    const Bstr& cloneTo(BSTR *pstr) const
    229283    {
    230284        if (pstr)
    231         {
    232             *pstr = NULL;
    233             raw_copy(*pstr, bstr);
    234         }
     285            *pstr = ::SysAllocString((const OLECHAR*)raw());
     286                    // raw() never returns NULL, so we always allocate something here
    235287        return *this;
    236288    }
     
    243295     *  As opposed to cloneTo(), this method doesn't create a copy of the
    244296     *  string.
    245      */
    246     Bstr &detachTo(BSTR *pstr)
    247     {
    248         *pstr = bstr;
    249         bstr = NULL;
     297     *
     298     *  This allocates a single 0 byte in the target if the member string is empty.
     299     */
     300    Bstr& detachTo(BSTR *pstr)
     301    {
     302        *pstr = (m_bstr) ? m_bstr : ::SysAllocString((const OLECHAR*)"");
     303        m_bstr = NULL;
    250304        return *this;
    251305    }
    252 
    253     /**
    254      *  Intended to assign copies of instances to |char *| out parameters from
    255      *  within the interface method. Transfers the ownership of the duplicated
    256      *  string to the caller.
    257      */
    258     const Bstr &cloneTo(char **pstr) const;
    259306
    260307    /**
     
    262309     *  Takes the ownership of the returned data.
    263310     */
    264     BSTR *asOutParam() { setNull(); return &bstr; }
     311    BSTR* asOutParam()
     312    {
     313        cleanup();
     314        return &m_bstr;
     315    }
    265316
    266317    /**
     
    271322protected:
    272323
    273     void safe_assign(CBSTR str)
    274     {
    275         if (bstr != str)
     324    /**
     325     * Destructor implementation, also used to clean up in operator=() before
     326     * assigning a new string.
     327     */
     328    void cleanup()
     329    {
     330        if (m_bstr)
    276331        {
    277             setNull();
    278             raw_copy(bstr, str);
     332            ::SysFreeString(m_bstr);
     333            m_bstr = NULL;
    279334        }
    280335    }
    281336
    282     inline static void raw_copy(BSTR &ls, CBSTR rs)
    283     {
    284         if (rs)
    285             ls = ::SysAllocString((const OLECHAR *) rs);
    286     }
    287 
    288     inline static void raw_copy(BSTR &ls, const char *rs)
    289     {
    290         if (rs)
     337    /**
     338     *  Protected internal helper which allocates memory for a string capable of
     339     *  storing \a aSize - 1 characters (not bytes, not codepoints); in other words,
     340     *  aSize includes the terminating null character.
     341     *
     342     *  Does NOT call cleanup() before allocating!
     343     *
     344     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     345     *             a NULL string.
     346     */
     347    void alloc(size_t cw)
     348    {
     349        if (cw)
    291350        {
     351            m_bstr = ::SysAllocStringLen(NULL, (unsigned int)cw - 1);
     352#ifdef RT_EXCEPTIONS_ENABLED
     353            if (!m_bstr)
     354                throw std::bad_alloc();
     355#endif
     356        }
     357    }
     358
     359    /**
     360     * Protected internal helper to copy a string, ignoring the previous object state.
     361     *
     362     * copyFrom() unconditionally sets the members to a copy of the given other
     363     * strings and makes no assumptions about previous contents. Can therefore be
     364     * used both in copy constructors, when member variables have no defined value,
     365     * and in assignments after having called cleanup().
     366     *
     367     * This variant copies from another Bstr. Since Bstr does _not_ cache string lengths,
     368     * this is not fast.
     369     *
     370     * @param   s               The source string.
     371     *
     372     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     373     *             a NULL string.
     374     */
     375    void copyFrom(const Bstr &s)
     376    {
     377        copyFrom(s.raw());
     378    }
     379
     380    /**
     381     * Protected internal helper to copy a string, ignoring the previous object state.
     382     *
     383     * See copyFrom() above.
     384     *
     385     * This variant copies from a wide char C string.
     386     *
     387     * @param   pcsz            The source string.
     388     *
     389     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     390     *             a NULL string.
     391     */
     392    void copyFrom(CBSTR pw)
     393    {
     394        size_t cwLength;
     395        if (    (pw)
     396             && ((cwLength = ::SysStringLen((BSTR)pw)))
     397           )
     398        {
     399            size_t cwAllocated = cwLength + 1;
     400            alloc(cwAllocated);
     401            memcpy(m_bstr, pw, cwAllocated * sizeof(OLECHAR));     // include 0 terminator
     402        }
     403        else
     404            m_bstr = NULL;
     405    }
     406
     407    /**
     408     * Protected internal helper to copy a string, ignoring the previous object state.
     409     *
     410     * See copyFrom() above.
     411     *
     412     * This variant converts from a Utf-8 C string.
     413     *
     414     * @param   pcsz            The source string.
     415     *
     416     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     417     *             a NULL string.
     418     */
     419    void copyFrom(const char *pcsz)
     420    {
     421        if (pcsz && *pcsz)
     422        {
     423            // @todo r=dj apparently this was copied twice in the original because our buffers
     424            // use memory from SysAllocMem and IPRT doesn't, but check if this can be made faster
    292425            PRTUTF16 s = NULL;
    293             ::RTStrToUtf16(rs, &s);
    294             raw_copy(ls, (BSTR)s);
     426            ::RTStrToUtf16(pcsz, &s);
     427            copyFrom((BSTR)s);              // @todo r=dj this is not exception safe
    295428            ::RTUtf16Free(s);
    296429        }
    297     }
    298 
    299     BSTR bstr;
    300 
    301     friend class Utf8Str; /* to access our raw_copy() */
     430        else
     431            m_bstr = NULL;
     432    }
     433
     434    BSTR    m_bstr;                     /**< The string buffer. */
    302435};
    303436
    304437/* symmetric compare operators */
    305 inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
    306 inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
    307 inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
    308 inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
     438// inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
     439// inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
     440// inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
     441// inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
    309442
    310443////////////////////////////////////////////////////////////////////////////////
    311444
    312445/**
    313  *  Helper class that represents UTF8 (|char *|) strings. Useful in
    314  *  conjunction with Bstr to simplify conversions between UTF16 (|BSTR|)
    315  *  and UTF8.
    316  *
    317  *  This class uses COM/XPCOM-provided memory management routines to allocate
    318  *  and free string buffers. This makes it possible to:
    319  *  - use it as a type of member variables of COM/XPCOM components and pass
    320  *    their values to callers through component methods' output parameters
    321  *    using the #cloneTo() operation;
    322  *  - adopt (take ownership of) string buffers returned in output parameters
    323  *    of COM methods using the #asOutParam() operation and correctly free them
    324  *    afterwards.
     446 *  String class used universally in Main for Utf-8 strings.
     447 *
     448 *  This is based on iprt::MiniString, to which some functionality has been
     449 *  moved. Here we keep things that are specific to Main, such as conversions
     450 *  with UTF-16 strings (Bstr).
     451 *
     452 *  Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
     453 *  and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
     454 *  behave the same. In both cases, MiniString allocates no memory, reports
     455 *  a zero length and zero allocated bytes for both, and returns an empty
     456 *  C string from c_str().
    325457 */
    326458class Utf8Str : public iprt::MiniString
     
    340472    Utf8Str(const Bstr &that)
    341473    {
    342         copyFrom(that);
     474        copyFrom(that.raw());
    343475    }
    344476
     
    361493
    362494    Utf8Str& operator=(const Bstr &that)
     495    {
     496        cleanup();
     497        copyFrom(that.raw());
     498        return *this;
     499    }
     500
     501    Utf8Str& operator=(CBSTR that)
    363502    {
    364503        cleanup();
     
    367506    }
    368507
    369     Utf8Str& operator=(CBSTR that)
    370     {
    371         cleanup();
    372         copyFrom(that);
    373         return *this;
    374     }
    375 
    376508    /**
    377509     * Intended to assign instances to |char *| out parameters from within the
     
    379511     * caller.
    380512     *
     513     * This allocates a single 0 byte in the target if the member string is empty.
     514     *
    381515     * @remarks The returned string must be freed by RTStrFree, not RTMemFree.
    382516     */
    383517    const Utf8Str& cloneTo(char **pstr) const
    384518    {
    385         if (pstr) /** @todo r=bird: This needs to if m_psz is NULL. Shouldn't it also throw std::bad_alloc? */
    386             *pstr = RTStrDup(m_psz);
    387         return *this;
    388     }
    389 
    390     /**
    391      *  Intended to assign instances to |char *| out parameters from within the
    392      *  interface method. Transfers the ownership of the original string to the
    393      *  caller and resets the instance to null.
    394      *
    395      *  As opposed to cloneTo(), this method doesn't create a copy of the
    396      *  string.
    397      */
    398     Utf8Str& detachTo(char **pstr)
    399     {
    400         *pstr = m_psz;
    401         m_psz = NULL;
    402         m_cbAllocated = 0;
    403         m_cbLength = 0;
     519        if (pstr)
     520        {
     521            *pstr = RTStrDup(raw());
     522#ifdef RT_EXCEPTIONS_ENABLED
     523            if (!*pstr)
     524                throw std::bad_alloc();
     525#endif
     526        }
    404527        return *this;
    405528    }
     
    409532     *  interface method. Transfers the ownership of the duplicated string to the
    410533     *  caller.
     534     *
     535     *  This allocates a single 0 byte in the target if the member string is empty.
    411536     */
    412537    const Utf8Str& cloneTo(BSTR *pstr) const
     
    414539        if (pstr)
    415540        {
     541            Bstr bstr(c_str());
    416542            *pstr = NULL;
    417             Bstr::raw_copy(*pstr, m_psz);
     543            bstr.detachTo(pstr);
    418544        }
    419545        return *this;
     
    507633        if (s)
    508634        {
    509             RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This isn't throwing std::bad_alloc / handling return codes.
    510                                                  * Also, this technically requires using RTStrFree, ministring::cleanup() uses RTMemFree. */
     635            RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This technically requires using RTStrFree, ministring::cleanup() uses RTMemFree. */
     636#ifdef RT_EXCEPTIONS_ENABLED
     637            if (!m_psz)
     638                throw std::bad_alloc();
     639#endif
    511640            m_cbLength = strlen(m_psz);         /** @todo optimize by using a different RTUtf* function */
    512641            m_cbAllocated = m_cbLength + 1;
     
    524653
    525654// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
    526 WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)
    527 
    528 ////////////////////////////////////////////////////////////////////////////////
    529 
    530 // inlined Bstr members that depend on Utf8Str
    531 
    532 inline Bstr::Bstr(const iprt::MiniString &that)
    533     : bstr(NULL)
    534 {
    535     raw_copy(bstr, that.c_str());
    536 }
    537 
    538 inline Bstr::Bstr(const char *that)
    539     : bstr(NULL)
    540 {
    541     raw_copy(bstr, that);
    542 }
    543 
    544 inline Bstr &Bstr::operator=(const Utf8Str &that)
    545 {
    546     setNull();
    547     raw_copy(bstr, that.c_str());
    548     return *this;
    549 }
    550 inline Bstr &Bstr::operator=(const char *that)
    551 {
    552     setNull();
    553     raw_copy(bstr, that);
    554     return *this;
    555 }
    556 
    557 inline const Bstr& Bstr::cloneTo(char **pstr) const
    558 {
    559     if (pstr)
    560     {
    561         Utf8Str ustr(*this);
    562         ustr.detachTo(pstr);
    563     }
    564     return *this;
    565 }
     655// @todo r=dj if I enable this I get about five warnings every time this header
     656// is included, figure out what that is... for now I have modified the calling code instead
     657// WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)
    566658
    567659////////////////////////////////////////////////////////////////////////////////
     
    654746        va_list args;
    655747        va_start(args, aFormat);
    656         raw_copy(bstr, Utf8StrFmtVA(aFormat, args).c_str());
     748        copyFrom(Utf8StrFmtVA(aFormat, args).c_str());
    657749        va_end(args);
    658750    }
     
    675767    BstrFmtVA(const char *aFormat, va_list aArgs)
    676768    {
    677         raw_copy(bstr, Utf8StrFmtVA(aFormat, aArgs).c_str());
     769        copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str());
    678770    }
    679771};
  • trunk/include/iprt/cdefs.h

    r26226 r26587  
    19201920#if defined(_MSC_VER)
    19211921# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls) \
    1922     inline bool operator! (const Cls &that) { return !bool (that); } \
    1923     inline bool operator&& (const Cls &that, bool b) { return bool (that) && b; } \
    1924     inline bool operator|| (const Cls &that, bool b) { return bool (that) || b; } \
    1925     inline bool operator&& (bool b, const Cls &that) { return b && bool (that); } \
    1926     inline bool operator|| (bool b, const Cls &that) { return b || bool (that); }
     1922    inline bool operator! (const Cls &that) { return !bool(that); } \
     1923    inline bool operator&& (const Cls &that, bool b) { return bool(that) && b; } \
     1924    inline bool operator|| (const Cls &that, bool b) { return bool(that) || b; } \
     1925    inline bool operator&& (bool b, const Cls &that) { return b && bool(that); } \
     1926    inline bool operator|| (bool b, const Cls &that) { return b || bool(that); }
    19271927#else
    19281928# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls)
  • trunk/include/iprt/cpp/ministring.h

    r26553 r26587  
    4545 * else except IPRT memory management functions.  Semantics are like in
    4646 * std::string, except it can do a lot less.
     47 *
     48 * Note that MiniString does not differentiate between NULL strings and
     49 * empty strings. In other words, MiniString("") and MiniString(NULL)
     50 * behave the same. In both cases, MiniString allocates no memory, reports
     51 * a zero length and zero allocated bytes for both, and returns an empty
     52 * C string from c_str().
    4753 */
    4854#ifdef VBOX
     
    7177     * Creates a copy of another MiniString.
    7278     *
    73      * This allocates s.length() + 1 bytes for the new instance.
     79     * This allocates s.length() + 1 bytes for the new instance, unless s is empty.
    7480     *
    7581     * @param   s               The source string.
     
    8389
    8490    /**
    85      * Creates a copy of another MiniString.
    86      *
    87      * This allocates strlen(pcsz) + 1 bytes for the new instance.
     91     * Creates a copy of a C string.
     92     *
     93     * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
    8894     *
    8995     * @param   pcsz            The source string.
     
    123129     *
    124130     * Returns the number of bytes allocated in the internal string buffer, which is
    125      * at least length() + 1 if length() > 0.
     131     * at least length() + 1 if length() > 0. Returns 0 for an empty string.
    126132     *
    127133     * @returns m_cbAllocated.
     
    275281     * Returns the byte at the given index, or a null byte if the index is not
    276282     * smaller than length().  This does _not_ count codepoints but simply points
    277      * into the member C string.
     283     * into the member C string; the result may not be a valid UTF-8 character.
    278284     *
    279285     * @param   i       The index into the string buffer.
     
    289295    /**
    290296     * Returns the contained string as a C-style const char* pointer.
     297     * This never returns NULL; if the string is empty, returns a
     298     * pointer to static null byte.
    291299     *
    292300     * @returns const pointer to C-style string.
     
    294302    inline const char *c_str() const
    295303    {
    296         return m_psz;
     304        return (m_psz) ? m_psz : "";
    297305    }
    298306
    299307    /**
    300308     * Like c_str(), for compatibility with lots of VirtualBox Main code.
     309     * This never returns NULL; if the string is empty, returns a
     310     * pointer to static null byte.
    301311     *
    302312     * @returns const pointer to C-style string.
     
    304314    inline const char *raw() const
    305315    {
    306         return m_psz;
    307     }
    308 
    309     /**
    310      * Emptry string or not?
     316        return (m_psz) ? m_psz : "";
     317    }
     318
     319    /**
     320     * Empty string or not?
    311321     *
    312322     * Returns true if the member string has no length.  This states nothing about
     
    472482
    473483    /**
    474      * Hide operator bool() to force people to use isEmpty() explicitly.
    475      */
    476     operator bool() const { return false; }
    477 
    478     /**
    479484     * Destructor implementation, also used to clean up in operator=() before
    480485     * assigning a new string.
     
    492497
    493498    /**
    494      * Protected internal helper for copy a string that completely ignors the
    495      * current object state.
     499     * Protected internal helper to copy a string, ignoring the previous object state.
    496500     *
    497501     * copyFrom() unconditionally sets the members to a copy of the given other
     
    501505     *
    502506     * This variant copies from another MiniString and is fast since
    503      * the length of source string is known.
     507     * the length of the source string is known.
    504508     *
    505509     * @param   s               The source string.
     
    533537
    534538    /**
    535      * Protected internal helper for copy a string that completely ignors the
    536      * current object state.
     539     * Protected internal helper to copy a string, ignoring the previous object state.
    537540     *
    538541     * See copyFrom() above.
     
    572575    }
    573576
     577private:
     578
     579    /**
     580     * Hide operator bool() to force people to use isEmpty() explicitly.
     581     */
     582    operator bool() const;
     583
     584protected:
     585
    574586    char    *m_psz;                     /**< The string buffer. */
    575587    size_t  m_cbLength;                 /**< strlen(m_psz) - i.e. no terminator included. */
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