~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to services/plugins/dndcp/stringxx/ubstr_t.hh

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********************************************************
 
2
 * Copyright (C) 2008 VMware, Inc. All rights reserved.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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.
 
16
 *
 
17
 *********************************************************/
 
18
 
 
19
/*
 
20
 * ubstr_t.hh --
 
21
 *
 
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.
 
25
 */
 
26
 
 
27
#ifndef _WIN32
 
28
#error This file should be built on Windows only.
 
29
#endif
 
30
 
 
31
#pragma once
 
32
 
 
33
#include <algorithm>
 
34
#include <comutil.h>
 
35
#include <glibmm/refptr.h>
 
36
 
 
37
extern "C" {
 
38
#include "unicode.h"
 
39
#include "util.h"
 
40
}
 
41
 
 
42
 
 
43
#ifdef I_LOVE_BSTR_T_CLASSIC
 
44
 
 
45
typedef _bstr_t ubstr_t;
 
46
typedef _variant_t uvariant_t;
 
47
 
 
48
#else
 
49
 
 
50
class ubstr_t
 
51
{
 
52
public:
 
53
   ubstr_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);
 
59
 
 
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);
 
64
 
 
65
   // Wrappers around standard _bstr_t methods.
 
66
   void Assign(BSTR s);
 
67
   BSTR copy(bool copy = true) const;
 
68
 
 
69
   void Attach(BSTR s);
 
70
   BSTR Detach();
 
71
 
 
72
   BSTR *GetAddress();
 
73
   BSTR& GetBSTR();
 
74
 
 
75
   unsigned int length() const;
 
76
 
 
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;
 
81
 
 
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;
 
89
 
 
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.
 
95
#endif
 
96
 
 
97
   /*
 
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.
 
101
    */
 
102
   operator _variant_t() const;
 
103
 
 
104
   void swap(ubstr_t& s);
 
105
 
 
106
private:
 
107
   class UTF8Data
 
108
   {
 
109
   public:
 
110
      // Takes ownership of the input string.
 
111
      UTF8Data(char *utf8String = NULL) // IN/OUT: May be NULL
 
112
         : mUTF8String(utf8String),
 
113
           mRefCount(1)
 
114
      {
 
115
      }
 
116
 
 
117
      // For Glib::RefPtr.
 
118
      void reference()
 
119
      {
 
120
         ++mRefCount;
 
121
      }
 
122
 
 
123
      // For Glib::RefPtr.
 
124
      void unreference()
 
125
      {
 
126
         --mRefCount;
 
127
         if (mRefCount == 0) {
 
128
            delete this;
 
129
         }
 
130
      }
 
131
 
 
132
      // Takes ownership of the input string.
 
133
      void Set(char *utf8String) // IN/OUT: May be NULL.
 
134
      {
 
135
         free(mUTF8String);
 
136
         mUTF8String = utf8String;
 
137
      }
 
138
 
 
139
      char *Get()
 
140
      {
 
141
         return mUTF8String;
 
142
      }
 
143
 
 
144
   private:
 
145
      // Only destructible via unreference().
 
146
      ~UTF8Data()
 
147
      {
 
148
         free(mUTF8String);
 
149
      }
 
150
 
 
151
      char *mUTF8String;
 
152
      unsigned int mRefCount;
 
153
 
 
154
   private:
 
155
      // Intentionally unimplemented.
 
156
      UTF8Data(const UTF8Data&);
 
157
      UTF8Data& operator=(const UTF8Data&);
 
158
   };
 
159
 
 
160
   char *GetUTF8Cache() const;
 
161
   void InvalidateCache();
 
162
 
 
163
   /*
 
164
    * Anything that mutates mBstr (all non-const methods) must call
 
165
    * InvalidateCache().
 
166
    */
 
167
   _bstr_t mBstr;
 
168
 
 
169
   // mUTF8 is allocated and initialized lazily.
 
170
   mutable Glib::RefPtr<UTF8Data> mUTF8;
 
171
};
 
172
 
 
173
 
 
174
/*
 
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.
 
179
 */
 
180
class uvariant_t
 
181
   : public _variant_t
 
182
{
 
183
public:
 
184
   /*
 
185
    * Wrappers around standard _variant_t constructors.  Unfortunately we
 
186
    * have to wrap all the constructors since they aren't inherited.
 
187
    */
 
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) { }
 
213
#endif
 
214
 
 
215
   // Override the _variant_t constructor that assumes locally-encoded strings.
 
216
   uvariant_t(const char *s) : _variant_t(ubstr_t(s)) { }
 
217
 
 
218
   // Provide conversion from our ubstr_t wrapper.
 
219
   uvariant_t(const ubstr_t& s) : _variant_t(s) { }
 
220
};
 
221
 
 
222
 
 
223
/*
 
224
 *-----------------------------------------------------------------------------
 
225
 *
 
226
 * ubstr_t::ubstr_t --
 
227
 *
 
228
 *      ubstr_t constructors.
 
229
 *
 
230
 * Results:
 
231
 *      None.
 
232
 *
 
233
 * Side effects:
 
234
 *      None.
 
235
 *
 
236
 *-----------------------------------------------------------------------------
 
237
 */
 
238
 
 
239
inline
 
240
ubstr_t::ubstr_t()
 
241
   : mBstr(),
 
242
     mUTF8()
 
243
{
 
244
}
 
245
 
 
246
 
 
247
inline
 
248
ubstr_t::ubstr_t(const char *s) // IN: A UTF-8-encoded string.
 
249
   : mBstr(),
 
250
     mUTF8()
 
251
{
 
252
   if (s != NULL) {
 
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);
 
256
      try {
 
257
         mBstr = utf16Str;
 
258
         free(utf16Str);
 
259
      } catch (...) {
 
260
         free(utf16Str);
 
261
         throw;
 
262
      }
 
263
   }
 
264
}
 
265
 
 
266
 
 
267
inline
 
268
ubstr_t::ubstr_t(const wchar_t *s) // IN
 
269
   : mBstr(s),
 
270
     mUTF8()
 
271
{
 
272
}
 
273
 
 
274
 
 
275
inline
 
276
ubstr_t::ubstr_t(const _variant_t& var) // IN
 
277
   : mBstr(var),
 
278
     mUTF8()
 
279
{
 
280
}
 
281
 
 
282
 
 
283
inline
 
284
ubstr_t::ubstr_t(BSTR bstr, // IN
 
285
                 bool copy) // IN
 
286
   : mBstr(bstr, copy),
 
287
     mUTF8()
 
288
{
 
289
}
 
290
 
 
291
 
 
292
inline
 
293
ubstr_t::ubstr_t(const ubstr_t& s) // IN
 
294
   : mBstr(s.mBstr),
 
295
     mUTF8(s.mUTF8)
 
296
{
 
297
   if (static_cast<wchar_t *>(mBstr) != NULL && !mUTF8) {
 
298
      mUTF8 = s.mUTF8 = Glib::RefPtr<UTF8Data>(new UTF8Data());
 
299
   }
 
300
}
 
301
 
 
302
 
 
303
/*
 
304
 *-----------------------------------------------------------------------------
 
305
 *
 
306
 * ubstr_t::operator= --
 
307
 *
 
308
 *      ubstr_t assignment operators.
 
309
 *
 
310
 * Results:
 
311
 *      None.
 
312
 *
 
313
 * Side effects:
 
314
 *      None.
 
315
 *
 
316
 *-----------------------------------------------------------------------------
 
317
 */
 
318
 
 
319
inline ubstr_t&
 
320
ubstr_t::operator=(ubstr_t copy) // IN
 
321
{
 
322
   swap(copy);
 
323
   return *this;
 
324
}
 
325
 
 
326
 
 
327
inline ubstr_t&
 
328
ubstr_t::operator=(const char *s) // IN: A UTF-8-encoded string.
 
329
{
 
330
   return operator=(ubstr_t(s));
 
331
}
 
332
 
 
333
 
 
334
inline ubstr_t&
 
335
ubstr_t::operator=(const wchar_t *s) // IN
 
336
{
 
337
   return operator=(ubstr_t(s));
 
338
}
 
339
 
 
340
 
 
341
inline ubstr_t&
 
342
ubstr_t::operator=(const _variant_t& var) // IN
 
343
{
 
344
   return operator=(ubstr_t(var));
 
345
}
 
346
 
 
347
 
 
348
 
 
349
/*
 
350
 *-----------------------------------------------------------------------------
 
351
 *
 
352
 * ubstr_t::Assign --
 
353
 *
 
354
 *      Wrapper around _bstr_t::Assign.
 
355
 *
 
356
 * Results:
 
357
 *      None.
 
358
 *
 
359
 * Side effects:
 
360
 *      None.
 
361
 *
 
362
 *-----------------------------------------------------------------------------
 
363
 */
 
364
 
 
365
inline void
 
366
ubstr_t::Assign(BSTR s) // IN
 
367
{
 
368
   InvalidateCache();
 
369
   mBstr.Assign(s);
 
370
}
 
371
 
 
372
 
 
373
/*
 
374
 *-----------------------------------------------------------------------------
 
375
 *
 
376
 * ubstr_t::copy --
 
377
 *
 
378
 *      Wrapper around _bstr_t::copy.
 
379
 *
 
380
 * Results:
 
381
 *      A copy of the underlying BSTR.
 
382
 *
 
383
 * Side effects:
 
384
 *      None.
 
385
 *
 
386
 *-----------------------------------------------------------------------------
 
387
 */
 
388
 
 
389
inline BSTR
 
390
ubstr_t::copy(bool copy) // IN/OPT
 
391
   const
 
392
{
 
393
   return mBstr.copy(copy);
 
394
}
 
395
 
 
396
 
 
397
/*
 
398
 *-----------------------------------------------------------------------------
 
399
 *
 
400
 * ubstr_t::Attach --
 
401
 *
 
402
 *      Wrapper around _bstr_t::Attach.
 
403
 *
 
404
 * Results:
 
405
 *      None.
 
406
 *
 
407
 * Side effects:
 
408
 *      Invalidates the UTF-8 cache.
 
409
 *
 
410
 *-----------------------------------------------------------------------------
 
411
 */
 
412
 
 
413
inline void
 
414
ubstr_t::Attach(BSTR s) // IN
 
415
{
 
416
   InvalidateCache();
 
417
   mBstr.Attach(s);
 
418
}
 
419
 
 
420
 
 
421
/*
 
422
 *-----------------------------------------------------------------------------
 
423
 *
 
424
 * ubstr_t::Detach --
 
425
 *
 
426
 *      Wrapper around _bstr_t::Detach.
 
427
 *
 
428
 * Results:
 
429
 *      The underlying BSTR, which is no longer managed.
 
430
 *
 
431
 * Side effects:
 
432
 *      Invalidates the UTF-8 cache.
 
433
 *
 
434
 *-----------------------------------------------------------------------------
 
435
 */
 
436
 
 
437
inline BSTR
 
438
ubstr_t::Detach()
 
439
{
 
440
   InvalidateCache();
 
441
   return mBstr.Detach();
 
442
}
 
443
 
 
444
 
 
445
/*
 
446
 *-----------------------------------------------------------------------------
 
447
 *
 
448
 * ubstr_t::GetAddress --
 
449
 *
 
450
 *      Wrapper around _bstr_t::GetAddress.
 
451
 *
 
452
 * Results:
 
453
 *      A pointer to the underlying BSTR.
 
454
 *
 
455
 * Side effects:
 
456
 *      Invalidates the UTF-8 cache.
 
457
 *
 
458
 *-----------------------------------------------------------------------------
 
459
 */
 
460
 
 
461
inline BSTR *
 
462
ubstr_t::GetAddress()
 
463
{
 
464
   /*
 
465
    * We don't know if the underlying BSTR will be modified via the returned
 
466
    * pointer.  We can only assume it will.
 
467
    */
 
468
   InvalidateCache();
 
469
   return mBstr.GetAddress();
 
470
}
 
471
 
 
472
 
 
473
/*
 
474
 *-----------------------------------------------------------------------------
 
475
 *
 
476
 * ubstr_t::GetBSTR --
 
477
 *
 
478
 *      Wrapper around _bstr_t::GetBSTR.
 
479
 *
 
480
 * Results:
 
481
 *      A reference to the underlying BSTR.
 
482
 *
 
483
 * Side effects:
 
484
 *      Invalidates the UTF-8 cache.
 
485
 *
 
486
 *-----------------------------------------------------------------------------
 
487
 */
 
488
 
 
489
inline BSTR&
 
490
ubstr_t::GetBSTR()
 
491
{
 
492
   /*
 
493
    * We don't know if the underlying BSTR will be modified via the returned
 
494
    * reference.  We can only assume it will.
 
495
    */
 
496
   InvalidateCache();
 
497
   return mBstr.GetBSTR();
 
498
}
 
499
 
 
500
 
 
501
/*
 
502
 *-----------------------------------------------------------------------------
 
503
 *
 
504
 * ubstr_t::length --
 
505
 *
 
506
 *      Wrapper around _bstr_t::length.
 
507
 *
 
508
 * Results:
 
509
 *      The length of the string, in TCHARs.
 
510
 *
 
511
 * Side effects:
 
512
 *      None.
 
513
 *
 
514
 *-----------------------------------------------------------------------------
 
515
 */
 
516
 
 
517
inline unsigned int
 
518
ubstr_t::length()
 
519
   const
 
520
{
 
521
   return mBstr.length();
 
522
}
 
523
 
 
524
 
 
525
/*
 
526
 *-----------------------------------------------------------------------------
 
527
 *
 
528
 * ubstr_t::operator+= --
 
529
 *
 
530
 *      Mutating concatenation operator.
 
531
 *
 
532
 * Results:
 
533
 *      A reference to this ubstr_t object.
 
534
 *
 
535
 * Side effects:
 
536
 *      Invalidates the UTF-8 cache.
 
537
 *
 
538
 *-----------------------------------------------------------------------------
 
539
 */
 
540
 
 
541
inline ubstr_t&
 
542
ubstr_t::operator+=(const ubstr_t& s) // IN
 
543
{
 
544
   InvalidateCache();
 
545
   mBstr += s.mBstr;
 
546
   return *this;
 
547
}
 
548
 
 
549
 
 
550
/*
 
551
 *-----------------------------------------------------------------------------
 
552
 *
 
553
 * ubstr_t::operator+ --
 
554
 *
 
555
 *      Concatenation operators.
 
556
 *
 
557
 * Results:
 
558
 *      A copy of the concatenated string.
 
559
 *
 
560
 * Side effects:
 
561
 *      None.
 
562
 *
 
563
 *-----------------------------------------------------------------------------
 
564
 */
 
565
 
 
566
inline ubstr_t
 
567
ubstr_t::operator+(const ubstr_t& s) // IN
 
568
   const
 
569
{
 
570
   ubstr_t copy(*this);
 
571
   copy += s;
 
572
   return copy;
 
573
}
 
574
 
 
575
 
 
576
inline ubstr_t
 
577
ubstr_t::operator+(const char *s) // IN
 
578
   const
 
579
{
 
580
   return operator+(ubstr_t(s));
 
581
}
 
582
 
 
583
 
 
584
inline ubstr_t
 
585
ubstr_t::operator+(const wchar_t *s) // IN
 
586
   const
 
587
{
 
588
   return operator+(ubstr_t(s));
 
589
}
 
590
 
 
591
 
 
592
/*
 
593
 *-----------------------------------------------------------------------------
 
594
 *
 
595
 * ubstr_t::operator! --
 
596
 *
 
597
 *      Wrapper around _bstr_t::operator!.
 
598
 *
 
599
 * Results:
 
600
 *      true if the underlying _bstr_t is NULL, false otherwise.
 
601
 *
 
602
 * Side effects:
 
603
 *      None.
 
604
 *
 
605
 *-----------------------------------------------------------------------------
 
606
 */
 
607
 
 
608
inline bool
 
609
ubstr_t::operator!()
 
610
   const
 
611
{
 
612
   return !mBstr;
 
613
}
 
614
 
 
615
 
 
616
/*
 
617
 *-----------------------------------------------------------------------------
 
618
 *
 
619
 * ubstr_t::operator== --
 
620
 * ubstr_t::operator!= --
 
621
 * ubstr_t::operator< --
 
622
 * ubstr_t::operator> --
 
623
 * ubstr_t::operator<= --
 
624
 * ubstr_t::operator>= --
 
625
 *
 
626
 *      Wrappers around _bstr_t's comparison operators.
 
627
 *
 
628
 * Results:
 
629
 *      true if the comparisons are hold, false otherwise.
 
630
 *
 
631
 * Side effects:
 
632
 *      None.
 
633
 *
 
634
 *-----------------------------------------------------------------------------
 
635
 */
 
636
 
 
637
inline bool
 
638
ubstr_t::operator==(const ubstr_t& s) // IN
 
639
   const
 
640
{
 
641
   return mBstr == s.mBstr;
 
642
}
 
643
 
 
644
 
 
645
inline bool
 
646
ubstr_t::operator!=(const ubstr_t& s) // IN
 
647
   const
 
648
{
 
649
   return mBstr != s.mBstr;
 
650
}
 
651
 
 
652
 
 
653
inline bool
 
654
ubstr_t::operator<(const ubstr_t& s) // IN
 
655
   const
 
656
{
 
657
   return mBstr < s.mBstr;
 
658
}
 
659
 
 
660
 
 
661
inline bool
 
662
ubstr_t::operator>(const ubstr_t& s) // IN
 
663
   const
 
664
{
 
665
   return mBstr > s.mBstr;
 
666
}
 
667
 
 
668
 
 
669
inline bool
 
670
ubstr_t::operator<=(const ubstr_t& s) // IN
 
671
   const
 
672
{
 
673
   return mBstr <= s.mBstr;
 
674
}
 
675
 
 
676
 
 
677
inline bool
 
678
ubstr_t::operator>=(const ubstr_t& s) // IN
 
679
   const
 
680
{
 
681
   return mBstr >= s.mBstr;
 
682
}
 
683
 
 
684
 
 
685
/*
 
686
 *-----------------------------------------------------------------------------
 
687
 *
 
688
 * ubstr_t::operator const wchar_t* --
 
689
 * ubstr_t::operator wchar_t* --
 
690
 *
 
691
 *      Wrappers around _bstr_t's cast operators.
 
692
 *
 
693
 * Results:
 
694
 *      A pointer to the underlying UTF-16 string.
 
695
 *
 
696
 * Side effects:
 
697
 *      None.
 
698
 *
 
699
 *-----------------------------------------------------------------------------
 
700
 */
 
701
 
 
702
inline
 
703
ubstr_t::operator const wchar_t*()
 
704
   const
 
705
{
 
706
   return static_cast<const wchar_t *>(mBstr);
 
707
}
 
708
 
 
709
 
 
710
inline
 
711
ubstr_t::operator wchar_t*()
 
712
   const
 
713
{
 
714
   return static_cast<wchar_t *>(mBstr);
 
715
}
 
716
 
 
717
 
 
718
/*
 
719
 *-----------------------------------------------------------------------------
 
720
 *
 
721
 * ubstr_t::operator const char_t* --
 
722
 * ubstr_t::operator char_t* --
 
723
 *
 
724
 *      Cast operators to UTF-8 strings.
 
725
 *
 
726
 * Results:
 
727
 *      A pointer to a UTF-8 string.
 
728
 *
 
729
 * Side effects:
 
730
 *      Might initializes the UTF-8 cache.
 
731
 *
 
732
 *-----------------------------------------------------------------------------
 
733
 */
 
734
 
 
735
inline
 
736
ubstr_t::operator const char*()
 
737
   const
 
738
{
 
739
   return GetUTF8Cache();
 
740
}
 
741
 
 
742
 
 
743
#ifndef I_HATE_NON_CONST_BSTR_T_CASTS
 
744
inline
 
745
ubstr_t::operator char*()
 
746
   const
 
747
{
 
748
   return GetUTF8Cache();
 
749
}
 
750
#endif
 
751
 
 
752
 
 
753
/*
 
754
 *-----------------------------------------------------------------------------
 
755
 *
 
756
 * ubstr_t::operator _variant_t --
 
757
 *
 
758
 *      Cast operator to _variant_t.
 
759
 *
 
760
 * Results:
 
761
 *      A _variant_t equivalent to this ubstr_t object.
 
762
 *
 
763
 * Side effects:
 
764
 *      None.
 
765
 *
 
766
 *-----------------------------------------------------------------------------
 
767
 */
 
768
 
 
769
inline
 
770
ubstr_t::operator _variant_t()
 
771
   const
 
772
{
 
773
   return static_cast<const wchar_t *>(mBstr);
 
774
}
 
775
 
 
776
 
 
777
/*
 
778
 *-----------------------------------------------------------------------------
 
779
 *
 
780
 * ubstr_t::swap --
 
781
 *
 
782
 *      Swaps this ubstr_t object with another.
 
783
 *
 
784
 * Results:
 
785
 *      None.
 
786
 *
 
787
 * Side effects:
 
788
 *      None.
 
789
 *
 
790
 *-----------------------------------------------------------------------------
 
791
 */
 
792
 
 
793
inline void
 
794
ubstr_t::swap(ubstr_t& s) // IN/OUT
 
795
{
 
796
   std::swap(mBstr, s.mBstr);
 
797
   mUTF8.swap(s.mUTF8);
 
798
}
 
799
 
 
800
 
 
801
/*
 
802
 *-----------------------------------------------------------------------------
 
803
 *
 
804
 * ubstr_t::GetUTF8Cache --
 
805
 *
 
806
 *      Retrieves the UTF-8 cache, initializing it if necessary.
 
807
 *
 
808
 * Results:
 
809
 *      The cached UTF-8 string.
 
810
 *
 
811
 * Side effects:
 
812
 *      None.
 
813
 *
 
814
 *-----------------------------------------------------------------------------
 
815
 */
 
816
 
 
817
inline char *
 
818
ubstr_t::GetUTF8Cache()
 
819
   const
 
820
{
 
821
   if (static_cast<wchar_t *>(mBstr) == NULL) {
 
822
      // Nothing to do.
 
823
      return NULL;
 
824
   }
 
825
 
 
826
   char *utf8Str = NULL;
 
827
   try {
 
828
      if (!mUTF8) {
 
829
         mUTF8 = Glib::RefPtr<UTF8Data>(new UTF8Data());
 
830
      }
 
831
 
 
832
      if (mUTF8->Get() == NULL) {
 
833
         utf8Str = Unicode_AllocWithUTF16(static_cast<wchar_t *>(mBstr));
 
834
         mUTF8->Set(utf8Str);
 
835
      }
 
836
   } catch (...) {
 
837
      free(utf8Str);
 
838
      throw;
 
839
   }
 
840
 
 
841
   return mUTF8->Get();
 
842
}
 
843
 
 
844
 
 
845
/*
 
846
 *-----------------------------------------------------------------------------
 
847
 *
 
848
 * ubstr_t::InvalidateCache --
 
849
 *
 
850
 *      Clears the UTF-8 cache.
 
851
 *
 
852
 * Results:
 
853
 *      None.
 
854
 *
 
855
 * Side effects:
 
856
 *      None.
 
857
 *
 
858
 *-----------------------------------------------------------------------------
 
859
 */
 
860
 
 
861
inline void
 
862
ubstr_t::InvalidateCache()
 
863
{
 
864
   mUTF8.clear();
 
865
}
 
866
 
 
867
 
 
868
/*
 
869
 *-----------------------------------------------------------------------------
 
870
 *
 
871
 * operator+ --
 
872
 *
 
873
 *      Non-member concatenation operators.
 
874
 *
 
875
 * Results:
 
876
 *      A copy of the concatenated string.
 
877
 *
 
878
 * Side effects:
 
879
 *      None.
 
880
 *
 
881
 *-----------------------------------------------------------------------------
 
882
 */
 
883
 
 
884
inline ubstr_t
 
885
operator+(const char *s1,    // IN: A UTF-8-encoded sting.
 
886
          const ubstr_t& s2) // IN
 
887
{
 
888
   return ubstr_t(s1) + s2;
 
889
}
 
890
 
 
891
 
 
892
inline ubstr_t
 
893
operator+(const wchar_t *s1, // IN
 
894
          const ubstr_t& s2) // IN
 
895
{
 
896
   return ubstr_t(s1) + s2;
 
897
}
 
898
 
 
899
 
 
900
/*
 
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.
 
905
 */
 
906
 
 
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);
 
913
 
 
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);
 
920
 
 
921
 
 
922
#endif // I_LOVE_BSTR_T_CLASSIC