VirtualBox

Changeset 26603 in vbox for trunk/include


Ignore:
Timestamp:
Feb 17, 2010 12:24:34 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
57796
Message:

Main: back out r57775

Location:
trunk/include
Files:
4 edited

Legend:

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

    r26587 r26603  
    9797    {
    9898        ::RTUuidClear (&uuid);
    99         if (!that.isEmpty())
     99        if (!that.isNull())
    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

    r26587 r26603  
    33/** @file
    44 * MS COM / XPCOM Abstraction Layer:
    5  * UTF-8 and UTF-16 string classes
     5 * Smart string classes declaration
    66 */
    77
     
    5959
    6060/**
    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().
     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.
    8972 */
    9073class Bstr
     
    9275public:
    9376
    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     }
     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); }
    12984
    13085#if defined (VBOX_WITH_XPCOM)
    131     Bstr(const wchar_t *pw)
     86    Bstr(const wchar_t *that) : bstr(NULL)
    13287    {
    13388        AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
    134         copyFrom((CBSTR)pw);
     89        raw_copy(bstr, (CBSTR)that);
    13590    }
    13691#endif
    13792
    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 
     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); }
    254157    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
    255173    bool operator!=(CBSTR that) const { return !!compare(that); }
    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     /** @} */
     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); }
    264197
    265198    /** Intended to to pass instances as |CBSTR| input parameters to methods. */
    266     operator CBSTR() const { return raw(); }
     199    operator CBSTR() const { return bstr; }
    267200
    268201    /**
     
    271204     * input BSTR parameters of interface methods are not const.
    272205     */
    273     operator BSTR() { return (BSTR)raw(); }
     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; }
    274222
    275223    /**
     
    277225     *  within the interface method. Transfers the ownership of the duplicated
    278226     *  string to the caller.
    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
     227     */
     228    const Bstr &cloneTo(BSTR *pstr) const
    283229    {
    284230        if (pstr)
    285             *pstr = ::SysAllocString((const OLECHAR*)raw());
    286                     // raw() never returns NULL, so we always allocate something here
     231        {
     232            *pstr = NULL;
     233            raw_copy(*pstr, bstr);
     234        }
    287235        return *this;
    288236    }
     
    295243     *  As opposed to cloneTo(), this method doesn't create a copy of the
    296244     *  string.
    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;
    304         return *this;
    305     }
     245     */
     246    Bstr &detachTo(BSTR *pstr)
     247    {
     248        *pstr = bstr;
     249        bstr = NULL;
     250        return *this;
     251    }
     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;
    306259
    307260    /**
     
    309262     *  Takes the ownership of the returned data.
    310263     */
    311     BSTR* asOutParam()
    312     {
    313         cleanup();
    314         return &m_bstr;
    315     }
     264    BSTR *asOutParam() { setNull(); return &bstr; }
    316265
    317266    /**
     
    322271protected:
    323272
    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)
    331         {
    332             ::SysFreeString(m_bstr);
    333             m_bstr = NULL;
    334         }
    335     }
    336 
    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)
    350         {
    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
     273    void safe_assign(CBSTR str)
     274    {
     275        if (bstr != str)
     276        {
     277            setNull();
     278            raw_copy(bstr, str);
     279        }
     280    }
     281
     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)
     291        {
    425292            PRTUTF16 s = NULL;
    426             ::RTStrToUtf16(pcsz, &s);
    427             copyFrom((BSTR)s);              // @todo r=dj this is not exception safe
     293            ::RTStrToUtf16(rs, &s);
     294            raw_copy(ls, (BSTR)s);
    428295            ::RTUtf16Free(s);
    429296        }
    430         else
    431             m_bstr = NULL;
    432     }
    433 
    434     BSTR    m_bstr;                     /**< The string buffer. */
     297    }
     298
     299    BSTR bstr;
     300
     301    friend class Utf8Str; /* to access our raw_copy() */
    435302};
    436303
    437304/* symmetric compare operators */
    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); }
     305inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
     306inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
     307inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
     308inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
    442309
    443310////////////////////////////////////////////////////////////////////////////////
    444311
    445312/**
    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().
     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.
    457325 */
    458326class Utf8Str : public iprt::MiniString
     
    472340    Utf8Str(const Bstr &that)
    473341    {
    474         copyFrom(that.raw());
     342        copyFrom(that);
    475343    }
    476344
     
    495363    {
    496364        cleanup();
    497         copyFrom(that.raw());
     365        copyFrom(that);
    498366        return *this;
    499367    }
     
    511379     * caller.
    512380     *
    513      * This allocates a single 0 byte in the target if the member string is empty.
    514      *
    515381     * @remarks The returned string must be freed by RTStrFree, not RTMemFree.
    516382     */
    517383    const Utf8Str& cloneTo(char **pstr) const
    518384    {
    519         if (pstr)
    520         {
    521             *pstr = RTStrDup(raw());
    522 #ifdef RT_EXCEPTIONS_ENABLED
    523             if (!*pstr)
    524                 throw std::bad_alloc();
    525 #endif
    526         }
     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;
    527404        return *this;
    528405    }
     
    532409     *  interface method. Transfers the ownership of the duplicated string to the
    533410     *  caller.
    534      *
    535      *  This allocates a single 0 byte in the target if the member string is empty.
    536411     */
    537412    const Utf8Str& cloneTo(BSTR *pstr) const
     
    539414        if (pstr)
    540415        {
    541             Bstr bstr(c_str());
    542416            *pstr = NULL;
    543             bstr.detachTo(pstr);
     417            Bstr::raw_copy(*pstr, m_psz);
    544418        }
    545419        return *this;
     
    633507        if (s)
    634508        {
    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
     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. */
    640511            m_cbLength = strlen(m_psz);         /** @todo optimize by using a different RTUtf* function */
    641512            m_cbAllocated = m_cbLength + 1;
     
    653524
    654525// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
    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)
     526WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)
     527
     528////////////////////////////////////////////////////////////////////////////////
     529
     530// inlined Bstr members that depend on Utf8Str
     531
     532inline Bstr::Bstr(const iprt::MiniString &that)
     533    : bstr(NULL)
     534{
     535    raw_copy(bstr, that.c_str());
     536}
     537
     538inline Bstr::Bstr(const char *that)
     539    : bstr(NULL)
     540{
     541    raw_copy(bstr, that);
     542}
     543
     544inline Bstr &Bstr::operator=(const Utf8Str &that)
     545{
     546    setNull();
     547    raw_copy(bstr, that.c_str());
     548    return *this;
     549}
     550inline Bstr &Bstr::operator=(const char *that)
     551{
     552    setNull();
     553    raw_copy(bstr, that);
     554    return *this;
     555}
     556
     557inline 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}
    658566
    659567////////////////////////////////////////////////////////////////////////////////
     
    746654        va_list args;
    747655        va_start(args, aFormat);
    748         copyFrom(Utf8StrFmtVA(aFormat, args).c_str());
     656        raw_copy(bstr, Utf8StrFmtVA(aFormat, args).c_str());
    749657        va_end(args);
    750658    }
     
    767675    BstrFmtVA(const char *aFormat, va_list aArgs)
    768676    {
    769         copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str());
     677        raw_copy(bstr, Utf8StrFmtVA(aFormat, aArgs).c_str());
    770678    }
    771679};
  • trunk/include/iprt/cdefs.h

    r26587 r26603  
    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

    r26587 r26603  
    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().
    5347 */
    5448#ifdef VBOX
     
    7771     * Creates a copy of another MiniString.
    7872     *
    79      * This allocates s.length() + 1 bytes for the new instance, unless s is empty.
     73     * This allocates s.length() + 1 bytes for the new instance.
    8074     *
    8175     * @param   s               The source string.
     
    8983
    9084    /**
    91      * Creates a copy of a C string.
    92      *
    93      * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
     85     * Creates a copy of another MiniString.
     86     *
     87     * This allocates strlen(pcsz) + 1 bytes for the new instance.
    9488     *
    9589     * @param   pcsz            The source string.
     
    129123     *
    130124     * Returns the number of bytes allocated in the internal string buffer, which is
    131      * at least length() + 1 if length() > 0. Returns 0 for an empty string.
     125     * at least length() + 1 if length() > 0.
    132126     *
    133127     * @returns m_cbAllocated.
     
    281275     * Returns the byte at the given index, or a null byte if the index is not
    282276     * smaller than length().  This does _not_ count codepoints but simply points
    283      * into the member C string; the result may not be a valid UTF-8 character.
     277     * into the member C string.
    284278     *
    285279     * @param   i       The index into the string buffer.
     
    295289    /**
    296290     * 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.
    299291     *
    300292     * @returns const pointer to C-style string.
     
    302294    inline const char *c_str() const
    303295    {
    304         return (m_psz) ? m_psz : "";
     296        return m_psz;
    305297    }
    306298
    307299    /**
    308300     * 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.
    311301     *
    312302     * @returns const pointer to C-style string.
     
    314304    inline const char *raw() const
    315305    {
    316         return (m_psz) ? m_psz : "";
    317     }
    318 
    319     /**
    320      * Empty string or not?
     306        return m_psz;
     307    }
     308
     309    /**
     310     * Emptry string or not?
    321311     *
    322312     * Returns true if the member string has no length.  This states nothing about
     
    482472
    483473    /**
     474     * Hide operator bool() to force people to use isEmpty() explicitly.
     475     */
     476    operator bool() const { return false; }
     477
     478    /**
    484479     * Destructor implementation, also used to clean up in operator=() before
    485480     * assigning a new string.
     
    497492
    498493    /**
    499      * Protected internal helper to copy a string, ignoring the previous object state.
     494     * Protected internal helper for copy a string that completely ignors the
     495     * current object state.
    500496     *
    501497     * copyFrom() unconditionally sets the members to a copy of the given other
     
    505501     *
    506502     * This variant copies from another MiniString and is fast since
    507      * the length of the source string is known.
     503     * the length of source string is known.
    508504     *
    509505     * @param   s               The source string.
     
    537533
    538534    /**
    539      * Protected internal helper to copy a string, ignoring the previous object state.
     535     * Protected internal helper for copy a string that completely ignors the
     536     * current object state.
    540537     *
    541538     * See copyFrom() above.
     
    575572    }
    576573
    577 private:
    578 
    579     /**
    580      * Hide operator bool() to force people to use isEmpty() explicitly.
    581      */
    582     operator bool() const;
    583 
    584 protected:
    585 
    586574    char    *m_psz;                     /**< The string buffer. */
    587575    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