VirtualBox

Changeset 26550 in vbox for trunk/include/VBox/com


Ignore:
Timestamp:
Feb 15, 2010 5:14:18 PM (15 years ago)
Author:
vboxsync
Message:

Main: Bstr makeover -- 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/VBox/com
Files:
2 edited

Legend:

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

    r26177 r26550  
    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

    r26239 r26550  
    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    /** Case sensitivity selector. */
     211    enum CaseSensitivity
     212    {
     213        CaseSensitive,
     214        CaseInsensitive
     215    };
     216
     217    int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
     218    {
     219        if (m_bstr == str)
     220            return 0;
     221        if (m_bstr == NULL)
     222            return -1;
     223        if (str == NULL)
     224            return 1;
     225
     226        if (cs == CaseSensitive)
     227            return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
     228        else
     229            return ::RTUtf16ICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
     230    }
     231
     232    int compare(const Bstr &bstr, CaseSensitivity cs = CaseSensitive) const
     233    {
     234        return compare(bstr.raw(), cs);
     235    }
     236
     237    /** @name Comparison operators.
     238     * @{  */
     239    bool operator==(const Bstr &that) const { return !compare(that.raw()); }
     240    bool operator!=(const Bstr &that) const { return !!compare(that.raw()); }
     241    bool operator<( const Bstr &that) const { return compare(that.raw()) < 0; }
     242    bool operator>( const Bstr &that) const { return compare(that.raw()) > 0; }
     243
    157244    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 
    173245    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); }
     246    bool operator<( CBSTR that) const { return compare(that) < 0; }
     247    bool operator>( CBSTR that) const { return compare(that) > 0; }
     248
     249    /** @} */
    197250
    198251    /** Intended to to pass instances as |CBSTR| input parameters to methods. */
    199     operator CBSTR() const { return bstr; }
     252    operator CBSTR() const { return raw(); }
    200253
    201254    /**
     
    204257     * input BSTR parameters of interface methods are not const.
    205258     */
    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; }
     259    operator BSTR() { return (BSTR)raw(); }
    222260
    223261    /**
     
    225263     *  within the interface method. Transfers the ownership of the duplicated
    226264     *  string to the caller.
    227      */
    228     const Bstr &cloneTo(BSTR *pstr) const
     265     *
     266     *  This allocates a single 0 byte in the target if the member string is empty.
     267     */
     268    const Bstr& cloneTo(BSTR *pstr) const
    229269    {
    230270        if (pstr)
    231         {
    232             *pstr = NULL;
    233             raw_copy(*pstr, bstr);
    234         }
     271            *pstr = ::SysAllocString((const OLECHAR*)raw());
     272                    // raw() never returns NULL, so we always allocate something here
    235273        return *this;
    236274    }
     
    243281     *  As opposed to cloneTo(), this method doesn't create a copy of the
    244282     *  string.
    245      */
    246     Bstr &detachTo(BSTR *pstr)
    247     {
    248         *pstr = bstr;
    249         bstr = NULL;
     283     *
     284     *  This allocates a single 0 byte in the target if the member string is empty.
     285     */
     286    Bstr& detachTo(BSTR *pstr)
     287    {
     288        *pstr = (m_bstr) ? m_bstr : ::SysAllocString((const OLECHAR*)"");
     289        m_bstr = NULL;
    250290        return *this;
    251291    }
    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;
    259292
    260293    /**
     
    262295     *  Takes the ownership of the returned data.
    263296     */
    264     BSTR *asOutParam() { setNull(); return &bstr; }
     297    BSTR* asOutParam()
     298    {
     299        cleanup();
     300        return &m_bstr;
     301    }
    265302
    266303    /**
     
    271308protected:
    272309
    273     void safe_assign(CBSTR str)
    274     {
    275         if (bstr != str)
     310    /**
     311     * Destructor implementation, also used to clean up in operator=() before
     312     * assigning a new string.
     313     */
     314    void cleanup()
     315    {
     316        if (m_bstr)
    276317        {
    277             setNull();
    278             raw_copy(bstr, str);
     318            ::SysFreeString(m_bstr);
     319            m_bstr = NULL;
    279320        }
    280321    }
    281322
    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)
     323    /**
     324     *  Protected internal helper which allocates memory for a string capable of
     325     *  storing \a aSize - 1 characters (not bytes, not codepoints); in other words,
     326     *  aSize includes the terminating null character.
     327     *
     328     *  Does NOT call cleanup() before allocating!
     329     *
     330     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     331     *             a NULL string.
     332     */
     333    void alloc(size_t cw)
     334    {
     335        if (cw)
    291336        {
     337            m_bstr = ::SysAllocStringLen(NULL, (unsigned int)cw - 1);
     338#ifdef RT_EXCEPTIONS_ENABLED
     339            if (!m_bstr)
     340                throw std::bad_alloc();
     341#endif
     342        }
     343    }
     344
     345    /**
     346     * Protected internal helper to copy a string, ignoring the previous object state.
     347     *
     348     * copyFrom() unconditionally sets the members to a copy of the given other
     349     * strings and makes no assumptions about previous contents. Can therefore be
     350     * used both in copy constructors, when member variables have no defined value,
     351     * and in assignments after having called cleanup().
     352     *
     353     * This variant copies from another Bstr. Since Bstr does _not_ cache string lengths,
     354     * this is not fast.
     355     *
     356     * @param   s               The source string.
     357     *
     358     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     359     *             a NULL string.
     360     */
     361    void copyFrom(const Bstr &s)
     362    {
     363        copyFrom(s.raw());
     364    }
     365
     366    /**
     367     * Protected internal helper to copy a string, ignoring the previous object state.
     368     *
     369     * See copyFrom() above.
     370     *
     371     * This variant copies from a wide char C string.
     372     *
     373     * @param   pcsz            The source string.
     374     *
     375     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     376     *             a NULL string.
     377     */
     378    void copyFrom(CBSTR pw)
     379    {
     380        size_t cwLength;
     381        if (    (pw)
     382             && ((cwLength = ::SysStringLen((BSTR)pw)))
     383           )
     384        {
     385            size_t cwAllocated = cwLength + 1;
     386            alloc(cwAllocated);
     387            memcpy(m_bstr, pw, cwAllocated * sizeof(OLECHAR));     // include 0 terminator
     388        }
     389        else
     390            m_bstr = NULL;
     391    }
     392
     393    /**
     394     * Protected internal helper to copy a string, ignoring the previous object state.
     395     *
     396     * See copyFrom() above.
     397     *
     398     * This variant converts from a Utf-8 C string.
     399     *
     400     * @param   pcsz            The source string.
     401     *
     402     * @throws  std::bad_alloc  On allocation failure. The object is left describing
     403     *             a NULL string.
     404     */
     405    void copyFrom(const char *pcsz)
     406    {
     407        if (pcsz && *pcsz)
     408        {
     409            // @todo r=dj apparently this was copied twice in the original because our buffers
     410            // use memory from SysAllocMem and IPRT doesn't, but check if this can be made faster
    292411            PRTUTF16 s = NULL;
    293             ::RTStrToUtf16(rs, &s);
    294             raw_copy(ls, (BSTR)s);
     412            ::RTStrToUtf16(pcsz, &s);
     413            copyFrom((BSTR)s);              // @todo r=dj this is not exception safe
    295414            ::RTUtf16Free(s);
    296415        }
    297     }
    298 
    299     BSTR bstr;
    300 
    301     friend class Utf8Str; /* to access our raw_copy() */
     416        else
     417            m_bstr = NULL;
     418    }
     419
     420    BSTR    m_bstr;                     /**< The string buffer. */
    302421};
    303422
    304 /* 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); }
    309 
    310423////////////////////////////////////////////////////////////////////////////////
    311424
    312425/**
    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.
     426 *  String class used universally in Main for Utf-8 strings.
     427 *
     428 *  This is based on iprt::MiniString, to which some functionality has been
     429 *  moved. Here we keep things that are specific to Main, such as conversions
     430 *  with UTF-16 strings (Bstr).
     431 *
     432 *  Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
     433 *  and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
     434 *  behave the same. In both cases, MiniString allocates no memory, reports
     435 *  a zero length and zero allocated bytes for both, and returns an empty
     436 *  C string from c_str().
    325437 */
    326438class Utf8Str : public iprt::MiniString
     
    340452    Utf8Str(const Bstr &that)
    341453    {
    342         copyFrom(that);
     454        copyFrom(that.raw());
    343455    }
    344456
     
    361473
    362474    Utf8Str& operator=(const Bstr &that)
     475    {
     476        cleanup();
     477        copyFrom(that.raw());
     478        return *this;
     479    }
     480
     481    Utf8Str& operator=(CBSTR that)
    363482    {
    364483        cleanup();
     
    367486    }
    368487
    369     Utf8Str& operator=(CBSTR that)
    370     {
    371         cleanup();
    372         copyFrom(that);
    373         return *this;
    374     }
    375 
    376488    /**
    377489     * Intended to assign instances to |char *| out parameters from within the
     
    379491     * caller.
    380492     *
     493     * This allocates a single 0 byte in the target if the member string is empty.
     494     *
    381495     * @remarks The returned string must be freed by RTStrFree, not RTMemFree.
    382496     */
    383497    const Utf8Str& cloneTo(char **pstr) const
    384498    {
    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;
     499        if (pstr)
     500        {
     501            *pstr = RTStrDup(raw());
     502#ifdef RT_EXCEPTIONS_ENABLED
     503            if (!*pstr)
     504                throw std::bad_alloc();
     505#endif
     506        }
    404507        return *this;
    405508    }
     
    409512     *  interface method. Transfers the ownership of the duplicated string to the
    410513     *  caller.
     514     *
     515     *  This allocates a single 0 byte in the target if the member string is empty.
    411516     */
    412517    const Utf8Str& cloneTo(BSTR *pstr) const
     
    414519        if (pstr)
    415520        {
     521            Bstr bstr(c_str());
    416522            *pstr = NULL;
    417             Bstr::raw_copy(*pstr, m_psz);
     523            bstr.detachTo(pstr);
    418524        }
    419525        return *this;
     
    507613        if (s)
    508614        {
    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. */
     615            RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This technically requires using RTStrFree, ministring::cleanup() uses RTMemFree. */
     616#ifdef RT_EXCEPTIONS_ENABLED
     617            if (!m_psz)
     618                throw std::bad_alloc();
     619#endif
    511620            m_cbLength = strlen(m_psz);         /** @todo optimize by using a different RTUtf* function */
    512621            m_cbAllocated = m_cbLength + 1;
     
    525634// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
    526635WORKAROUND_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 }
    566636
    567637////////////////////////////////////////////////////////////////////////////////
     
    654724        va_list args;
    655725        va_start(args, aFormat);
    656         raw_copy(bstr, Utf8StrFmtVA(aFormat, args).c_str());
     726        copyFrom(Utf8StrFmtVA(aFormat, args).c_str());
    657727        va_end(args);
    658728    }
     
    675745    BstrFmtVA(const char *aFormat, va_list aArgs)
    676746    {
    677         raw_copy(bstr, Utf8StrFmtVA(aFormat, aArgs).c_str());
     747        copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str());
    678748    }
    679749};
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