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

« back to all changes in this revision

Viewing changes to vmware-user/stringxx/string.cc

  • 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
 
 * string.cc --
21
 
 *
22
 
 *     A string wrapper for bora/lib/unicode. This class is intended to provide
23
 
 *     more c++ features such as operator overloading, automatic string conversion
24
 
 *     between different types of string classes.
25
 
 */
26
 
 
27
 
 
28
 
#include <sstream>
29
 
#include <iostream>
30
 
 
31
 
#include "string.hh"
32
 
#include "unicode.h"
33
 
#include "util.h"
34
 
 
35
 
namespace utf {
36
 
 
37
 
/*
38
 
 * Initialize static scope variables,
39
 
 *
40
 
 * Note that with the way this is done, it's important not to delay load glib
41
 
 * libraries. See bug 397373 for more details. If you're getting crazy values
42
 
 * for utf::string::npos, check your linker flags.
43
 
 */
44
 
const string::size_type string::npos = Glib::ustring::npos;
45
 
 
46
 
 
47
 
/*
48
 
 *-----------------------------------------------------------------------------
49
 
 *
50
 
 * utf::string::string --
51
 
 *
52
 
 *      Constructor.
53
 
 *
54
 
 * Results:
55
 
 *      None.
56
 
 *
57
 
 * Side effects:
58
 
 *      None
59
 
 *
60
 
 *-----------------------------------------------------------------------------
61
 
 */
62
 
 
63
 
string::string()
64
 
   : mUstr(),
65
 
     mUtf16Cache(NULL),
66
 
     mUtf16Length(npos)
67
 
{
68
 
}
69
 
 
70
 
 
71
 
/*
72
 
 *-----------------------------------------------------------------------------
73
 
 *
74
 
 * utf::string::string --
75
 
 *
76
 
 *      Constructor.
77
 
 *
78
 
 * Results:
79
 
 *      None.
80
 
 *
81
 
 * Side effects:
82
 
 *      None
83
 
 *
84
 
 *-----------------------------------------------------------------------------
85
 
 */
86
 
 
87
 
string::string(ConstUnicode s) // IN
88
 
   : mUstr(),
89
 
     mUtf16Cache(NULL),
90
 
     mUtf16Length(npos)
91
 
{
92
 
   ASSERT(s);
93
 
   mUstr = Unicode_GetUTF8(s);
94
 
   ASSERT(Validate(mUstr));
95
 
}
96
 
 
97
 
 
98
 
#ifdef _WIN32
99
 
 
100
 
/*
101
 
 *-----------------------------------------------------------------------------
102
 
 *
103
 
 * utf::string::init_bstr_t --
104
 
 *
105
 
 *      Utility function to construct from a _bstr_t object.
106
 
 *      Copies the UTF-16 representation of the _bstr_t.
107
 
 *
108
 
 * Results:
109
 
 *      None.
110
 
 *
111
 
 * Side effects:
112
 
 *      Makes a copy of the _bstr_t data and frees that data when
113
 
 *      the utf::string is destroyed.
114
 
 *
115
 
 * Note:
116
 
 *      WIN32 only call
117
 
 *
118
 
 *-----------------------------------------------------------------------------
119
 
 */
120
 
 
121
 
void
122
 
string::init_bstr_t(const _bstr_t &s) // IN
123
 
{
124
 
   // If the input is empty, then there's nothing to do.
125
 
   if (s.length() == 0) {
126
 
      return;
127
 
   }
128
 
 
129
 
   Unicode utf8 = Unicode_AllocWithUTF16(static_cast<const utf16_t *>(s));
130
 
 
131
 
   try {
132
 
      mUstr = utf8;
133
 
      Unicode_Free(utf8);
134
 
   } catch (...) {
135
 
      Unicode_Free(utf8);
136
 
      throw;
137
 
   }
138
 
 
139
 
   ASSERT(Validate(mUstr));
140
 
}
141
 
 
142
 
 
143
 
/*
144
 
 *-----------------------------------------------------------------------------
145
 
 *
146
 
 * utf::string::string --
147
 
 *
148
 
 *      Constructor from a ubstr_t object.  Copies the UTF-16 representation of
149
 
 *      the ubstr_t.
150
 
 *
151
 
 * Results:
152
 
 *      None.
153
 
 *
154
 
 * Side effects:
155
 
 *      Makes a copy of the ubstr_t data and frees that data when the
156
 
 *      utf::string is destroyed.
157
 
 *
158
 
 * Note:
159
 
 *      WIN32 only call
160
 
 *
161
 
 *-----------------------------------------------------------------------------
162
 
 */
163
 
 
164
 
string::string(const ubstr_t &s) // IN
165
 
   : mUstr(),
166
 
     mUtf16Cache(NULL),
167
 
     mUtf16Length(npos)
168
 
{
169
 
   // If the input is empty, then there's nothing to do.
170
 
   if (s.length() == 0) {
171
 
      return;
172
 
   }
173
 
 
174
 
   mUstr = static_cast<const char *>(s);
175
 
   ASSERT(Validate(mUstr));
176
 
}
177
 
 
178
 
 
179
 
/*
180
 
 *-----------------------------------------------------------------------------
181
 
 *
182
 
 * utf::string::string --
183
 
 *
184
 
 *      Constructor from a _bstr_t object.  Copies the UTF-16 representation of
185
 
 *      the _bstr_t.  Needed for dealing with _com_error::Description().
186
 
 *
187
 
 * Results:
188
 
 *      None.
189
 
 *
190
 
 * Side effects:
191
 
 *      Makes a copy of the _bstr_t data and frees that data when
192
 
 *      the utf::string is destroyed.
193
 
 *
194
 
 * Note:
195
 
 *      WIN32 only call
196
 
 *
197
 
 *-----------------------------------------------------------------------------
198
 
 */
199
 
 
200
 
string::string(const _bstr_t &s) // IN
201
 
   : mUstr(),
202
 
     mUtf16Cache(NULL),
203
 
     mUtf16Length(npos)
204
 
{
205
 
   init_bstr_t(s);
206
 
}
207
 
 
208
 
 
209
 
/*
210
 
 *-----------------------------------------------------------------------------
211
 
 *
212
 
 * utf::string::string --
213
 
 *
214
 
 *      Constructor from a uvariant_t object. Copies the UTF-16 representation
215
 
 *      of the ubstr_t interface.
216
 
 *
217
 
 * Results:
218
 
 *      None.
219
 
 *
220
 
 * Side effects:
221
 
 *      Makes a copy of the uvariant_t data and frees that data when the
222
 
 *      utf::string is destroyed.
223
 
 *
224
 
 * Note:
225
 
 *      WIN32 only call
226
 
 *
227
 
 *-----------------------------------------------------------------------------
228
 
 */
229
 
 
230
 
string::string(const uvariant_t &v) // IN
231
 
   : mUstr(),
232
 
     mUtf16Cache(NULL),
233
 
     mUtf16Length(npos)
234
 
{
235
 
   ubstr_t s;
236
 
 
237
 
   try {
238
 
      s = v;
239
 
   } catch (...) {
240
 
      Warning("Invalid uvariant_t to ubstr_t conversion.\n");
241
 
      throw;
242
 
   }
243
 
 
244
 
   // If the input is empty, then there's nothing to do.
245
 
   if (s.length() == 0) {
246
 
      return;
247
 
   }
248
 
 
249
 
   mUstr = static_cast<const char *>(s);
250
 
   ASSERT(Validate(mUstr));
251
 
}
252
 
 
253
 
 
254
 
/*
255
 
 *-----------------------------------------------------------------------------
256
 
 *
257
 
 * utf::string::string --
258
 
 *
259
 
 *      Constructor from a _variant_t object. Copies the UTF-16 representation
260
 
 *      of the _variant_t.
261
 
 *
262
 
 * Results:
263
 
 *      None.
264
 
 *
265
 
 * Side effects:
266
 
 *      Makes a copy of the _variant_t data and frees that data when
267
 
 *      the utf::string is destroyed.
268
 
 *
269
 
 * Note:
270
 
 *      WIN32 only call
271
 
 *
272
 
 *-----------------------------------------------------------------------------
273
 
 */
274
 
 
275
 
string::string(const _variant_t &v) // IN
276
 
   : mUstr(),
277
 
     mUtf16Cache(NULL),
278
 
     mUtf16Length(npos)
279
 
{
280
 
   _bstr_t s;
281
 
 
282
 
   try {
283
 
      s = v;
284
 
   } catch (...) {
285
 
      Warning("Invalid _variant_t to _bstr_t conversion.\n");
286
 
      throw;
287
 
   }
288
 
 
289
 
   init_bstr_t(s);
290
 
}
291
 
 
292
 
#endif
293
 
 
294
 
 
295
 
/*
296
 
 *-----------------------------------------------------------------------------
297
 
 *
298
 
 * utf::string::string --
299
 
 *
300
 
 *      Constructor.
301
 
 *
302
 
 * Results:
303
 
 *      None.
304
 
 *
305
 
 * Side effects:
306
 
 *      None
307
 
 *
308
 
 *-----------------------------------------------------------------------------
309
 
 */
310
 
 
311
 
string::string(const utf16string &s) // IN
312
 
   : mUstr(),
313
 
     mUtf16Cache(NULL),
314
 
     mUtf16Length(npos)
315
 
{
316
 
   // If the input is empty, then there's nothing to do.
317
 
   if (s.empty()) {
318
 
      return;
319
 
   }
320
 
 
321
 
   string copy(s.c_str());
322
 
   swap(copy);
323
 
}
324
 
 
325
 
 
326
 
/*
327
 
 *-----------------------------------------------------------------------------
328
 
 *
329
 
 * utf::string::string --
330
 
 *
331
 
 *      Constructor.
332
 
 *
333
 
 * Results:
334
 
 *      None.
335
 
 *
336
 
 * Side effects:
337
 
 *      None
338
 
 *
339
 
 *-----------------------------------------------------------------------------
340
 
 */
341
 
 
342
 
string::string(const utf16_t *s) // IN
343
 
   : mUstr(),
344
 
     mUtf16Cache(NULL),
345
 
     mUtf16Length(npos)
346
 
{
347
 
   ASSERT(s != NULL);
348
 
 
349
 
   /*
350
 
    * Since we already have a UTF-16 representation of the string, copy it
351
 
    * now.
352
 
    */
353
 
   mUtf16Cache = Unicode_UTF16Strdup(s);
354
 
 
355
 
   Unicode utf8 = Unicode_AllocWithUTF16(s);
356
 
 
357
 
   try {
358
 
      mUstr = utf8;
359
 
      Unicode_Free(utf8);
360
 
   } catch (...) {
361
 
      Unicode_Free(utf8);
362
 
      throw;
363
 
   }
364
 
 
365
 
   ASSERT(Validate(mUstr));
366
 
}
367
 
 
368
 
 
369
 
/*
370
 
 *-----------------------------------------------------------------------------
371
 
 *
372
 
 * utf::string::string --
373
 
 *
374
 
 *      Constructor.
375
 
 *
376
 
 * Results:
377
 
 *      None.
378
 
 *
379
 
 * Side effects:
380
 
 *      None
381
 
 *
382
 
 *-----------------------------------------------------------------------------
383
 
 */
384
 
 
385
 
string::string(const char *s,           // IN
386
 
               StringEncoding encoding) // IN
387
 
   : mUstr(),
388
 
     mUtf16Cache(NULL),
389
 
     mUtf16Length(npos)
390
 
{
391
 
   ASSERT(s != NULL);
392
 
 
393
 
   Unicode utf8 = Unicode_Alloc(s, encoding);
394
 
 
395
 
   try {
396
 
      mUstr = utf8;
397
 
      Unicode_Free(utf8);
398
 
   } catch (...) {
399
 
      Unicode_Free(utf8);
400
 
      throw;
401
 
   }
402
 
 
403
 
   ASSERT(Validate(mUstr));
404
 
}
405
 
 
406
 
 
407
 
/*
408
 
 *-----------------------------------------------------------------------------
409
 
 *
410
 
 * utf::string::string --
411
 
 *
412
 
 *      Constructor.
413
 
 *
414
 
 *      XXX: When initializing mUstr, we do a deep copy of the string data
415
 
 *      instead of just calling mUstr(s). This is because Glib::ustring is very
416
 
 *      smart about sharing storage, and zero_clear is very dumb. Once we get
417
 
 *      rid of zero_clear and have a separate sensitive-string class, this can
418
 
 *      go back to being simple.
419
 
 *
420
 
 * Results:
421
 
 *      None.
422
 
 *
423
 
 * Side effects:
424
 
 *      None
425
 
 *
426
 
 *-----------------------------------------------------------------------------
427
 
 */
428
 
 
429
 
string::string(const Glib::ustring &s)    // IN
430
 
   : mUstr(s.c_str()),
431
 
     mUtf16Cache(NULL),
432
 
     mUtf16Length(npos)
433
 
{
434
 
   ASSERT(Validate(s));
435
 
}
436
 
 
437
 
 
438
 
/*
439
 
 *-----------------------------------------------------------------------------
440
 
 *
441
 
 * utf::string::string --
442
 
 *
443
 
 *      Copy constructor.
444
 
 *
445
 
 *      XXX: When initializing mUstr, we do a deep copy of the string data
446
 
 *      instead of just calling mUstr(s). This is because Glib::ustring is very
447
 
 *      smart about sharing storage, and zero_clear is very dumb. Once we get
448
 
 *      rid of zero_clear and have a separate sensitive-string class, this can
449
 
 *      go back to being simple.
450
 
 *
451
 
 * Results:
452
 
 *      None.
453
 
 *
454
 
 * Side effects:
455
 
 *      None
456
 
 *
457
 
 *-----------------------------------------------------------------------------
458
 
 */
459
 
 
460
 
string::string(const string &s) // IN
461
 
   : mUstr(s.mUstr.c_str()),
462
 
     mUtf16Cache(NULL),
463
 
     mUtf16Length(npos)
464
 
{
465
 
}
466
 
 
467
 
 
468
 
/*
469
 
 *-----------------------------------------------------------------------------
470
 
 *
471
 
 * utf::string::~string --
472
 
 *
473
 
 *      Destructor.
474
 
 *
475
 
 * Results:
476
 
 *      None.
477
 
 *
478
 
 * Side effects:
479
 
 *      None.
480
 
 *
481
 
 *-----------------------------------------------------------------------------
482
 
 */
483
 
 
484
 
string::~string()
485
 
{
486
 
   InvalidateCache();
487
 
}
488
 
 
489
 
 
490
 
/*
491
 
 *-----------------------------------------------------------------------------
492
 
 *
493
 
 * utf::string::operator Glib::ustring --
494
 
 *
495
 
 *      Implicit conversion to Glib::ustring operator
496
 
 *
497
 
 * Results:
498
 
 *      The internal Glib::ustring object.
499
 
 *
500
 
 * Side effects:
501
 
 *      None.
502
 
 *
503
 
 *-----------------------------------------------------------------------------
504
 
 */
505
 
 
506
 
string::operator const Glib::ustring& ()
507
 
   const
508
 
{
509
 
   return ustr();
510
 
}
511
 
 
512
 
 
513
 
#ifdef _WIN32
514
 
 
515
 
/*
516
 
 *-----------------------------------------------------------------------------
517
 
 *
518
 
 * utf::string::operator ubstr_t --
519
 
 *
520
 
 *      Implicit conversion to ubstr_t
521
 
 *
522
 
 * Results:
523
 
 *      The current ubstr_t string. NUL-terminated.
524
 
 *
525
 
 * Side effects:
526
 
 *      None
527
 
 *
528
 
 * Note:
529
 
 *      This function is only defined in _WIN32
530
 
 *
531
 
 *-----------------------------------------------------------------------------
532
 
 */
533
 
 
534
 
string::operator const ubstr_t()
535
 
   const
536
 
{
537
 
   return ubstr_t(GetUtf16Cache());
538
 
}
539
 
 
540
 
#endif
541
 
 
542
 
 
543
 
/*
544
 
 *-----------------------------------------------------------------------------
545
 
 *
546
 
 * utf::string::operator= --
547
 
 *
548
 
 *      Assignment operator.
549
 
 *
550
 
 * Results:
551
 
 *      A reference to this string.
552
 
 *
553
 
 * Side effects:
554
 
 *      None
555
 
 *
556
 
 *-----------------------------------------------------------------------------
557
 
 */
558
 
 
559
 
string&
560
 
string::operator=(string copy) // IN
561
 
{
562
 
   swap(copy);
563
 
   return *this;
564
 
}
565
 
 
566
 
 
567
 
/*
568
 
 *-----------------------------------------------------------------------------
569
 
 *
570
 
 * utf::string::operator+= --
571
 
 *
572
 
 *      Append operator of the utf::string class.
573
 
 *
574
 
 * Results:
575
 
 *      A reference to this string.
576
 
 *
577
 
 * Side effects:
578
 
 *      None
579
 
 *
580
 
 *-----------------------------------------------------------------------------
581
 
 */
582
 
 
583
 
string&
584
 
string::operator+=(const string &s) // IN
585
 
{
586
 
   return append(s);
587
 
}
588
 
 
589
 
 
590
 
string&
591
 
string::operator+=(value_type uc) // IN
592
 
{
593
 
   push_back(uc);
594
 
   return *this;
595
 
}
596
 
 
597
 
 
598
 
/*
599
 
 *-----------------------------------------------------------------------------
600
 
 *
601
 
 * utf::string::swap --
602
 
 *
603
 
 *      Swaps the contents with a given utf::string.
604
 
 *
605
 
 * Results:
606
 
 *      None.
607
 
 *
608
 
 * Side effects:
609
 
 *      None
610
 
 *
611
 
 *-----------------------------------------------------------------------------
612
 
 */
613
 
 
614
 
void
615
 
string::swap(string &s) // IN/OUT
616
 
{
617
 
   mUstr.swap(s.mUstr);
618
 
   std::swap(mUtf16Cache, s.mUtf16Cache);
619
 
   std::swap(mUtf16Length, s.mUtf16Length);
620
 
}
621
 
 
622
 
 
623
 
/*
624
 
 *-----------------------------------------------------------------------------
625
 
 *
626
 
 * utf::string::resize --
627
 
 *
628
 
 *      Change the size of this utf::string.
629
 
 *
630
 
 * Results:
631
 
 *      None.
632
 
 *
633
 
 * Side effects:
634
 
 *      None
635
 
 *
636
 
 *-----------------------------------------------------------------------------
637
 
 */
638
 
 
639
 
void
640
 
string::resize(size_type n,  // IN
641
 
               value_type c) // IN/OPT
642
 
{
643
 
   InvalidateCache();
644
 
   mUstr.resize(n, c);
645
 
}
646
 
 
647
 
 
648
 
/*
649
 
 *-----------------------------------------------------------------------------
650
 
 *
651
 
 * utf::string::c_str --
652
 
 *
653
 
 *      Get the UTF-8 representation of this string.
654
 
 *
655
 
 * Results:
656
 
 *      The current string with UTF-8 encoding. NUL-terminated.
657
 
 *
658
 
 * Side effects:
659
 
 *      None
660
 
 *
661
 
 *-----------------------------------------------------------------------------
662
 
 */
663
 
 
664
 
const char *
665
 
string::c_str()
666
 
   const
667
 
{
668
 
   return mUstr.c_str();
669
 
}
670
 
 
671
 
 
672
 
/*
673
 
 *-----------------------------------------------------------------------------
674
 
 *
675
 
 * utf::string::w_str --
676
 
 *
677
 
 *      Get the UTF-16 representation of this string.
678
 
 *
679
 
 * Results:
680
 
 *      The current string with UTF-16 (host-endian) encoding. NUL-terminated.
681
 
 *
682
 
 * Side effects:
683
 
 *      None
684
 
 *
685
 
 *-----------------------------------------------------------------------------
686
 
 */
687
 
 
688
 
const utf16_t *
689
 
string::w_str()
690
 
   const
691
 
{
692
 
   return GetUtf16Cache();
693
 
}
694
 
 
695
 
 
696
 
/*
697
 
 *-----------------------------------------------------------------------------
698
 
 *
699
 
 * utf::string::ustr --
700
 
 *
701
 
 *      Get the Glib::ustring backing of this string.
702
 
 *
703
 
 * Results:
704
 
 *      The internal Glib::ustring object.
705
 
 *
706
 
 * Side effects:
707
 
 *      None
708
 
 *
709
 
 *-----------------------------------------------------------------------------
710
 
 */
711
 
 
712
 
const Glib::ustring&
713
 
string::ustr()
714
 
   const
715
 
{
716
 
   return mUstr;
717
 
}
718
 
 
719
 
 
720
 
/*
721
 
 *-----------------------------------------------------------------------------
722
 
 *
723
 
 * utf::string::empty --
724
 
 *
725
 
 *      Test if this is an empty string.
726
 
 *
727
 
 * Results:
728
 
 *      true if it's an empty string, otherwise false.
729
 
 *
730
 
 * Side effects:
731
 
 *      None
732
 
 *
733
 
 *-----------------------------------------------------------------------------
734
 
 */
735
 
 
736
 
bool
737
 
string::empty()
738
 
   const
739
 
{
740
 
   return mUstr.empty();
741
 
}
742
 
 
743
 
 
744
 
/*
745
 
 *-----------------------------------------------------------------------------
746
 
 *
747
 
 * utf::string::size --
748
 
 *
749
 
 * Results:
750
 
 *      Returns the length of this string, in characters (code points),
751
 
 *      excluding NUL.
752
 
 *
753
 
 * Side effects:
754
 
 *      None
755
 
 *
756
 
 *-----------------------------------------------------------------------------
757
 
 */
758
 
 
759
 
string::size_type
760
 
string::size()
761
 
   const
762
 
{
763
 
   return mUstr.size();
764
 
}
765
 
 
766
 
 
767
 
/*
768
 
 *-----------------------------------------------------------------------------
769
 
 *
770
 
 * utf::string::w_size --
771
 
 *
772
 
 * Results:
773
 
 *      Returns the length of this string, in UTF-16 code units,
774
 
 *      excluding NUL.
775
 
 *
776
 
 * Side effects:
777
 
 *      None
778
 
 *
779
 
 *-----------------------------------------------------------------------------
780
 
 */
781
 
 
782
 
string::size_type
783
 
string::w_size()
784
 
   const
785
 
{
786
 
   if (mUtf16Length == npos) {
787
 
      mUtf16Length = Unicode_UTF16Strlen(GetUtf16Cache());
788
 
   }
789
 
 
790
 
   return mUtf16Length;
791
 
}
792
 
 
793
 
 
794
 
/*
795
 
 *-----------------------------------------------------------------------------
796
 
 *
797
 
 * utf::string::length --
798
 
 *
799
 
 * Results:
800
 
 *      Returns the length of this string, in characters (code points),
801
 
 *      excluding NUL. (Same as size().)
802
 
 *
803
 
 * Side effects:
804
 
 *      None
805
 
 *
806
 
 *-----------------------------------------------------------------------------
807
 
 */
808
 
 
809
 
string::size_type
810
 
string::length()
811
 
   const
812
 
{
813
 
   return size();
814
 
}
815
 
 
816
 
 
817
 
/*
818
 
 *-----------------------------------------------------------------------------
819
 
 *
820
 
 * utf::string::bytes --
821
 
 *
822
 
 * Results:
823
 
 *      Returns the number of bytes used by the UTF-8 representation of this
824
 
 *      string, excluding NUL.
825
 
 *
826
 
 * Side effects:
827
 
 *      None
828
 
 *
829
 
 *-----------------------------------------------------------------------------
830
 
 */
831
 
 
832
 
string::size_type
833
 
string::bytes()
834
 
   const
835
 
{
836
 
   return mUstr.bytes();
837
 
}
838
 
 
839
 
 
840
 
/*
841
 
 *-----------------------------------------------------------------------------
842
 
 *
843
 
 * utf::string::foldCase --
844
 
 *
845
 
 *      Returns the case-folded string of this string.
846
 
 *
847
 
 * Results:
848
 
 *      The newly created string.
849
 
 *
850
 
 * Side effects:
851
 
 *      None
852
 
 *
853
 
 *-----------------------------------------------------------------------------
854
 
 */
855
 
 
856
 
string
857
 
string::foldCase()
858
 
   const
859
 
{
860
 
   return string(mUstr.casefold());
861
 
}
862
 
 
863
 
 
864
 
/*
865
 
 *-----------------------------------------------------------------------------
866
 
 *
867
 
 * utf::string::trim --
868
 
 *
869
 
 *      Returns the whitespace-trimmed version of this string.
870
 
 *
871
 
 * Results:
872
 
 *      The newly created string.
873
 
 *
874
 
 * Side effects:
875
 
 *      None
876
 
 *
877
 
 *-----------------------------------------------------------------------------
878
 
 */
879
 
 
880
 
string
881
 
string::trim()
882
 
   const
883
 
{
884
 
   Unicode trim = Unicode_Trim(c_str());
885
 
   string result(trim);
886
 
   Unicode_Free(trim);
887
 
   return result;
888
 
}
889
 
 
890
 
 
891
 
/*
892
 
 *-----------------------------------------------------------------------------
893
 
 *
894
 
 * utf::string::trimLeft --
895
 
 *
896
 
 *      Get the left-trimmed version of this string.
897
 
 *
898
 
 * Results:
899
 
 *      The newly created string.
900
 
 *
901
 
 * Side effects:
902
 
 *      None
903
 
 *
904
 
 *-----------------------------------------------------------------------------
905
 
 */
906
 
 
907
 
string
908
 
string::trimLeft()
909
 
   const
910
 
{
911
 
   Unicode trim = Unicode_TrimLeft(c_str());
912
 
   string result(trim);
913
 
   Unicode_Free(trim);
914
 
   return result;
915
 
}
916
 
 
917
 
 
918
 
/*
919
 
 *-----------------------------------------------------------------------------
920
 
 *
921
 
 * utf::string::trimRight --
922
 
 *
923
 
 *      Get the right-trimmed version of this string.
924
 
 *
925
 
 * Results:
926
 
 *      The newly created string.
927
 
 *
928
 
 * Side effects:
929
 
 *      None
930
 
 *
931
 
 *-----------------------------------------------------------------------------
932
 
 */
933
 
 
934
 
string
935
 
string::trimRight()
936
 
   const
937
 
{
938
 
   Unicode trim = Unicode_TrimRight(c_str());
939
 
   string result(trim);
940
 
   Unicode_Free(trim);
941
 
   return result;
942
 
}
943
 
 
944
 
 
945
 
/*
946
 
 *-----------------------------------------------------------------------------
947
 
 *
948
 
 * utf::string::normalize --
949
 
 *
950
 
 *      Creates a new string by normalizing the input string.
951
 
 *
952
 
 * Results:
953
 
 *      The newly created string.
954
 
 *
955
 
 * Side effects:
956
 
 *      None
957
 
 *
958
 
 *-----------------------------------------------------------------------------
959
 
 */
960
 
 
961
 
string
962
 
string::normalize(NormalizeMode mode) // IN
963
 
   const
964
 
{
965
 
   return mUstr.normalize((Glib::NormalizeMode)mode);
966
 
}
967
 
 
968
 
 
969
 
#ifdef SUPPORT_UNICODE
970
 
 
971
 
/*
972
 
 *-----------------------------------------------------------------------------
973
 
 *
974
 
 * utf::string::toLower --
975
 
 *
976
 
 *      Creates a new string by lower-casing the input string using
977
 
 *      the rules of the specified locale.
978
 
 *
979
 
 * Results:
980
 
 *      The newly created string.
981
 
 *
982
 
 * Side effects:
983
 
 *      None
984
 
 *
985
 
 *-----------------------------------------------------------------------------
986
 
 */
987
 
 
988
 
string
989
 
string::toLower(const char *locale) // IN
990
 
   const
991
 
{
992
 
   Unicode lower = Unicode_ToLower(c_str(), locale);
993
 
   string results(lower);
994
 
   Unicode_Free(lower);
995
 
 
996
 
   return results;
997
 
}
998
 
 
999
 
 
1000
 
/*
1001
 
 *-----------------------------------------------------------------------------
1002
 
 *
1003
 
 * utf::string::toUpper --
1004
 
 *
1005
 
 *      Creates a new string by upper-casing the input string using
1006
 
 *      the rules of the specified locale.
1007
 
 *
1008
 
 * Results:
1009
 
 *      The newly created string.
1010
 
 *
1011
 
 * Side effects:
1012
 
 *      None
1013
 
 *
1014
 
 *-----------------------------------------------------------------------------
1015
 
 */
1016
 
 
1017
 
string
1018
 
string::toUpper(const char *locale) // IN
1019
 
   const
1020
 
{
1021
 
   Unicode upper = Unicode_ToUpper(c_str(), locale);
1022
 
   string results(upper);
1023
 
   Unicode_Free(upper);
1024
 
 
1025
 
   return results;
1026
 
}
1027
 
 
1028
 
 
1029
 
/*
1030
 
 *-----------------------------------------------------------------------------
1031
 
 *
1032
 
 * utf::string::toTitle --
1033
 
 *
1034
 
 *      Creates a new string by title-casing the input string using
1035
 
 *      the rules of the specified locale.
1036
 
 *
1037
 
 * Results:
1038
 
 *      The newly created string.
1039
 
 *
1040
 
 * Side effects:
1041
 
 *      None
1042
 
 *
1043
 
 *-----------------------------------------------------------------------------
1044
 
 */
1045
 
 
1046
 
string
1047
 
string::toTitle(const char *locale) // IN
1048
 
   const
1049
 
{
1050
 
   Unicode title = Unicode_ToTitle(c_str(), locale);
1051
 
   string results(title);
1052
 
   Unicode_Free(title);
1053
 
 
1054
 
   return results;
1055
 
}
1056
 
 
1057
 
#endif
1058
 
 
1059
 
 
1060
 
/*
1061
 
 *-----------------------------------------------------------------------------
1062
 
 *
1063
 
 * utf::string::append --
1064
 
 *
1065
 
 *      Appends the argument string to this utf::string.
1066
 
 *
1067
 
 * Results:
1068
 
 *      A reference to this object.
1069
 
 *
1070
 
 * Side effects:
1071
 
 *      None
1072
 
 *
1073
 
 *-----------------------------------------------------------------------------
1074
 
 */
1075
 
 
1076
 
string&
1077
 
string::append(const string &s) // IN
1078
 
{
1079
 
   InvalidateCache();
1080
 
   mUstr.append(s.mUstr);
1081
 
 
1082
 
   return *this;
1083
 
}
1084
 
 
1085
 
 
1086
 
string&
1087
 
string::append(const string &s, // IN
1088
 
               size_type i,     // IN
1089
 
               size_type n)     // IN
1090
 
{
1091
 
   InvalidateCache();
1092
 
   mUstr.append(s.mUstr, i, n);
1093
 
 
1094
 
   return *this;
1095
 
}
1096
 
 
1097
 
 
1098
 
/*
1099
 
 *-----------------------------------------------------------------------------
1100
 
 *
1101
 
 * utf::string::push_back --
1102
 
 *
1103
 
 *      Appends the character at the end of this string.
1104
 
 *
1105
 
 * Results:
1106
 
 *      None
1107
 
 *
1108
 
 * Side effects:
1109
 
 *      None
1110
 
 *
1111
 
 *-----------------------------------------------------------------------------
1112
 
 */
1113
 
 
1114
 
void
1115
 
string::push_back(value_type uc) // IN
1116
 
{
1117
 
   InvalidateCache();
1118
 
   mUstr.push_back(uc);
1119
 
}
1120
 
 
1121
 
 
1122
 
/*
1123
 
 *-----------------------------------------------------------------------------
1124
 
 *
1125
 
 * utf::string::assign --
1126
 
 *
1127
 
 *      Assigns the passed in string to this string.
1128
 
 *
1129
 
 *      Callers should prefer using operator= instead of assign().
1130
 
 *
1131
 
 * Results:
1132
 
 *      A reference to this object
1133
 
 *
1134
 
 * Side effects:
1135
 
 *      None
1136
 
 *
1137
 
 *-----------------------------------------------------------------------------
1138
 
 */
1139
 
 
1140
 
string&
1141
 
string::assign(const string &s) // IN
1142
 
{
1143
 
   return operator=(s);
1144
 
}
1145
 
 
1146
 
 
1147
 
/*
1148
 
 *-----------------------------------------------------------------------------
1149
 
 *
1150
 
 * utf::string::insert --
1151
 
 *
1152
 
 *      Inserts the argument string to this string at index i, return this
1153
 
 *      string.
1154
 
 *
1155
 
 *      These are passthrough calls to the Glib::insert calls.
1156
 
 *
1157
 
 * Results:
1158
 
 *      A reference to this object
1159
 
 *
1160
 
 * Side effects:
1161
 
 *      None
1162
 
 *
1163
 
 *-----------------------------------------------------------------------------
1164
 
 */
1165
 
 
1166
 
string&
1167
 
string::insert(size_type i,      // IN
1168
 
               const string &s)  // IN
1169
 
{
1170
 
   InvalidateCache();
1171
 
   mUstr.insert(i, s.mUstr);
1172
 
   return *this;
1173
 
}
1174
 
 
1175
 
 
1176
 
string&
1177
 
string::insert(size_type i,      // IN
1178
 
               size_type n,      // IN
1179
 
               value_type uc)
1180
 
{
1181
 
   InvalidateCache();
1182
 
   mUstr.insert(i, n, uc);
1183
 
   return *this;
1184
 
}
1185
 
 
1186
 
 
1187
 
/*
1188
 
 *-----------------------------------------------------------------------------
1189
 
 *
1190
 
 * utf::string::clear --
1191
 
 *
1192
 
 *      Clears this string.
1193
 
 *
1194
 
 * Results:
1195
 
 *      None
1196
 
 *
1197
 
 * Side effects:
1198
 
 *      None
1199
 
 *
1200
 
 *-----------------------------------------------------------------------------
1201
 
 */
1202
 
 
1203
 
void
1204
 
string::clear()
1205
 
{
1206
 
   InvalidateCache();
1207
 
   mUstr.clear();
1208
 
}
1209
 
 
1210
 
 
1211
 
/*
1212
 
 *-----------------------------------------------------------------------------
1213
 
 *
1214
 
 * utf::string::zero_clear --
1215
 
 *
1216
 
 *      Zeroes and clears this string.
1217
 
 *
1218
 
 *      XXX: This is temporary until we have a separate string class for
1219
 
 *      passwords.
1220
 
 *
1221
 
 * Results:
1222
 
 *      None
1223
 
 *
1224
 
 * Side effects:
1225
 
 *      None
1226
 
 *
1227
 
 *-----------------------------------------------------------------------------
1228
 
 */
1229
 
 
1230
 
void
1231
 
string::zero_clear()
1232
 
{
1233
 
   if (mUtf16Cache != NULL) {
1234
 
      Util_ZeroFree(mUtf16Cache,
1235
 
                    Unicode_UTF16Strlen(mUtf16Cache) * sizeof *mUtf16Cache);
1236
 
      mUtf16Cache = NULL;
1237
 
   }
1238
 
 
1239
 
   /*
1240
 
    * This is a best effort.  We aren't guaranteed that Glib::ustring doesn't
1241
 
    * leave behind any internal copies of the string.
1242
 
    */
1243
 
   if (mUstr.c_str() != mUstr.data()) {
1244
 
      Util_Zero(const_cast<char *>(mUstr.c_str()), mUstr.bytes());
1245
 
   }
1246
 
   Util_Zero(const_cast<char *>(mUstr.data()), mUstr.bytes());
1247
 
   mUstr.clear();
1248
 
}
1249
 
 
1250
 
 
1251
 
/*
1252
 
 *-----------------------------------------------------------------------------
1253
 
 *
1254
 
 * utf::string::erase --
1255
 
 *
1256
 
 *      Erase the contents of this string in the specified index range.
1257
 
 *
1258
 
 * Results:
1259
 
 *      A reference to this object
1260
 
 *
1261
 
 * Side effects:
1262
 
 *      None
1263
 
 *
1264
 
 *-----------------------------------------------------------------------------
1265
 
 */
1266
 
 
1267
 
string&
1268
 
string::erase(size_type i,    // IN
1269
 
              size_type n)    // IN
1270
 
{
1271
 
   InvalidateCache();
1272
 
   mUstr.erase(i, n);
1273
 
   return *this;
1274
 
}
1275
 
 
1276
 
 
1277
 
/*
1278
 
 *-----------------------------------------------------------------------------
1279
 
 *
1280
 
 * utf::string::erase --
1281
 
 *
1282
 
 *      Erase the contents of this string with given iterator.
1283
 
 *
1284
 
 * Results:
1285
 
 *      The current iterator.
1286
 
 *
1287
 
 * Side effects:
1288
 
 *      None
1289
 
 *
1290
 
 *-----------------------------------------------------------------------------
1291
 
 */
1292
 
 
1293
 
string::iterator
1294
 
string::erase(iterator p)    // IN
1295
 
{
1296
 
   InvalidateCache();
1297
 
   return mUstr.erase(p);
1298
 
}
1299
 
 
1300
 
 
1301
 
string::iterator
1302
 
string::erase(iterator pbegin,    // IN
1303
 
              iterator pend)      // IN
1304
 
{
1305
 
   InvalidateCache();
1306
 
   return mUstr.erase(pbegin, pend);
1307
 
}
1308
 
 
1309
 
/*
1310
 
 *-----------------------------------------------------------------------------
1311
 
 *
1312
 
 * utf::string::replace --
1313
 
 *
1314
 
 *      Replace the string contents specified by the range, with the passed in
1315
 
 *      string.
1316
 
 *
1317
 
 * Results:
1318
 
 *      A reference to this object.
1319
 
 *
1320
 
 * Side effects:
1321
 
 *      None
1322
 
 *
1323
 
 *-----------------------------------------------------------------------------
1324
 
 */
1325
 
 
1326
 
string&
1327
 
string::replace(size_type i,     // IN
1328
 
                size_type n,     // IN
1329
 
                const string &s) // IN
1330
 
{
1331
 
   InvalidateCache();
1332
 
   mUstr.replace(i, n, s.mUstr);
1333
 
   return *this;
1334
 
}
1335
 
 
1336
 
 
1337
 
/*
1338
 
 *-----------------------------------------------------------------------------
1339
 
 *
1340
 
 * utf::string::replace --
1341
 
 *
1342
 
 *      Mutates this string by replacing all occurrences of one string with
1343
 
 *      another.
1344
 
 *
1345
 
 * Results:
1346
 
 *      A reference to this object.
1347
 
 *
1348
 
 * Side effects:
1349
 
 *      None
1350
 
 *
1351
 
 *-----------------------------------------------------------------------------
1352
 
 */
1353
 
 
1354
 
string&
1355
 
string::replace(const string &from, // IN
1356
 
                const string &to)   // IN
1357
 
{
1358
 
   size_type end;
1359
 
   size_type start = 0;
1360
 
   size_type fromSize = from.length();
1361
 
   string result;
1362
 
 
1363
 
   while ((end = find(from, start)) != string::npos) {
1364
 
      result += substr(start, end - start);
1365
 
      result += to;
1366
 
 
1367
 
      start = end + fromSize;
1368
 
   }
1369
 
 
1370
 
   if (start < length()) {
1371
 
      result += substr(start);
1372
 
   }
1373
 
 
1374
 
   swap(result);
1375
 
   return *this;
1376
 
}
1377
 
 
1378
 
 
1379
 
/*
1380
 
 *-----------------------------------------------------------------------------
1381
 
 *
1382
 
 * utf::string::replace_copy --
1383
 
 *
1384
 
 * Results:
1385
 
 *      Returns a new string with all occurrences of one string replaced by
1386
 
 *      another.
1387
 
 *
1388
 
 * Side effects:
1389
 
 *      None
1390
 
 *
1391
 
 *-----------------------------------------------------------------------------
1392
 
 */
1393
 
 
1394
 
string
1395
 
string::replace_copy(const string& from, // IN
1396
 
                     const string& to)   // IN
1397
 
   const
1398
 
{
1399
 
   return string(*this).replace(from, to);
1400
 
}
1401
 
 
1402
 
 
1403
 
/*
1404
 
 *-----------------------------------------------------------------------------
1405
 
 *
1406
 
 * utf::string::compare --
1407
 
 *
1408
 
 *      A 3-way (output -1, 0, or 1) string comparison. Compares each Unicode
1409
 
 *      code point of this string to the argument string.
1410
 
 *
1411
 
 * Results:
1412
 
 *      -1 if *this < s, 0 if *this == s, 1 if *this > s.
1413
 
 *
1414
 
 * Side effects:
1415
 
 *      None
1416
 
 *
1417
 
 *-----------------------------------------------------------------------------
1418
 
 */
1419
 
 
1420
 
int
1421
 
string::compare(const string &s, // IN
1422
 
                bool ignoreCase) // IN/OPT: false by default
1423
 
   const
1424
 
{
1425
 
   return ignoreCase
1426
 
          ? Unicode_CompareIgnoreCase(c_str(), s.c_str())
1427
 
          : Unicode_Compare(c_str(), s.c_str());
1428
 
}
1429
 
 
1430
 
 
1431
 
int
1432
 
string::compare(size_type i,     // IN
1433
 
                size_type n,     // IN
1434
 
                const string &s) // IN
1435
 
   const
1436
 
{
1437
 
   return mUstr.compare(i, n, s.mUstr);
1438
 
}
1439
 
 
1440
 
 
1441
 
/*
1442
 
 *-----------------------------------------------------------------------------
1443
 
 *
1444
 
 * utf::string::compareLength --
1445
 
 *
1446
 
 *      A 3-way (output -1, 0, or 1) string comparison with given length.
1447
 
 *      Compares only the first len characters (in code units) of the strings.
1448
 
 *
1449
 
 * Results:
1450
 
 *      -1 if *this < s, 0 if *this == s, 1 if *this > s.
1451
 
 *
1452
 
 * Side effects:
1453
 
 *      None
1454
 
 *
1455
 
 *-----------------------------------------------------------------------------
1456
 
 */
1457
 
 
1458
 
int
1459
 
string::compareLength(const string &s, // IN
1460
 
                      size_type len,   // IN: length in code-point
1461
 
                      bool ignoreCase) // IN/OPT: false by default
1462
 
   const
1463
 
{
1464
 
   return substr(0, len).compare(s.substr(0, len), ignoreCase);
1465
 
}
1466
 
 
1467
 
 
1468
 
/*
1469
 
 *-----------------------------------------------------------------------------
1470
 
 *
1471
 
 * utf::string::compareRange --
1472
 
 *
1473
 
 *      A 3-way (output -1, 0, or 1) string comparison with given length.
1474
 
 *      Compares the substrings from this string [thisStart ~ thisStart + thisLength-1]
1475
 
 *      with the input string str [strStart ~ strStart + strLength - 1].
1476
 
 *
1477
 
 * Results:
1478
 
 *      -1 if *this < s, 0 if *this == s, 1 if *this > s.
1479
 
 *
1480
 
 * Side effects:
1481
 
 *      None
1482
 
 *
1483
 
 *-----------------------------------------------------------------------------
1484
 
 */
1485
 
 
1486
 
int
1487
 
string::compareRange(size_type thisStart,  // IN: index in code-point
1488
 
                     size_type thisLength, // IN: length in code-point
1489
 
                     const string &str,    // IN
1490
 
                     size_type strStart,   // IN: index in code-point
1491
 
                     size_type strLength,  // IN: length in code-point
1492
 
                     bool ignoreCase)      // IN/OPT: false by default
1493
 
   const
1494
 
{
1495
 
   return substr(thisStart, thisLength).compare(str.substr(strStart, strLength), ignoreCase);
1496
 
}
1497
 
 
1498
 
 
1499
 
/*
1500
 
 *-----------------------------------------------------------------------------
1501
 
 *
1502
 
 * utf::string::find --
1503
 
 *
1504
 
 *      Searches for the first occurrence of the input string inside this string.
1505
 
 *
1506
 
 * Results:
1507
 
 *      If s is found, then, it returns the first starting index of the input string.
1508
 
 *      Otherwise, returns npos.
1509
 
 *
1510
 
 * Side effects:
1511
 
 *      None
1512
 
 *
1513
 
 *-----------------------------------------------------------------------------
1514
 
 */
1515
 
 
1516
 
string::size_type
1517
 
string::find(const string &s,   // IN
1518
 
             size_type pos)     // IN/OPT
1519
 
   const
1520
 
{
1521
 
   return mUstr.find(s.mUstr, pos);
1522
 
}
1523
 
 
1524
 
 
1525
 
string::size_type
1526
 
string::find(value_type uc, // IN
1527
 
             size_type pos) // IN/OPT
1528
 
   const
1529
 
{
1530
 
   return mUstr.find(uc, pos);
1531
 
}
1532
 
 
1533
 
 
1534
 
/*
1535
 
 *-----------------------------------------------------------------------------
1536
 
 *
1537
 
 * utf::string::rfind --
1538
 
 *
1539
 
 *      Searches for the last occurrence of the input string inside this string.
1540
 
 *
1541
 
 * Results:
1542
 
 *      If s is found, then, it returns the last starting index of the input string.
1543
 
 *      Otherwise, returns npos.
1544
 
 *
1545
 
 * Side effects:
1546
 
 *      None
1547
 
 *
1548
 
 *-----------------------------------------------------------------------------
1549
 
 */
1550
 
 
1551
 
string::size_type
1552
 
string::rfind(const string &s,   // IN
1553
 
              size_type pos)     // IN/OPT
1554
 
   const
1555
 
{
1556
 
   return mUstr.rfind(s.mUstr, pos);
1557
 
}
1558
 
 
1559
 
 
1560
 
string::size_type
1561
 
string::rfind(value_type uc,     // IN
1562
 
              size_type pos)     // IN/OPT
1563
 
   const
1564
 
{
1565
 
   return mUstr.rfind(uc, pos);
1566
 
}
1567
 
 
1568
 
 
1569
 
/*
1570
 
 *-----------------------------------------------------------------------------
1571
 
 *
1572
 
 * utf::string::find_first_of --
1573
 
 *
1574
 
 *      Find the first occurrence of 's' in this string.  'i' determines where in
1575
 
 *      the current string we start searching for 's'
1576
 
 *
1577
 
 * Results:
1578
 
 *      If s is found, then, it returns the index where s occurs in this
1579
 
 *      string.
1580
 
 *      Otherwise, returns npos.
1581
 
 *
1582
 
 * Side effects:
1583
 
 *      None
1584
 
 *
1585
 
 *-----------------------------------------------------------------------------
1586
 
 */
1587
 
 
1588
 
string::size_type
1589
 
string::find_first_of(const string &s, // IN
1590
 
                      size_type i)     // IN/OPT
1591
 
   const
1592
 
{
1593
 
   return mUstr.find_first_of(s.mUstr, i);
1594
 
}
1595
 
 
1596
 
 
1597
 
string::size_type
1598
 
string::find_first_of(value_type uc,   // IN
1599
 
                      size_type i)     // IN/OPT
1600
 
   const
1601
 
{
1602
 
   return mUstr.find_first_of(uc, i);
1603
 
}
1604
 
 
1605
 
 
1606
 
/*
1607
 
 *-----------------------------------------------------------------------------
1608
 
 *
1609
 
 * utf::string::find_first_not_of --
1610
 
 *
1611
 
 *      Find the first occurrence of a string NOT in 's' in this string.  'i'
1612
 
 *      determines where in this string we start searching to NOT 's'.
1613
 
 *
1614
 
 * Results:
1615
 
 *      Returns the index of the first sequence in this string that is not 's'
1616
 
 *      Otherwise, returns npos.
1617
 
 *
1618
 
 * Side effects:
1619
 
 *      None
1620
 
 *
1621
 
 *-----------------------------------------------------------------------------
1622
 
 */
1623
 
 
1624
 
string::size_type
1625
 
string::find_first_not_of(const string &s, // IN
1626
 
                          size_type i)     // IN/OPT
1627
 
   const
1628
 
{
1629
 
   return mUstr.find_first_not_of(s.mUstr, i);
1630
 
}
1631
 
 
1632
 
 
1633
 
string::size_type
1634
 
string::find_first_not_of(value_type uc,   // IN
1635
 
                          size_type i)     // IN/OPT
1636
 
   const
1637
 
{
1638
 
   return mUstr.find_first_not_of(uc, i);
1639
 
}
1640
 
 
1641
 
 
1642
 
/*
1643
 
 *-----------------------------------------------------------------------------
1644
 
 *
1645
 
 * utf::string::find_last_of --
1646
 
 *
1647
 
 *      Does a reverse search in this string for 's'.  'i' determines where we
1648
 
 *      start the search for in this string.
1649
 
 *
1650
 
 * Results:
1651
 
 *      If s is found, then, it returns the index where s occurs in this
1652
 
 *      string.
1653
 
 *      Otherwise, returns npos.
1654
 
 *
1655
 
 * Side effects:
1656
 
 *      None
1657
 
 *
1658
 
 *-----------------------------------------------------------------------------
1659
 
 */
1660
 
 
1661
 
string::size_type
1662
 
string::find_last_of(const string &s, // IN
1663
 
                     size_type i)     // IN/OPT
1664
 
   const
1665
 
{
1666
 
   return mUstr.find_last_of(s.mUstr, i);
1667
 
}
1668
 
 
1669
 
 
1670
 
string::size_type
1671
 
string::find_last_of(value_type uc,   // IN
1672
 
                     size_type i)     // IN/OPT
1673
 
   const
1674
 
{
1675
 
   return mUstr.find_last_of(uc, i);
1676
 
}
1677
 
 
1678
 
 
1679
 
/*
1680
 
 *-----------------------------------------------------------------------------
1681
 
 *
1682
 
 * utf::string::find_last_not_of --
1683
 
 *
1684
 
 *      Searches for the last character within the current string that does
1685
 
 *      not match any characters in 's'.  'i' determines where we start the
1686
 
 *      search for in this string.  (moving backwards).
1687
 
 *
1688
 
 * Results:
1689
 
 *      If NOT 's' is found, then, it returns the index where s does not occurs
1690
 
 *      in this string.
1691
 
 *      Otherwise, returns npos.
1692
 
 *
1693
 
 * Side effects:
1694
 
 *      None
1695
 
 *
1696
 
 *-----------------------------------------------------------------------------
1697
 
 */
1698
 
 
1699
 
string::size_type
1700
 
string::find_last_not_of(const string &s, // IN
1701
 
                         size_type i)     // IN/OPT
1702
 
   const
1703
 
{
1704
 
   return mUstr.find_last_not_of(s.mUstr, i);
1705
 
}
1706
 
 
1707
 
 
1708
 
string::size_type
1709
 
string::find_last_not_of(value_type uc,   // IN
1710
 
                         size_type i)     // IN/OPT
1711
 
   const
1712
 
{
1713
 
   return mUstr.find_last_not_of(uc, i);
1714
 
}
1715
 
 
1716
 
 
1717
 
/*
1718
 
 *-----------------------------------------------------------------------------
1719
 
 *
1720
 
 * utf::string::substr --
1721
 
 *
1722
 
 *      Create a substring of this string with given range.
1723
 
 *
1724
 
 * Results:
1725
 
 *      The newly created string.
1726
 
 *
1727
 
 * Side effects:
1728
 
 *      None
1729
 
 *
1730
 
 *-----------------------------------------------------------------------------
1731
 
 */
1732
 
 
1733
 
string
1734
 
string::substr(size_type start, // IN
1735
 
               size_type len)   // IN
1736
 
   const
1737
 
{
1738
 
   return string(mUstr.substr(start, len));
1739
 
}
1740
 
 
1741
 
 
1742
 
/*
1743
 
 *-----------------------------------------------------------------------------
1744
 
 *
1745
 
 * utf::string::operator[] --
1746
 
 *
1747
 
 *      Get the UTF-32 character at given index in this string.
1748
 
 *
1749
 
 * Results:
1750
 
 *      UTF-32 character (gunichar).
1751
 
 *
1752
 
 * Side effects:
1753
 
 *      None
1754
 
 *
1755
 
 *-----------------------------------------------------------------------------
1756
 
 */
1757
 
 
1758
 
string::value_type
1759
 
string::operator[](size_type i)  // IN
1760
 
   const
1761
 
{
1762
 
   return mUstr[i];
1763
 
}
1764
 
 
1765
 
 
1766
 
/*
1767
 
 *-----------------------------------------------------------------------------
1768
 
 *
1769
 
 * utf::string::startsWith --
1770
 
 *
1771
 
 *      Tests if the current string starts with 's'
1772
 
 *
1773
 
 * Results:
1774
 
 *      true if current string starts with 's', false otherwise
1775
 
 *
1776
 
 * Side effects:
1777
 
 *      None
1778
 
 *
1779
 
 *-----------------------------------------------------------------------------
1780
 
 */
1781
 
 
1782
 
bool
1783
 
string::startsWith(const string &s, // IN
1784
 
                   bool ignoreCase) // IN/OPT: false by default
1785
 
   const
1786
 
{
1787
 
   return UnicodeStartsWith(c_str(), s.c_str(), ignoreCase);
1788
 
}
1789
 
 
1790
 
 
1791
 
/*
1792
 
 *-----------------------------------------------------------------------------
1793
 
 *
1794
 
 * utf::string::endsWith --
1795
 
 *
1796
 
 *      Tests if the current string ends with 's'
1797
 
 *
1798
 
 * Results:
1799
 
 *      true if current string ends with 's', false otherwise
1800
 
 *
1801
 
 * Side effects:
1802
 
 *      None
1803
 
 *
1804
 
 *-----------------------------------------------------------------------------
1805
 
 */
1806
 
 
1807
 
bool
1808
 
string::endsWith(const string &s, // IN
1809
 
                 bool ignoreCase) // IN/OPT: false by default
1810
 
   const
1811
 
{
1812
 
   return UnicodeEndsWith(c_str(), s.c_str(), ignoreCase);
1813
 
}
1814
 
 
1815
 
 
1816
 
/*
1817
 
 *-----------------------------------------------------------------------------
1818
 
 *
1819
 
 * utf::string::split --
1820
 
 *
1821
 
 *      Return a vector of utf::strings.  The vector contains the elements of
1822
 
 *      the string split by the passed in separator. Empty tokens are not
1823
 
 *      skipped.
1824
 
 *
1825
 
 *      "1,2,3".split(",") -> ["1", "2", "3"]
1826
 
 *      "1,,".split(",") -> ["1", "", ""]
1827
 
 *      "1".split(",") -> ["1"]
1828
 
 *
1829
 
 *      XXX If this is to be used for things like command line parsing, support
1830
 
 *      for quoted strings needs to be added.
1831
 
 *
1832
 
 * Results:
1833
 
 *      A vector of utf::strings
1834
 
 *
1835
 
 * Side effects:
1836
 
 *      None
1837
 
 *
1838
 
 *-----------------------------------------------------------------------------
1839
 
 */
1840
 
 
1841
 
std::vector<string>
1842
 
string::split(const string &sep) // IN
1843
 
   const
1844
 
{
1845
 
   std::vector<string> splitStrings;
1846
 
   size_type sIndex = 0;
1847
 
   size_type sepLen = sep.length();
1848
 
 
1849
 
   ASSERT(sepLen > 0);
1850
 
 
1851
 
   while (true) {
1852
 
      size_type index = find(sep, sIndex);
1853
 
      if (index == npos) {
1854
 
         splitStrings.push_back(substr(sIndex));
1855
 
         break;
1856
 
      }
1857
 
 
1858
 
      splitStrings.push_back(substr(sIndex, index - sIndex));
1859
 
      sIndex = index + sepLen;
1860
 
   }
1861
 
 
1862
 
   return splitStrings;
1863
 
}
1864
 
 
1865
 
 
1866
 
/*
1867
 
 *-----------------------------------------------------------------------------
1868
 
 *
1869
 
 * utf::string::GetUtf16Cache --
1870
 
 *
1871
 
 *      Return the UTF-16 representation of the current string, this value is
1872
 
 *      cached, in the object.  If the cache is not valid (NULL), then create
1873
 
 *      the cache value
1874
 
 *
1875
 
 * Results:
1876
 
 *      A UTF-16 representation of the current string
1877
 
 *
1878
 
 * Side effects:
1879
 
 *      Allocates a UTF16 string
1880
 
 *
1881
 
 *-----------------------------------------------------------------------------
1882
 
 */
1883
 
 
1884
 
const utf16_t *
1885
 
string::GetUtf16Cache()
1886
 
   const
1887
 
{
1888
 
   if (mUtf16Cache == NULL) {
1889
 
      mUtf16Cache = Unicode_GetAllocUTF16(c_str());
1890
 
   }
1891
 
 
1892
 
   return mUtf16Cache;
1893
 
}
1894
 
 
1895
 
 
1896
 
/*
1897
 
 *-----------------------------------------------------------------------------
1898
 
 *
1899
 
 * utf::string::InvalidateCache --
1900
 
 *
1901
 
 *      Frees the cache in this string.
1902
 
 *
1903
 
 * Results:
1904
 
 *      None
1905
 
 *
1906
 
 * Side effects:
1907
 
 *      None
1908
 
 *
1909
 
 *-----------------------------------------------------------------------------
1910
 
 */
1911
 
 
1912
 
void
1913
 
string::InvalidateCache()
1914
 
{
1915
 
   free(mUtf16Cache);
1916
 
   mUtf16Cache = NULL;
1917
 
   mUtf16Length = npos;
1918
 
}
1919
 
 
1920
 
 
1921
 
/*
1922
 
 *-----------------------------------------------------------------------------
1923
 
 *
1924
 
 * utf::string::operator+ --
1925
 
 *
1926
 
 *      Create a new string by appending the input string to this string.
1927
 
 *
1928
 
 *      NOTE: This is not the same as append.  append() will modify the
1929
 
 *      current object, while this will return a new object.
1930
 
 *
1931
 
 * Results:
1932
 
 *      The newly created string.
1933
 
 *
1934
 
 * Side effects:
1935
 
 *      None
1936
 
 *
1937
 
 *-----------------------------------------------------------------------------
1938
 
 */
1939
 
 
1940
 
string
1941
 
string::operator+(const string &rhs)     // IN
1942
 
   const
1943
 
{
1944
 
   return mUstr + rhs.mUstr;
1945
 
}
1946
 
 
1947
 
 
1948
 
string
1949
 
string::operator+(value_type uc)        // IN
1950
 
   const
1951
 
{
1952
 
   return mUstr + uc;
1953
 
}
1954
 
 
1955
 
 
1956
 
/*
1957
 
 *-----------------------------------------------------------------------------
1958
 
 *
1959
 
 * utf::string::operator== --
1960
 
 *
1961
 
 *      Equality operator for string objects
1962
 
 *
1963
 
 * Results:
1964
 
 *      true or false (true if equal)
1965
 
 *
1966
 
 * Side effects:
1967
 
 *      None
1968
 
 *
1969
 
 *-----------------------------------------------------------------------------
1970
 
 */
1971
 
 
1972
 
bool
1973
 
string::operator==(const string &rhs)     // IN
1974
 
   const
1975
 
{
1976
 
   return compare(rhs) == 0;
1977
 
}
1978
 
 
1979
 
 
1980
 
/*
1981
 
 *-----------------------------------------------------------------------------
1982
 
 *
1983
 
 * utf::string::operator!= --
1984
 
 *
1985
 
 *      Inequality operator for string objects
1986
 
 *
1987
 
 * Results:
1988
 
 *      true or false (true if not equal)
1989
 
 *
1990
 
 * Side effects:
1991
 
 *      None
1992
 
 *
1993
 
 *-----------------------------------------------------------------------------
1994
 
 */
1995
 
 
1996
 
bool
1997
 
string::operator!=(const string &rhs)     // IN
1998
 
   const
1999
 
{
2000
 
   return compare(rhs) != 0;
2001
 
}
2002
 
 
2003
 
 
2004
 
/*
2005
 
 *-----------------------------------------------------------------------------
2006
 
 *
2007
 
 * utf::string::operator< --
2008
 
 *
2009
 
 *      Less than operator for string objects
2010
 
 *
2011
 
 * Results:
2012
 
 *      true or false (true if lhs is < rhs)
2013
 
 *
2014
 
 * Side effects:
2015
 
 *      None
2016
 
 *
2017
 
 *-----------------------------------------------------------------------------
2018
 
 */
2019
 
 
2020
 
bool
2021
 
string::operator<(const string &rhs)     // IN
2022
 
   const
2023
 
{
2024
 
   return compare(rhs) < 0;
2025
 
}
2026
 
 
2027
 
 
2028
 
/*
2029
 
 *-----------------------------------------------------------------------------
2030
 
 *
2031
 
 * utf::string::operator> --
2032
 
 *
2033
 
 *      Greater than operator for string objects
2034
 
 *
2035
 
 * Results:
2036
 
 *      true or false (true if lhs is > rhs)
2037
 
 *
2038
 
 * Side effects:
2039
 
 *      None
2040
 
 *
2041
 
 *-----------------------------------------------------------------------------
2042
 
 */
2043
 
 
2044
 
bool
2045
 
string::operator>(const string &rhs)     // IN
2046
 
   const
2047
 
{
2048
 
   return compare(rhs) > 0;
2049
 
}
2050
 
 
2051
 
 
2052
 
/*
2053
 
 *-----------------------------------------------------------------------------
2054
 
 *
2055
 
 * utf::string::operator<= --
2056
 
 *
2057
 
 *      Less than or equal than operator for string objects
2058
 
 *
2059
 
 * Results:
2060
 
 *      true or false (true if lhs is <= rhs)
2061
 
 *
2062
 
 * Side effects:
2063
 
 *      None
2064
 
 *
2065
 
 *-----------------------------------------------------------------------------
2066
 
 */
2067
 
 
2068
 
bool
2069
 
string::operator<=(const string &rhs)     // IN
2070
 
   const
2071
 
{
2072
 
   return compare(rhs) <= 0;
2073
 
}
2074
 
 
2075
 
 
2076
 
/*
2077
 
 *-----------------------------------------------------------------------------
2078
 
 *
2079
 
 * utf::string::operator>= --
2080
 
 *
2081
 
 *      Greater than or equal than operator for string objects
2082
 
 *
2083
 
 * Results:
2084
 
 *      true or false (true if lhs is >= rhs)
2085
 
 *
2086
 
 * Side effects:
2087
 
 *      None
2088
 
 *
2089
 
 *-----------------------------------------------------------------------------
2090
 
 */
2091
 
 
2092
 
bool
2093
 
string::operator>=(const string &rhs)     // IN
2094
 
   const
2095
 
{
2096
 
   return compare(rhs) >= 0;
2097
 
}
2098
 
 
2099
 
 
2100
 
/*
2101
 
 *-----------------------------------------------------------------------------
2102
 
 *
2103
 
 * utf::string::begin --
2104
 
 *
2105
 
 *      Returns an iterator to the start of the string.
2106
 
 *
2107
 
 * Results:
2108
 
 *      iterator
2109
 
 *
2110
 
 * Side effects:
2111
 
 *      None
2112
 
 *
2113
 
 *-----------------------------------------------------------------------------
2114
 
 */
2115
 
 
2116
 
string::iterator
2117
 
string::begin()
2118
 
{
2119
 
   return mUstr.begin();
2120
 
}
2121
 
 
2122
 
 
2123
 
string::const_iterator
2124
 
string::begin()
2125
 
   const
2126
 
{
2127
 
   return mUstr.begin();
2128
 
}
2129
 
 
2130
 
 
2131
 
/*
2132
 
 *-----------------------------------------------------------------------------
2133
 
 *
2134
 
 * utf::string::end --
2135
 
 *
2136
 
 *      Returns an iterator to the end of the string.
2137
 
 *
2138
 
 * Results:
2139
 
 *      iterator
2140
 
 *
2141
 
 * Side effects:
2142
 
 *      None
2143
 
 *
2144
 
 *-----------------------------------------------------------------------------
2145
 
 */
2146
 
 
2147
 
string::iterator
2148
 
string::end()
2149
 
{
2150
 
   return mUstr.end();
2151
 
}
2152
 
 
2153
 
 
2154
 
string::const_iterator
2155
 
string::end()
2156
 
   const
2157
 
{
2158
 
   return mUstr.end();
2159
 
}
2160
 
 
2161
 
 
2162
 
/*
2163
 
 *-----------------------------------------------------------------------------
2164
 
 *
2165
 
 * utf::Validate --
2166
 
 *
2167
 
 *      Validates the string.
2168
 
 *
2169
 
 * Results:
2170
 
 *      true if the string contains is valid UTF-8, false otherwise.
2171
 
 *
2172
 
 * Side effects:
2173
 
 *      None
2174
 
 *
2175
 
 *-----------------------------------------------------------------------------
2176
 
 */
2177
 
 
2178
 
bool
2179
 
Validate(const Glib::ustring& s) // IN
2180
 
{
2181
 
   bool isValid = s.validate();
2182
 
   if (!isValid) {
2183
 
      char *escaped = Unicode_EscapeBuffer(s.c_str(), -1, STRING_ENCODING_UTF8);
2184
 
      Warning("Invalid UTF-8 string: \"%s\"\n", escaped);
2185
 
      free(escaped);
2186
 
   }
2187
 
   return isValid;
2188
 
}
2189
 
 
2190
 
 
2191
 
/*
2192
 
 *-----------------------------------------------------------------------------
2193
 
 *
2194
 
 * utf::CreateWithLength --
2195
 
 *
2196
 
 *      A wrapper function for Unicode_AllocWithLength() that returns a utf::string.
2197
 
 *
2198
 
 * Results:
2199
 
 *      A utf::string created with given parameters.
2200
 
 *
2201
 
 * Side effects:
2202
 
 *      None
2203
 
 *
2204
 
 *-----------------------------------------------------------------------------
2205
 
 */
2206
 
 
2207
 
string
2208
 
CreateWithLength(const void *buffer,      // IN
2209
 
                 ssize_t lengthInBytes,   // IN: NUL not included
2210
 
                 StringEncoding encoding) // IN
2211
 
{
2212
 
   if (!Unicode_IsBufferValid(buffer, lengthInBytes, encoding)) {
2213
 
      throw ConversionError();
2214
 
   }
2215
 
 
2216
 
   Unicode utf8 = Unicode_AllocWithLength(buffer, lengthInBytes, encoding);
2217
 
 
2218
 
   try {
2219
 
      string result(utf8);
2220
 
      Unicode_Free(utf8);
2221
 
      return result;
2222
 
   } catch (...) {
2223
 
      Unicode_Free(utf8);
2224
 
      throw;
2225
 
   }
2226
 
}
2227
 
 
2228
 
 
2229
 
/*
2230
 
 *----------------------------------------------------------------------
2231
 
 *
2232
 
 * utf::CreateWithBOMBuffer --
2233
 
 *
2234
 
 *       Convert a text buffer with BOM (byte-order mark) to utf::string.
2235
 
 *       If BOM not present, assume it's UTF-8.
2236
 
 *
2237
 
 * Results:
2238
 
 *       A utf::string containing the text buffer.
2239
 
 *
2240
 
 * Side Effect:
2241
 
 *       None.
2242
 
 *
2243
 
 *----------------------------------------------------------------------
2244
 
 */
2245
 
 
2246
 
string
2247
 
CreateWithBOMBuffer(const void *buffer,      // IN
2248
 
                    ssize_t lengthInBytes)   // IN: NUL not included
2249
 
{
2250
 
   struct BOMMap {
2251
 
      uint8 bom[4];              // BOM with max size.
2252
 
      ssize_t len;               // Length of BOM.
2253
 
      StringEncoding encoding;   // Encoding if a BOM is present.
2254
 
   };
2255
 
 
2256
 
   static const BOMMap mapBOM[] = {
2257
 
      {{0}, 0,                      STRING_ENCODING_UTF8     }, // Default encoding.
2258
 
      {{0xEF, 0xBB, 0xBF}, 3,       STRING_ENCODING_UTF8     },
2259
 
      {{0xFE, 0xFF}, 2,             STRING_ENCODING_UTF16_BE },
2260
 
      {{0xFF, 0xFE}, 2,             STRING_ENCODING_UTF16_LE },
2261
 
      {{0x00, 0x00, 0xFE, 0xFF}, 4, STRING_ENCODING_UTF32_BE },
2262
 
      {{0xFF, 0xFE, 0x00, 0x00}, 4, STRING_ENCODING_UTF32_LE }
2263
 
   };
2264
 
 
2265
 
   ASSERT(lengthInBytes >= 0);
2266
 
   unsigned int index = 0; // Default encoding, no need to check.
2267
 
   for (unsigned int i = 1; i < ARRAYSIZE(mapBOM); i++) {
2268
 
      if (   lengthInBytes >= mapBOM[i].len
2269
 
          && memcmp(mapBOM[i].bom, buffer, mapBOM[i].len) == 0) {
2270
 
         index = i;
2271
 
         break;
2272
 
      }
2273
 
   }
2274
 
 
2275
 
   return CreateWithLength(reinterpret_cast<const char*>(buffer) + mapBOM[index].len,
2276
 
                           lengthInBytes - mapBOM[index].len,
2277
 
                           mapBOM[index].encoding);
2278
 
}
2279
 
 
2280
 
 
2281
 
/*
2282
 
 *-----------------------------------------------------------------------------
2283
 
 *
2284
 
 * utf::IntToStr --
2285
 
 *
2286
 
 *      Converts an integer to a utf::string.
2287
 
 *
2288
 
 * Results:
2289
 
 *      A utf::string created with the given integer.
2290
 
 *
2291
 
 * Side effects:
2292
 
 *      None
2293
 
 *
2294
 
 *-----------------------------------------------------------------------------
2295
 
 */
2296
 
 
2297
 
string
2298
 
IntToStr(int64 val) // IN
2299
 
{
2300
 
   std::ostringstream ostream;
2301
 
   ostream << val;
2302
 
   return ostream.str().c_str();
2303
 
}
2304
 
 
2305
 
 
2306
 
/*
2307
 
 *-----------------------------------------------------------------------------
2308
 
 *
2309
 
 * utf::CopyArray --
2310
 
 *
2311
 
 *      Copies an array to a vector.
2312
 
 *
2313
 
 * Results:
2314
 
 *      A vector containing a shallow copy of the array.
2315
 
 *
2316
 
 * Side effects:
2317
 
 *      None
2318
 
 *
2319
 
 *-----------------------------------------------------------------------------
2320
 
 */
2321
 
 
2322
 
template<typename T>
2323
 
static void
2324
 
CopyArray(const T *p,          // IN:
2325
 
          size_t n,            // IN: The number of array elements to copy.
2326
 
          std::vector<T>& buf) // OUT:
2327
 
{
2328
 
   buf.resize(n);
2329
 
   if (!buf.empty()) {
2330
 
      ASSERT(p != NULL);
2331
 
      memcpy(&buf[0], p, buf.size() * sizeof buf[0]);
2332
 
   }
2333
 
}
2334
 
 
2335
 
 
2336
 
/*
2337
 
 *-----------------------------------------------------------------------------
2338
 
 *
2339
 
 * utf::CreateWritableBuffer --
2340
 
 *
2341
 
 *      Copies a utf::string to a writable buffer.
2342
 
 *
2343
 
 * Results:
2344
 
 *      A std::vector containing the string data.
2345
 
 *
2346
 
 * Side effects:
2347
 
 *      None
2348
 
 *
2349
 
 *-----------------------------------------------------------------------------
2350
 
 */
2351
 
 
2352
 
void
2353
 
CreateWritableBuffer(const string& s,        // IN:
2354
 
                     std::vector<char>& buf) // OUT: A copy of the string, as UTF-8.
2355
 
{
2356
 
   CopyArray(s.c_str(), s.bytes() + 1, buf);
2357
 
}
2358
 
 
2359
 
 
2360
 
void
2361
 
CreateWritableBuffer(const string& s,           // IN:
2362
 
                     std::vector<utf16_t>& buf) // OUT: A copy of the string, as UTF-16.
2363
 
{
2364
 
   CopyArray(s.w_str(), s.w_size() + 1, buf);
2365
 
}
2366
 
 
2367
 
 
2368
 
} // namespace utf