1
/*********************************************************
2
* Copyright (C) 2008 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
22
* A string wrapper for _bstr_t. _bstr_t assumes all char* strings use
23
* the local MBCS encoding, but we want to require that char* strings be
24
* interpreted as UTF-8.
28
#error This file should be built on Windows only.
35
#include <glibmm/refptr.h>
43
#ifdef I_LOVE_BSTR_T_CLASSIC
45
typedef _bstr_t ubstr_t;
46
typedef _variant_t uvariant_t;
54
ubstr_t(const char *s);
55
ubstr_t(const wchar_t *s);
56
ubstr_t(const _variant_t& var);
57
ubstr_t(BSTR bstr, bool copy);
58
ubstr_t(const ubstr_t& s);
60
ubstr_t& operator=(ubstr_t copy);
61
ubstr_t& operator=(const char *s);
62
ubstr_t& operator=(const wchar_t *s);
63
ubstr_t& operator=(const _variant_t& var);
65
// Wrappers around standard _bstr_t methods.
67
BSTR copy(bool copy = true) const;
75
unsigned int length() const;
77
ubstr_t& operator+=(const ubstr_t& s);
78
ubstr_t operator+(const ubstr_t& s) const;
79
ubstr_t operator+(const char *s) const;
80
ubstr_t operator+(const wchar_t *s) const;
82
bool operator!() const;
83
bool operator==(const ubstr_t& s) const;
84
bool operator!=(const ubstr_t& s) const;
85
bool operator<(const ubstr_t& s) const;
86
bool operator>(const ubstr_t& s) const;
87
bool operator<=(const ubstr_t& s) const;
88
bool operator>=(const ubstr_t& s) const;
90
operator const wchar_t*() const;
91
operator wchar_t*() const; // XXX: Get rid of this.
92
operator const char*() const;
93
#ifndef I_HATE_NON_CONST_BSTR_T_CASTS
94
operator char*() const; // XXX: Get rid of this.
98
* _variant_t is implicitly constructible from a _bstr_t. Since we can't
99
* add a constructor to _variant_t, instead provide an implicit conversion
100
* from ubstr_t to _variant_t.
102
operator _variant_t() const;
104
void swap(ubstr_t& s);
110
// Takes ownership of the input string.
111
UTF8Data(char *utf8String = NULL) // IN/OUT: May be NULL
112
: mUTF8String(utf8String),
127
if (mRefCount == 0) {
132
// Takes ownership of the input string.
133
void Set(char *utf8String) // IN/OUT: May be NULL.
136
mUTF8String = utf8String;
145
// Only destructible via unreference().
152
unsigned int mRefCount;
155
// Intentionally unimplemented.
156
UTF8Data(const UTF8Data&);
157
UTF8Data& operator=(const UTF8Data&);
160
char *GetUTF8Cache() const;
161
void InvalidateCache();
164
* Anything that mutates mBstr (all non-const methods) must call
169
// mUTF8 is allocated and initialized lazily.
170
mutable Glib::RefPtr<UTF8Data> mUTF8;
175
* _variant_t does string conversions too, so we also need to wrap that.
176
* Since _variant_t doesn't keep a cached version of the locally-encoded
177
* MBCS string and since we don't use _variant_t nearly as much as _bstr_t,
178
* substitutability isn't as much of a concern, so we can use inheritance.
185
* Wrappers around standard _variant_t constructors. Unfortunately we
186
* have to wrap all the constructors since they aren't inherited.
188
uvariant_t() : _variant_t() { }
189
uvariant_t(const VARIANT& var) : _variant_t(var) { }
190
uvariant_t(const VARIANT *var) : _variant_t(var) { }
191
uvariant_t(const _variant_t& var) : _variant_t(var) { }
192
uvariant_t(VARIANT& var, bool copy) : _variant_t(var, copy) { }
193
uvariant_t(short i, VARTYPE vt = VT_I2) : _variant_t(i, vt) { }
194
uvariant_t(long i, VARTYPE vt = VT_I4) : _variant_t(i, vt) { }
195
uvariant_t(float f) : _variant_t(f) { }
196
uvariant_t(double d, VARTYPE vt = VT_R8) : _variant_t(d, vt) { }
197
uvariant_t(const CY& cy) : _variant_t(cy) { }
198
uvariant_t(const _bstr_t& s) : _variant_t(s) { }
199
uvariant_t(const wchar_t *s) : _variant_t(s) { }
200
uvariant_t(IDispatch *dispatch, bool addRef = true) : _variant_t(dispatch, addRef) { }
201
uvariant_t(bool b) : _variant_t(b) { }
202
uvariant_t(IUnknown *unknown, bool addRef = true) : _variant_t(unknown, addRef) { }
203
uvariant_t(const DECIMAL& dec) : _variant_t(dec) { }
204
uvariant_t(BYTE i) : _variant_t(i) { }
205
uvariant_t(char c) : _variant_t(c) { }
206
uvariant_t(unsigned short i) : _variant_t(i) { }
207
uvariant_t(unsigned long i) : _variant_t(i) { }
208
uvariant_t(int i) : _variant_t(i) { }
209
uvariant_t(unsigned int i) : _variant_t(i) { }
210
#if _WIN32_WINNT >= 0x0501
211
uvariant_t(__int64 i) : _variant_t(i) { }
212
uvariant_t(unsigned __int64 i) : _variant_t(i) { }
215
// Override the _variant_t constructor that assumes locally-encoded strings.
216
uvariant_t(const char *s) : _variant_t(ubstr_t(s)) { }
218
// Provide conversion from our ubstr_t wrapper.
219
uvariant_t(const ubstr_t& s) : _variant_t(s) { }
224
*-----------------------------------------------------------------------------
226
* ubstr_t::ubstr_t --
228
* ubstr_t constructors.
236
*-----------------------------------------------------------------------------
248
ubstr_t::ubstr_t(const char *s) // IN: A UTF-8-encoded string.
253
// Since we already have the UTF-8 version of the string, cache it now.
254
mUTF8 = Glib::RefPtr<UTF8Data>(new UTF8Data(Util_SafeStrdup(s)));
255
utf16_t *utf16Str = Unicode_GetAllocUTF16(s);
268
ubstr_t::ubstr_t(const wchar_t *s) // IN
276
ubstr_t::ubstr_t(const _variant_t& var) // IN
284
ubstr_t::ubstr_t(BSTR bstr, // IN
293
ubstr_t::ubstr_t(const ubstr_t& s) // IN
297
if (static_cast<wchar_t *>(mBstr) != NULL && !mUTF8) {
298
mUTF8 = s.mUTF8 = Glib::RefPtr<UTF8Data>(new UTF8Data());
304
*-----------------------------------------------------------------------------
306
* ubstr_t::operator= --
308
* ubstr_t assignment operators.
316
*-----------------------------------------------------------------------------
320
ubstr_t::operator=(ubstr_t copy) // IN
328
ubstr_t::operator=(const char *s) // IN: A UTF-8-encoded string.
330
return operator=(ubstr_t(s));
335
ubstr_t::operator=(const wchar_t *s) // IN
337
return operator=(ubstr_t(s));
342
ubstr_t::operator=(const _variant_t& var) // IN
344
return operator=(ubstr_t(var));
350
*-----------------------------------------------------------------------------
354
* Wrapper around _bstr_t::Assign.
362
*-----------------------------------------------------------------------------
366
ubstr_t::Assign(BSTR s) // IN
374
*-----------------------------------------------------------------------------
378
* Wrapper around _bstr_t::copy.
381
* A copy of the underlying BSTR.
386
*-----------------------------------------------------------------------------
390
ubstr_t::copy(bool copy) // IN/OPT
393
return mBstr.copy(copy);
398
*-----------------------------------------------------------------------------
402
* Wrapper around _bstr_t::Attach.
408
* Invalidates the UTF-8 cache.
410
*-----------------------------------------------------------------------------
414
ubstr_t::Attach(BSTR s) // IN
422
*-----------------------------------------------------------------------------
426
* Wrapper around _bstr_t::Detach.
429
* The underlying BSTR, which is no longer managed.
432
* Invalidates the UTF-8 cache.
434
*-----------------------------------------------------------------------------
441
return mBstr.Detach();
446
*-----------------------------------------------------------------------------
448
* ubstr_t::GetAddress --
450
* Wrapper around _bstr_t::GetAddress.
453
* A pointer to the underlying BSTR.
456
* Invalidates the UTF-8 cache.
458
*-----------------------------------------------------------------------------
462
ubstr_t::GetAddress()
465
* We don't know if the underlying BSTR will be modified via the returned
466
* pointer. We can only assume it will.
469
return mBstr.GetAddress();
474
*-----------------------------------------------------------------------------
476
* ubstr_t::GetBSTR --
478
* Wrapper around _bstr_t::GetBSTR.
481
* A reference to the underlying BSTR.
484
* Invalidates the UTF-8 cache.
486
*-----------------------------------------------------------------------------
493
* We don't know if the underlying BSTR will be modified via the returned
494
* reference. We can only assume it will.
497
return mBstr.GetBSTR();
502
*-----------------------------------------------------------------------------
506
* Wrapper around _bstr_t::length.
509
* The length of the string, in TCHARs.
514
*-----------------------------------------------------------------------------
521
return mBstr.length();
526
*-----------------------------------------------------------------------------
528
* ubstr_t::operator+= --
530
* Mutating concatenation operator.
533
* A reference to this ubstr_t object.
536
* Invalidates the UTF-8 cache.
538
*-----------------------------------------------------------------------------
542
ubstr_t::operator+=(const ubstr_t& s) // IN
551
*-----------------------------------------------------------------------------
553
* ubstr_t::operator+ --
555
* Concatenation operators.
558
* A copy of the concatenated string.
563
*-----------------------------------------------------------------------------
567
ubstr_t::operator+(const ubstr_t& s) // IN
577
ubstr_t::operator+(const char *s) // IN
580
return operator+(ubstr_t(s));
585
ubstr_t::operator+(const wchar_t *s) // IN
588
return operator+(ubstr_t(s));
593
*-----------------------------------------------------------------------------
595
* ubstr_t::operator! --
597
* Wrapper around _bstr_t::operator!.
600
* true if the underlying _bstr_t is NULL, false otherwise.
605
*-----------------------------------------------------------------------------
617
*-----------------------------------------------------------------------------
619
* ubstr_t::operator== --
620
* ubstr_t::operator!= --
621
* ubstr_t::operator< --
622
* ubstr_t::operator> --
623
* ubstr_t::operator<= --
624
* ubstr_t::operator>= --
626
* Wrappers around _bstr_t's comparison operators.
629
* true if the comparisons are hold, false otherwise.
634
*-----------------------------------------------------------------------------
638
ubstr_t::operator==(const ubstr_t& s) // IN
641
return mBstr == s.mBstr;
646
ubstr_t::operator!=(const ubstr_t& s) // IN
649
return mBstr != s.mBstr;
654
ubstr_t::operator<(const ubstr_t& s) // IN
657
return mBstr < s.mBstr;
662
ubstr_t::operator>(const ubstr_t& s) // IN
665
return mBstr > s.mBstr;
670
ubstr_t::operator<=(const ubstr_t& s) // IN
673
return mBstr <= s.mBstr;
678
ubstr_t::operator>=(const ubstr_t& s) // IN
681
return mBstr >= s.mBstr;
686
*-----------------------------------------------------------------------------
688
* ubstr_t::operator const wchar_t* --
689
* ubstr_t::operator wchar_t* --
691
* Wrappers around _bstr_t's cast operators.
694
* A pointer to the underlying UTF-16 string.
699
*-----------------------------------------------------------------------------
703
ubstr_t::operator const wchar_t*()
706
return static_cast<const wchar_t *>(mBstr);
711
ubstr_t::operator wchar_t*()
714
return static_cast<wchar_t *>(mBstr);
719
*-----------------------------------------------------------------------------
721
* ubstr_t::operator const char_t* --
722
* ubstr_t::operator char_t* --
724
* Cast operators to UTF-8 strings.
727
* A pointer to a UTF-8 string.
730
* Might initializes the UTF-8 cache.
732
*-----------------------------------------------------------------------------
736
ubstr_t::operator const char*()
739
return GetUTF8Cache();
743
#ifndef I_HATE_NON_CONST_BSTR_T_CASTS
745
ubstr_t::operator char*()
748
return GetUTF8Cache();
754
*-----------------------------------------------------------------------------
756
* ubstr_t::operator _variant_t --
758
* Cast operator to _variant_t.
761
* A _variant_t equivalent to this ubstr_t object.
766
*-----------------------------------------------------------------------------
770
ubstr_t::operator _variant_t()
773
return static_cast<const wchar_t *>(mBstr);
778
*-----------------------------------------------------------------------------
782
* Swaps this ubstr_t object with another.
790
*-----------------------------------------------------------------------------
794
ubstr_t::swap(ubstr_t& s) // IN/OUT
796
std::swap(mBstr, s.mBstr);
802
*-----------------------------------------------------------------------------
804
* ubstr_t::GetUTF8Cache --
806
* Retrieves the UTF-8 cache, initializing it if necessary.
809
* The cached UTF-8 string.
814
*-----------------------------------------------------------------------------
818
ubstr_t::GetUTF8Cache()
821
if (static_cast<wchar_t *>(mBstr) == NULL) {
826
char *utf8Str = NULL;
829
mUTF8 = Glib::RefPtr<UTF8Data>(new UTF8Data());
832
if (mUTF8->Get() == NULL) {
833
utf8Str = Unicode_AllocWithUTF16(static_cast<wchar_t *>(mBstr));
846
*-----------------------------------------------------------------------------
848
* ubstr_t::InvalidateCache --
850
* Clears the UTF-8 cache.
858
*-----------------------------------------------------------------------------
862
ubstr_t::InvalidateCache()
869
*-----------------------------------------------------------------------------
873
* Non-member concatenation operators.
876
* A copy of the concatenated string.
881
*-----------------------------------------------------------------------------
885
operator+(const char *s1, // IN: A UTF-8-encoded sting.
886
const ubstr_t& s2) // IN
888
return ubstr_t(s1) + s2;
893
operator+(const wchar_t *s1, // IN
894
const ubstr_t& s2) // IN
896
return ubstr_t(s1) + s2;
901
* These are not part of the _bstr_t interface but are provided to catch
902
* misuse. They are intentionally unimplemented to avoid a maintenance
903
* burden, and they intentionally return nothing so that accidental usage
904
* normally results in compile-time errors instead of link-time ones.
907
void operator==(const char *s1, const ubstr_t& s2);
908
void operator!=(const char *s1, const ubstr_t& s2);
909
void operator<(const char *s1, const ubstr_t& s2);
910
void operator>(const char *s1, const ubstr_t& s2);
911
void operator<=(const char *s1, const ubstr_t& s2);
912
void operator>=(const char *s1, const ubstr_t& s2);
914
void operator==(const WCHAR *s1, const ubstr_t& s2);
915
void operator!=(const WCHAR *s1, const ubstr_t& s2);
916
void operator<(const WCHAR *s1, const ubstr_t& s2);
917
void operator>(const WCHAR *s1, const ubstr_t& s2);
918
void operator<=(const WCHAR *s1, const ubstr_t& s2);
919
void operator>=(const WCHAR *s1, const ubstr_t& s2);
922
#endif // I_LOVE_BSTR_T_CLASSIC