Coverage Report

Created: 2026-03-31 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/ofstd/libsrc/ofstring.cc
Line
Count
Source
1
/*
2
 *
3
 *  Copyright (C) 1997-2023, OFFIS e.V.
4
 *  All rights reserved.  See COPYRIGHT file for details.
5
 *
6
 *  This software and supporting documentation were developed by
7
 *
8
 *    OFFIS e.V.
9
 *    R&D Division Health
10
 *    Escherweg 2
11
 *    D-26121 Oldenburg, Germany
12
 *
13
 *
14
 *  Module:  ofstd
15
 *
16
 *  Author:  Andrew Hewett
17
 *
18
 *  Purpose: A simple string class
19
 *
20
 */
21
22
23
/*
24
** A simple string class
25
** - for OFFIS projects when an ANSI string class is not always available
26
** - based on the ANSI-C++ specifications
27
** - this implementation is intended to be slow but reliable
28
** - it is known to be slow but is it reliable?
29
*/
30
31
#include "dcmtk/config/osconfig.h"     /* include OS specific configuration first */
32
33
#ifndef HAVE_STL_STRING
34
35
#include "dcmtk/ofstd/ofstring.h"
36
#include "dcmtk/ofstd/ofcast.h"
37
#include "dcmtk/ofstd/ofbmanip.h"
38
#include "dcmtk/ofstd/oftypes.h"
39
#include "dcmtk/ofstd/ofstd.h"
40
#include "dcmtk/ofstd/ofdiag.h"
41
42
static const char* verify_string(const char *s)
43
138
{
44
138
    if (s == NULL)
45
0
    {
46
#ifdef DEBUG
47
        fprintf(stderr, "WARNING: OFString constructed from NULL, this is deprecated.\n");
48
#endif
49
0
#ifdef USE_NULL_SAFE_OFSTRING
50
0
        s = "";
51
0
#endif
52
0
    }
53
138
    return s;
54
138
}
55
56
/*
57
** Constructors
58
*/
59
60
OFString::OFString()
61
117
    : theCString(NULL), theSize(0), theCapacity(0)
62
117
{
63
117
    reserve(1);
64
117
}
65
66
OFString::OFString(const OFString& str, size_t pos, size_t n)
67
238
    : theCString(NULL), theSize(0), theCapacity(0)
68
238
{
69
238
    this->assign(str, pos, n);
70
238
}
71
72
OFString::OFString (const char* s, size_t n)
73
0
    : theCString(NULL), theSize(0), theCapacity(0)
74
0
{
75
0
    s = verify_string(s);
76
0
    if (n == OFString_npos) {
77
0
        n = strlen(s);
78
0
    }
79
0
    reserve(n);
80
0
    OFBitmanipTemplate<char>::copyMem(s, this->theCString, n);
81
0
    this->theCString[n] = '\0';
82
0
    this->theSize = n;
83
0
}
84
85
OFString::OFString (const char* s)
86
138
    : theCString(NULL), theSize(0), theCapacity(0)
87
138
{
88
138
    s = verify_string(s);
89
138
    const size_t n = strlen(s);
90
138
    reserve(n);
91
    // Because we used strlen() to figure out the length we can use strlcpy()
92
    // since there won't be any '\0' bytes in the string.
93
    // The amount of memory allocated is always theCapacity+1
94
    // because one extra byte is always allocated for the eos zero byte.
95
138
    OFStandard::strlcpy(this->theCString, s, this->theCapacity+1);
96
138
    this->theSize = n;
97
138
}
98
99
100
OFString::OFString (size_t rep, char c)
101
30
    : theCString(NULL), theSize(0), theCapacity(0)
102
30
{
103
30
    reserve(rep);
104
60
    for (size_t i = 0; i < rep; i++) {
105
30
        this->theCString[i] = c;
106
30
    }
107
30
    this->theCString[rep] = '\0';
108
30
    this->theSize = rep;
109
30
}
110
111
/*
112
** Destructor
113
*/
114
115
OFString::~OFString()
116
256
{
117
256
    if (theCString) {
118
256
        delete[] theCString;
119
256
        theCString = NULL;
120
256
    }
121
256
}
122
123
/*
124
** Operator =
125
*/
126
127
OFString&
128
OFString::operator= (const OFString& rhs)
129
3
{
130
3
    this->assign(rhs);
131
3
    return *this;
132
3
}
133
134
OFString&
135
OFString::operator= (const char* s)
136
0
{
137
0
    this->assign(s);
138
0
    return *this;
139
0
}
140
141
OFString&
142
OFString::operator= (char s)
143
0
{
144
0
    this->assign(1, s);
145
0
    return *this;
146
0
}
147
148
/*
149
** Operator +=
150
*/
151
152
OFString&
153
OFString::operator+= (const OFString& rhs)
154
0
{
155
0
    return this->append(rhs);
156
0
}
157
158
OFString&
159
OFString::operator+= (const char* s)
160
0
{
161
0
    return this->append(s);
162
0
}
163
164
OFString&
165
OFString::operator+= (char s)
166
24
{
167
24
    return this->append(1, s);
168
24
}
169
170
/*
171
** Append
172
*/
173
174
OFString&
175
OFString::append (const OFString& str, size_t pos, size_t n)
176
56
{
177
56
    OFString b(str, pos, n);
178
56
    this->reserve(this->size() + b.size());
179
    // We can't use strcat() because some string could contain NULL bytes
180
    // We need size() + 1 so that the EOS mark is copied over, too
181
56
    OFBitmanipTemplate<char>::copyMem(b.theCString, this->theCString + this->size(), b.size() + 1);
182
56
    this->theSize += b.size();
183
184
56
    return *this;
185
56
}
186
187
OFString&
188
OFString::append (const char* s, size_t n)
189
0
{
190
0
    OFString str(s, n);
191
0
    return this->append(str);
192
0
}
193
194
OFString&
195
OFString::append (const char* s)
196
0
{
197
0
    OFString str(s);
198
0
    return this->append(str);
199
0
}
200
201
OFString&
202
OFString::append (size_t rep, char c)
203
24
{
204
24
    OFString str(rep, c);
205
24
    return this->append(str);
206
24
}
207
208
/*
209
** Assign
210
*/
211
212
OFString&
213
OFString::assign (const OFString& str, size_t pos, size_t n)
214
276
{
215
276
    OFSTRING_OUTOFRANGE(pos > str.size());
216
276
    const size_t remain = (str.size() - pos);
217
276
    if ((n == OFString_npos) || (n > remain)) {
218
241
        n = remain;
219
241
    }
220
276
    if (n > 0) {
221
180
        this->reserve(n);
222
        // Someone could try to assign a string to itself, but strncpy() must
223
        // not be called on overlapping memory areas, therefore, we use moveMem().
224
180
        OFBitmanipTemplate<char>::moveMem(str.theCString + pos, this->theCString, n);
225
180
        this->theCString[n] = '\0';
226
180
        this->theSize = n;
227
180
    } else {
228
96
        this->reserve(1);
229
        /* assign an empty string */
230
96
        this->theCString[0] = '\0';
231
96
        this->theSize = 0;
232
96
    }
233
276
    return *this;
234
276
}
235
236
OFString&
237
OFString::assign (const OFString& str)
238
35
{
239
35
    return assign(str, 0, OFString_npos);
240
35
}
241
242
OFString&
243
OFString::assign (const char* s, size_t n)
244
0
{
245
0
    OFString str(s, n);
246
0
    return this->assign(str);
247
0
}
248
249
OFString&
250
OFString::assign (const char* s)
251
0
{
252
0
    OFString str(s);
253
0
    return this->assign(str);
254
0
}
255
256
OFString&
257
OFString::assign (const char* s, const char *e)
258
0
{
259
0
    OFString str(s, e - s);
260
0
    return this->assign(str);
261
0
}
262
263
OFString&
264
OFString::assign (size_t rep, char c)
265
0
{
266
0
    OFString str(rep, c);
267
0
    return this->assign(str);
268
0
}
269
270
/*
271
** Insert
272
*/
273
274
OFString&
275
OFString::insert (size_t pos1, const OFString& str, size_t pos2, size_t n)
276
0
{
277
0
    OFString i(str, pos2, n);
278
0
    OFString a(*this, OFstatic_cast(size_t, 0), pos1);
279
0
    OFString b(*this, pos1);
280
0
    return this->assign(a).append(i).append(b);
281
0
}
282
283
OFString&
284
OFString::insert (size_t pos, const char* s, size_t n)
285
0
{
286
0
    OFString str(s, n);
287
0
    return this->insert(pos, str);
288
0
}
289
290
OFString&
291
OFString::insert (size_t pos, const char* s)
292
0
{
293
0
    OFString str(s);
294
0
    return this->insert(pos, str);
295
0
}
296
297
OFString&
298
OFString::insert (size_t pos, size_t rep, char s)
299
0
{
300
0
    OFString str(rep, s);
301
0
    return this->insert(pos, str);
302
0
}
303
304
/*
305
** Erase
306
*/
307
OFString&
308
OFString::erase (size_t pos, size_t n)
309
32
{
310
32
    OFString a(*this, 0, pos);
311
32
    OFString b;
312
32
    if (n != OFString_npos) {
313
0
        b.assign(*this, pos + n, OFString_npos);
314
0
    }
315
32
    return this->assign(a).append(b);
316
32
}
317
318
/*
319
** Replace
320
*/
321
322
OFString&
323
OFString::replace (size_t pos1, size_t n1, const OFString& str,
324
                   size_t pos2, size_t n2)
325
0
{
326
0
    OFString a(*this, OFstatic_cast(size_t, 0), pos1);
327
0
    OFString b;
328
0
    if ((n1 < OFString_npos) && ((pos1 + n1) < this->size())) {
329
0
        b.assign(*this, pos1 + n1, OFString_npos);
330
0
    }
331
0
    OFString i(str, pos2, n2);
332
0
    return this->assign(a).append(i).append(b);
333
0
}
334
335
OFString&
336
OFString::replace (size_t pos, size_t n, const char* s, size_t n2)
337
0
{
338
0
    OFString str(s, n2);
339
0
    return this->replace(pos, n, str);
340
0
}
341
342
OFString&
343
OFString::replace (size_t pos, size_t n, const char* s)
344
0
{
345
0
    OFString str(s);
346
0
    return this->replace(pos, n, str);
347
0
}
348
349
OFString&
350
OFString::replace (size_t pos, size_t n, size_t rep, char s)
351
0
{
352
0
    OFString str(rep, s);
353
0
    return this->replace(pos, n, str);
354
0
}
355
356
357
/*
358
** Data
359
*/
360
361
const char*
362
OFString::data () const
363
0
{
364
0
    return (this->size() != 0) ? this->c_str() : "";
365
0
}
366
367
368
/*
369
** Resize
370
*/
371
372
void
373
OFString::resize (size_t n, char c)
374
18
{
375
18
    OFSTRING_LENGTHERROR(n == OFString_npos);
376
377
18
    reserve(n);
378
18
    const size_t len = this->size();
379
18
    if (n <= len) {
380
42
        for (size_t i = n; i < len; i++) {
381
24
            this->theCString[i] = '\0';
382
24
        }
383
18
    } else {
384
0
        for (size_t i = len; i < n; i++) {
385
0
            this->theCString[i] = c;
386
0
        }
387
0
        this->theCString[n] = '\0';
388
0
    }
389
18
    this->theSize = n;
390
18
}
391
392
/*
393
** Reserve
394
*/
395
396
void
397
OFString::reserve (size_t res_arg)
398
635
{
399
635
    if (res_arg == OFString_npos) {
400
0
        res_arg = 0; /* let at least space for eos get reserved */
401
0
    }
402
635
    res_arg++; /* add space for eos */
403
635
    if (this->theCapacity < res_arg) {
404
576
        char* newstr = new char[res_arg];
405
576
        if (newstr) {
406
576
            size_t usedSpace = 0;
407
576
            this->theCapacity = res_arg - 1; /* not the eos */
408
576
            if (this->size() > 0) {
409
12
                const size_t len = size();
410
                // copyMem() because theCString could have null bytes
411
12
                OFBitmanipTemplate<char>::copyMem(this->theCString, newstr, len);
412
12
                usedSpace = len;
413
12
            }
414
// suppress spurious gcc 12 warning
415
576
#include DCMTK_DIAGNOSTIC_PUSH
416
576
#include DCMTK_DIAGNOSTIC_IGNORE_STRINGOP_OVERFLOW
417
576
            OFBitmanipTemplate<char>::zeroMem(newstr + usedSpace, res_arg - usedSpace);
418
576
#include DCMTK_DIAGNOSTIC_POP
419
576
            char* oldstr = this->theCString;
420
576
            this->theCString = newstr;
421
576
            delete[] oldstr;
422
576
        } else {
423
0
            OFSTRING_MEMORYALLOCERROR(newstr);
424
0
        }
425
576
    }
426
635
}
427
428
/*
429
** Copy
430
*/
431
432
size_t
433
OFString::copy (char* s, size_t n, size_t pos) const
434
0
{
435
0
    OFString sub(this->substr(pos, n));
436
0
    const size_t result = sub.size();
437
438
    // The string could have NULL bytes so no strncpy()
439
0
    OFBitmanipTemplate<char>::copyMem(sub.theCString, s, result);
440
0
    return result;
441
0
}
442
443
/*
444
** Substr
445
*/
446
447
OFString
448
OFString::substr (size_t pos, size_t n) const
449
0
{
450
0
    OFString sub;
451
0
    return sub.assign(*this, pos, n);
452
0
}
453
454
/*
455
** Swap
456
*/
457
458
void
459
OFString::swap(OFString& s)
460
0
{
461
0
    char* tmpCString = s.theCString;
462
0
    s.theCString = this->theCString;
463
0
    this->theCString = tmpCString;
464
465
0
    size_t tmpSize = s.theSize;
466
0
    s.theSize = this->theSize;
467
0
    this->theSize = tmpSize;
468
469
0
    size_t tmpCapacity = s.theCapacity;
470
0
    s.theCapacity = this->theCapacity;
471
0
    this->theCapacity = tmpCapacity;
472
0
}
473
474
/*
475
** Compare
476
*/
477
478
int
479
OFString::compare (const OFString& str) const
480
267
{
481
267
    const size_t this_size = this->size();
482
267
    const size_t str_size = str.size();
483
267
    const size_t rlen = (this_size < str_size) ? this_size : str_size;
484
    // Our string could contain null bytes and thus we can't use strncmp()
485
267
    int result = memcmp(this->theCString, str.theCString, rlen);
486
267
    if (result == 0) {
487
3
        result = this_size < str_size ? -1 : this_size > str_size ? 1 : 0;
488
3
    }
489
267
    return result;
490
267
}
491
492
int
493
OFString::compare (size_t pos1, size_t n1, const OFString& str) const
494
0
{
495
0
    return OFString(*this, pos1, n1).compare(str);
496
0
}
497
498
int
499
OFString::compare (size_t pos1, size_t n1, const OFString& str,
500
                   size_t pos2, size_t n2) const
501
0
{
502
0
    return OFString(*this, pos1, n1).compare(OFString(str, pos2, n2));
503
0
}
504
505
int
506
OFString::compare (const char* s) const
507
0
{
508
0
    return this->compare(OFString(s));
509
0
}
510
511
int
512
OFString::compare (size_t pos1, size_t n1,
513
                   const char* s, size_t n2) const
514
0
{
515
0
    return OFString(*this, pos1, n1).compare(OFString(s, n2));
516
0
}
517
518
/*
519
** Find
520
*/
521
522
size_t
523
OFString::find (const OFString& pattern, size_t pos) const
524
0
{
525
    /* determine string length only once */
526
0
    const size_t this_size = this->size();
527
0
    const size_t pattern_size = pattern.size();
528
0
    if ((this_size == 0) || (pattern_size == 0) || (pos == OFString_npos)) {
529
0
        return OFString_npos;
530
0
    }
531
0
    for (size_t i = pos; i < this_size; i++) {
532
        /* is there enough space for the pattern? */
533
0
        if ((i + pattern_size) > this_size) {
534
0
            return OFString_npos;
535
0
        }
536
0
        int match = 1; /* assume there is a match */
537
0
        for (size_t j = 0; (j < pattern_size) && match; j++) {
538
0
            if (this->at(i + j) != pattern[j]) {
539
0
                match = 0;
540
0
            }
541
0
        }
542
0
        if (match) {
543
0
            return i;
544
0
        }
545
0
    }
546
0
    return OFString_npos;
547
0
}
548
549
size_t
550
OFString::find (const char* pattern, size_t pos, size_t n) const
551
0
{
552
0
    OFString str(pattern, n);
553
0
    return this->find(str, pos);
554
0
}
555
556
size_t
557
OFString::find (const char* pattern, size_t pos) const
558
0
{
559
0
    OFString str(pattern);
560
0
    return this->find(str, pos);
561
0
}
562
563
size_t
564
OFString::find (char pattern, size_t pos) const
565
0
{
566
0
    size_t i = pos;
567
0
    const size_t this_size = this->size();
568
0
    while ((i < this_size) && (this->at(i) != pattern))
569
0
        i++;
570
0
    return (i < this_size) ? i : OFString_npos;
571
0
}
572
573
/*
574
** Rfind
575
*/
576
577
size_t
578
OFString::rfind (const OFString& pattern, size_t pos) const
579
0
{
580
    /* determine string length only once */
581
0
    const size_t this_size = this->size();
582
0
    const size_t pattern_size = pattern.size();
583
0
    if ((this_size == 0) || (pattern_size == 0) || (this_size < pattern_size)) {
584
0
        return OFString_npos;
585
0
    }
586
0
    OFintptr_t above = ((this_size - pattern_size) < pos) ? (this_size - pattern_size) : pos;
587
0
    for (OFintptr_t i = above; i >= 0; --i) {
588
0
        int match = 1; /* assume there is a match */
589
0
        for (size_t j = 0; (j < pattern_size) && match; ++j) {
590
0
            if (this->at(i + j) != pattern[j]) {
591
0
                match = 0;
592
0
            }
593
0
        }
594
0
        if (match) {
595
0
            return OFstatic_cast(size_t, i); // if i were < 0, the for-loop would've been already left.
596
0
        }
597
0
    }
598
0
    return OFString_npos;
599
0
}
600
601
size_t
602
OFString::rfind (const char* pattern, size_t pos, size_t n) const
603
0
{
604
0
    OFString str(pattern, n);
605
0
    return this->rfind(str, pos);
606
0
}
607
608
size_t
609
OFString::rfind (const char* pattern, size_t pos) const
610
0
{
611
0
    OFString str(pattern);
612
0
    return this->rfind(str, pos);
613
0
}
614
615
size_t
616
OFString::rfind (char pattern, size_t pos) const
617
0
{
618
0
    OFString str(1, pattern);
619
0
    return this->rfind(str, pos);
620
0
}
621
622
/*
623
** Find_first_of
624
*/
625
626
size_t
627
OFString::find_first_of (const OFString& str, size_t pos) const
628
0
{
629
    /* determine string length only once */
630
0
    const size_t this_size = this->size();
631
0
    const size_t str_size = str.size();
632
0
    if ((this_size == 0) || (str_size == 0) || (pos == OFString_npos)) {
633
0
        return OFString_npos;
634
0
    }
635
0
    for (size_t i = pos; i < this_size; i++) {
636
0
        for (size_t j = 0; j < str_size; j++) {
637
0
            if (this->at(i) == str[j]) {
638
0
                return i;
639
0
            }
640
0
        }
641
0
    }
642
0
    return OFString_npos;
643
0
}
644
645
size_t
646
OFString::find_first_of (const char* s, size_t pos, size_t n) const
647
0
{
648
0
    OFString str(s, n);
649
0
    return this->find_first_of(str, pos);
650
0
}
651
652
size_t
653
OFString::find_first_of (const char* s, size_t pos) const
654
0
{
655
0
    OFString str(s);
656
0
    return this->find_first_of(str, pos);
657
0
}
658
659
size_t
660
OFString::find_first_of (char s, size_t pos) const
661
0
{
662
0
    OFString str(1, s);
663
0
    return this->find_first_of(str, pos);
664
0
}
665
666
/*
667
** Find_last_of
668
*/
669
670
size_t
671
OFString::find_last_of (const OFString& str, size_t pos) const
672
6
{
673
    /* determine string length only once */
674
6
    const size_t this_size = this->size();
675
6
    const size_t str_size = str.size();
676
6
    if ((this_size == 0) || (str_size == 0)) {
677
0
        return OFString_npos;
678
0
    }
679
6
    if ((pos == OFString_npos) || (pos > this_size)) {
680
0
        pos = this_size;
681
0
    }
682
36
    for (int i = OFstatic_cast(int, pos - 1); i >= 0; i--) {
683
63
        for (size_t j = 0; j < str_size; j++) {
684
33
            if (this->at(i) == str[j]) {
685
3
                return i;
686
3
            }
687
33
        }
688
33
    }
689
3
    return OFString_npos;
690
6
}
691
692
size_t
693
OFString::find_last_of (const char* s, size_t pos, size_t n) const
694
0
{
695
0
    OFString str(s, n);
696
0
    return this->find_last_of(str, pos);
697
0
}
698
699
size_t
700
OFString::find_last_of (const char* s, size_t pos) const
701
0
{
702
0
    OFString str(s);
703
0
    return this->find_last_of(str, pos);
704
0
}
705
706
size_t
707
OFString::find_last_of (char s, size_t pos) const
708
6
{
709
6
    OFString str(1, s);
710
6
    return this->find_last_of(str, pos);
711
6
}
712
713
/*
714
** Find_first_not_of
715
*/
716
717
size_t
718
OFString::find_first_not_of (const OFString& str, size_t pos) const
719
0
{
720
    /* determine string length only once */
721
0
    const size_t this_size = this->size();
722
0
    const size_t str_size = str.size();
723
0
    if ((this_size == 0) || (str_size == 0) || (pos == OFString_npos)) {
724
0
        return OFString_npos;
725
0
    }
726
0
    for (size_t i = pos; i < this_size; i++) {
727
0
        if (str.find(this->at(i)) == OFString_npos)
728
0
            return i;
729
0
    }
730
0
    return OFString_npos;
731
0
}
732
733
size_t
734
OFString::find_first_not_of (const char* s, size_t pos, size_t n) const
735
0
{
736
0
    OFString str(s, n);
737
0
    return this->find_first_not_of(str, pos);
738
0
}
739
740
size_t
741
OFString::find_first_not_of (const char* s, size_t pos) const
742
0
{
743
0
    OFString str(s);
744
0
    return this->find_first_not_of(str, pos);
745
0
}
746
747
size_t
748
OFString::find_first_not_of (char s, size_t pos) const
749
0
{
750
0
    OFString str(1, s);
751
0
    return this->find_first_not_of(str, pos);
752
0
}
753
754
/*
755
** Find_last_not_of
756
*/
757
758
size_t
759
OFString::find_last_not_of (const OFString& str, size_t pos) const
760
0
{
761
    /* determine string length only once */
762
0
    const size_t this_size = this->size();
763
0
    const size_t str_size = str.size();
764
0
    if ((this_size == 0) || (str_size == 0)) {
765
0
        return OFString_npos;
766
0
    }
767
0
    if (pos == OFString_npos) {
768
0
        pos = this_size;
769
0
    }
770
0
    for (int i = OFstatic_cast(int, pos - 1); i >= 0; i--) {
771
0
        if (str.find(this->at(i)) == OFString_npos)
772
0
            return i;
773
0
    }
774
0
    return OFString_npos;
775
0
}
776
777
size_t
778
OFString::find_last_not_of (const char* s, size_t pos, size_t n) const
779
0
{
780
0
    OFString str(s, n);
781
0
    return this->find_last_not_of(str, pos);
782
0
}
783
784
size_t
785
OFString::find_last_not_of (const char* s, size_t pos) const
786
0
{
787
0
    OFString str(s);
788
0
    return this->find_last_not_of(str, pos);
789
0
}
790
791
size_t
792
OFString::find_last_not_of (char s, size_t pos) const
793
0
{
794
0
    OFString str(1, s);
795
0
    return this->find_last_not_of(str, pos);
796
0
}
797
798
/*
799
** Operator <<
800
*/
801
802
STD_NAMESPACE ostream& operator<< (STD_NAMESPACE ostream& o, const OFString& s)
803
0
{
804
0
    return o.write (s.c_str(), s.size());
805
0
}
806
807
/*
808
** Operator >>
809
*/
810
811
STD_NAMESPACE istream& operator>> (STD_NAMESPACE istream& i, OFString& s)
812
0
{
813
// suppress spurious gcc 12 warning
814
0
#include DCMTK_DIAGNOSTIC_PUSH
815
0
#include DCMTK_DIAGNOSTIC_IGNORE_STRINGOP_OVERFLOW
816
0
    s.resize(0);
817
0
#include DCMTK_DIAGNOSTIC_POP
818
0
    char c = '\0';
819
0
    size_t n = s.max_size();
820
0
    if (i.width() > 0) {
821
0
        n = OFstatic_cast(size_t, i.width());
822
0
    }
823
    // skip white space before word
824
0
    i.get(c);
825
0
    while (i.good() && isspace(OFstatic_cast(unsigned char, c))) {
826
0
        i.get(c);
827
0
    }
828
    // get the word
829
0
    while (i.good() && !isspace(OFstatic_cast(unsigned char, c)) && n--) {
830
0
        s += c;
831
0
        i.get(c);
832
0
    }
833
0
    if (isspace(OFstatic_cast(unsigned char, c))) {
834
0
        i.putback(c);
835
0
    }
836
0
    i.width(0);
837
0
    return i;
838
0
}
839
840
/*
841
** Operator +
842
*/
843
844
OFString operator+ (const OFString& lhs, const OFString& rhs)
845
0
{
846
0
    OFString s(lhs);
847
0
    s += rhs;
848
0
    return s;
849
0
}
850
851
OFString operator+ (const char* lhs, const OFString& rhs)
852
0
{
853
0
    OFString s(lhs);
854
0
    s += rhs;
855
0
    return s;
856
0
}
857
858
OFString operator+ (char lhs, const OFString& rhs)
859
0
{
860
0
    OFString s(1, lhs);
861
0
    s += rhs;
862
0
    return s;
863
0
}
864
865
OFString operator+ (const OFString& lhs, const char* rhs)
866
0
{
867
0
    OFString s(lhs);
868
0
    s += rhs;
869
0
    return s;
870
0
}
871
872
OFString operator+ (const OFString& lhs, char rhs)
873
0
{
874
0
    OFString s(lhs);
875
0
    s += rhs;
876
0
    return s;
877
0
}
878
879
/*
880
** Operator ==
881
*/
882
883
OFBool operator== (const OFString& lhs, const OFString& rhs)
884
156
{
885
156
    return (lhs.compare(rhs) == 0) ? OFTrue : OFFalse;
886
156
}
887
888
OFBool operator== (const char* lhs, const OFString& rhs)
889
0
{
890
0
    OFString slhs(lhs);
891
0
    return (slhs == rhs);
892
0
}
893
894
OFBool operator== (char lhs, const OFString& rhs)
895
0
{
896
0
    OFString slhs(1, lhs);
897
0
    return (slhs == rhs);
898
0
}
899
900
OFBool operator== (const OFString& lhs, const char* rhs)
901
0
{
902
0
    OFString srhs(rhs);
903
0
    return (lhs == srhs);
904
0
}
905
906
OFBool operator== (const OFString& lhs, char rhs)
907
0
{
908
0
    OFString srhs(1, rhs);
909
0
    return (lhs == srhs);
910
0
}
911
912
/*
913
** Operator <
914
*/
915
916
OFBool operator< (const OFString& lhs, const OFString& rhs)
917
111
{
918
111
    return (lhs.compare(rhs) < 0) ? OFTrue : OFFalse;
919
111
}
920
921
OFBool operator< (const char* lhs, const OFString& rhs)
922
0
{
923
0
    OFString slhs(lhs);
924
0
    return (slhs < rhs);
925
0
}
926
927
OFBool operator< (char lhs, const OFString& rhs)
928
0
{
929
0
    OFString slhs(1, lhs);
930
0
    return (slhs < rhs);
931
0
}
932
933
OFBool operator< (const OFString& lhs, const char* rhs)
934
0
{
935
0
    OFString srhs(rhs);
936
0
    return (lhs < srhs);
937
0
}
938
939
OFBool operator< (const OFString& lhs, char rhs)
940
0
{
941
0
    OFString srhs(1, rhs);
942
0
    return (lhs < srhs);
943
0
}
944
945
/*
946
** Operator <=
947
*/
948
949
OFBool operator<= (const OFString& lhs, const OFString& rhs)
950
0
{
951
0
    return (!(rhs < lhs));
952
0
}
953
954
OFBool operator<= (const char* lhs, const OFString& rhs)
955
0
{
956
0
    return (!(rhs < lhs));
957
0
}
958
959
OFBool operator<= (char lhs, const OFString& rhs)
960
0
{
961
0
    return (!(rhs < lhs));
962
0
}
963
964
OFBool operator<= (const OFString& lhs, const char* rhs)
965
0
{
966
0
    return (!(rhs < lhs));
967
0
}
968
969
OFBool operator<= (const OFString& lhs, char rhs)
970
0
{
971
0
    return (!(rhs < lhs));
972
0
}
973
974
/*
975
** Operator !=
976
*/
977
978
OFBool operator!= (const OFString& lhs, const OFString& rhs)
979
0
{
980
0
    return (!(lhs == rhs));
981
0
}
982
983
OFBool operator!= (const char* lhs, const OFString& rhs)
984
0
{
985
0
    return (!(lhs == rhs));
986
0
}
987
988
OFBool operator!= (char lhs, const OFString& rhs)
989
0
{
990
0
    return (!(lhs == rhs));
991
0
}
992
993
OFBool operator!= (const OFString& lhs, const char* rhs)
994
0
{
995
0
    return (!(lhs == rhs));
996
0
}
997
998
OFBool operator!= (const OFString& lhs, char rhs)
999
0
{
1000
0
    return (!(lhs == rhs));
1001
0
}
1002
1003
/*
1004
** Operator >
1005
*/
1006
1007
OFBool operator> (const OFString& lhs, const OFString& rhs)
1008
111
{
1009
111
    return (rhs < lhs);
1010
111
}
1011
1012
OFBool operator> (const char* lhs, const OFString& rhs)
1013
0
{
1014
0
    return (rhs < lhs);
1015
0
}
1016
1017
OFBool operator> (char lhs, const OFString& rhs)
1018
0
{
1019
0
    return (rhs < lhs);
1020
0
}
1021
1022
OFBool operator> (const OFString& lhs, const char* rhs)
1023
0
{
1024
0
    return (rhs < lhs);
1025
0
}
1026
1027
OFBool operator> (const OFString& lhs, char rhs)
1028
0
{
1029
0
    return (rhs < lhs);
1030
0
}
1031
1032
/*
1033
** Operator >=
1034
*/
1035
1036
OFBool operator>= (const OFString& lhs, const OFString& rhs)
1037
0
{
1038
0
    return (!(lhs < rhs));
1039
0
}
1040
1041
OFBool operator>= (const char* lhs, const OFString& rhs)
1042
0
{
1043
0
    return (!(lhs < rhs));
1044
0
}
1045
1046
OFBool operator>= (char lhs, const OFString& rhs)
1047
0
{
1048
0
    return (!(lhs < rhs));
1049
0
}
1050
1051
OFBool operator>= (const OFString& lhs, const char* rhs)
1052
0
{
1053
0
    return (!(lhs < rhs));
1054
0
}
1055
1056
OFBool operator>= (const OFString& lhs, char rhs)
1057
0
{
1058
0
    return (!(lhs < rhs));
1059
0
}
1060
1061
#else /* HAVE_STL_STRING */
1062
1063
int ofstring_cc_dummy_to_keep_linker_from_moaning = 0;
1064
1065
#endif