VirtualBox

Changeset 26553 in vbox for trunk/include/VBox


Ignore:
Timestamp:
Feb 15, 2010 5:34:29 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
57732
Message:

Main: backing out r57728 + r57730 which burn on windows

Location:
trunk/include/VBox/com
Files:
2 edited

Legend:

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

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

    r26552 r26553  
    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     /** 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 
     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); }
    244157    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
    245173    bool operator!=(CBSTR that) const { return !!compare(that); }
    246     bool operator<( CBSTR that) const { return compare(that) < 0; }
    247     bool operator>( CBSTR that) const { return compare(that) > 0; }
    248 
    249     /** @} */
     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); }
    250197
    251198    /** Intended to to pass instances as |CBSTR| input parameters to methods. */
    252     operator CBSTR() const { return raw(); }
     199    operator CBSTR() const { return bstr; }
    253200
    254201    /**
     
    257204     * input BSTR parameters of interface methods are not const.
    258205     */
    259     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; }
    260222
    261223    /**
     
    263225     *  within the interface method. Transfers the ownership of the duplicated
    264226     *  string to the caller.
    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
     227     */
     228    const Bstr &cloneTo(BSTR *pstr) const
    269229    {
    270230        if (pstr)
    271             *pstr = ::SysAllocString((const OLECHAR*)raw());
    272                     // raw() never returns NULL, so we always allocate something here
     231        {
     232            *pstr = NULL;
     233            raw_copy(*pstr, bstr);
     234        }
    273235        return *this;
    274236    }
     
    281243     *  As opposed to cloneTo(), this method doesn't create a copy of the
    282244     *  string.
    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;
    290         return *this;
    291     }
     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;
    292259
    293260    /**
     
    295262     *  Takes the ownership of the returned data.
    296263     */
    297     BSTR* asOutParam()
    298     {
    299         cleanup();
    300         return &m_bstr;
    301     }
     264    BSTR *asOutParam() { setNull(); return &bstr; }
    302265
    303266    /**
     
    308271protected:
    309272
    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)
    317         {
    318             ::SysFreeString(m_bstr);
    319             m_bstr = NULL;
    320         }
    321     }
    322 
    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)
    336         {
    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
     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        {
    411292            PRTUTF16 s = NULL;
    412             ::RTStrToUtf16(pcsz, &s);
    413             copyFrom((BSTR)s);              // @todo r=dj this is not exception safe
     293            ::RTStrToUtf16(rs, &s);
     294            raw_copy(ls, (BSTR)s);
    414295            ::RTUtf16Free(s);
    415296        }
    416         else
    417             m_bstr = NULL;
    418     }
    419 
    420     BSTR    m_bstr;                     /**< The string buffer. */
     297    }
     298
     299    BSTR bstr;
     300
     301    friend class Utf8Str; /* to access our raw_copy() */
    421302};
    422303
     
    430311
    431312/**
    432  *  String class used universally in Main for Utf-8 strings.
    433  *
    434  *  This is based on iprt::MiniString, to which some functionality has been
    435  *  moved. Here we keep things that are specific to Main, such as conversions
    436  *  with UTF-16 strings (Bstr).
    437  *
    438  *  Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
    439  *  and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
    440  *  behave the same. In both cases, MiniString allocates no memory, reports
    441  *  a zero length and zero allocated bytes for both, and returns an empty
    442  *  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.
    443325 */
    444326class Utf8Str : public iprt::MiniString
     
    458340    Utf8Str(const Bstr &that)
    459341    {
    460         copyFrom(that.raw());
     342        copyFrom(that);
    461343    }
    462344
     
    481363    {
    482364        cleanup();
    483         copyFrom(that.raw());
     365        copyFrom(that);
    484366        return *this;
    485367    }
     
    497379     * caller.
    498380     *
    499      * This allocates a single 0 byte in the target if the member string is empty.
    500      *
    501381     * @remarks The returned string must be freed by RTStrFree, not RTMemFree.
    502382     */
    503383    const Utf8Str& cloneTo(char **pstr) const
    504384    {
    505         if (pstr)
    506         {
    507             *pstr = RTStrDup(raw());
    508 #ifdef RT_EXCEPTIONS_ENABLED
    509             if (!*pstr)
    510                 throw std::bad_alloc();
    511 #endif
    512         }
     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;
    513404        return *this;
    514405    }
     
    518409     *  interface method. Transfers the ownership of the duplicated string to the
    519410     *  caller.
    520      *
    521      *  This allocates a single 0 byte in the target if the member string is empty.
    522411     */
    523412    const Utf8Str& cloneTo(BSTR *pstr) const
     
    525414        if (pstr)
    526415        {
    527             Bstr bstr(c_str());
    528416            *pstr = NULL;
    529             bstr.detachTo(pstr);
     417            Bstr::raw_copy(*pstr, m_psz);
    530418        }
    531419        return *this;
     
    619507        if (s)
    620508        {
    621             RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This technically requires using RTStrFree, ministring::cleanup() uses RTMemFree. */
    622 #ifdef RT_EXCEPTIONS_ENABLED
    623             if (!m_psz)
    624                 throw std::bad_alloc();
    625 #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. */
    626511            m_cbLength = strlen(m_psz);         /** @todo optimize by using a different RTUtf* function */
    627512            m_cbAllocated = m_cbLength + 1;
     
    640525// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
    641526WORKAROUND_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}
    642566
    643567////////////////////////////////////////////////////////////////////////////////
     
    730654        va_list args;
    731655        va_start(args, aFormat);
    732         copyFrom(Utf8StrFmtVA(aFormat, args).c_str());
     656        raw_copy(bstr, Utf8StrFmtVA(aFormat, args).c_str());
    733657        va_end(args);
    734658    }
     
    751675    BstrFmtVA(const char *aFormat, va_list aArgs)
    752676    {
    753         copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str());
     677        raw_copy(bstr, Utf8StrFmtVA(aFormat, aArgs).c_str());
    754678    }
    755679};
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