Coverage Report

Created: 2025-07-11 06:47

/src/xpdf-4.05/goo/GString.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// GString.cc
4
//
5
// Simple variable-length string type.
6
//
7
// Copyright 1996-2003 Glyph & Cog, LLC
8
//
9
//========================================================================
10
11
#include <aconf.h>
12
13
#include <stdlib.h>
14
#include <stddef.h>
15
#include <string.h>
16
#include <ctype.h>
17
#include <math.h>
18
#include <limits.h>
19
#include "gmem.h"
20
#include "gmempp.h"
21
#include "GString.h"
22
23
//------------------------------------------------------------------------
24
25
union GStringFormatArg {
26
  int i;
27
  Guint ui;
28
  long l;
29
  Gulong ul;
30
#ifdef LLONG_MAX
31
  long long ll;
32
#endif
33
#ifdef ULLONG_MAX
34
  unsigned long long ull;
35
#endif
36
  double f;
37
  char c;
38
  char *s;
39
  GString *gs;
40
};
41
42
enum GStringFormatType {
43
  fmtIntDecimal,
44
  fmtIntHex,
45
  fmtIntOctal,
46
  fmtIntBinary,
47
  fmtUIntDecimal,
48
  fmtUIntHex,
49
  fmtUIntOctal,
50
  fmtUIntBinary,
51
  fmtLongDecimal,
52
  fmtLongHex,
53
  fmtLongOctal,
54
  fmtLongBinary,
55
  fmtULongDecimal,
56
  fmtULongHex,
57
  fmtULongOctal,
58
  fmtULongBinary,
59
#ifdef LLONG_MAX
60
  fmtLongLongDecimal,
61
  fmtLongLongHex,
62
  fmtLongLongOctal,
63
  fmtLongLongBinary,
64
#endif
65
#ifdef ULLONG_MAX
66
  fmtULongLongDecimal,
67
  fmtULongLongHex,
68
  fmtULongLongOctal,
69
  fmtULongLongBinary,
70
#endif
71
  fmtDouble,
72
  fmtDoubleTrim,
73
  fmtChar,
74
  fmtString,
75
  fmtGString,
76
  fmtSpace
77
};
78
79
static const char *formatStrings[] = {
80
  "d", "x", "o", "b", "ud", "ux", "uo", "ub",
81
  "ld", "lx", "lo", "lb", "uld", "ulx", "ulo", "ulb",
82
#ifdef LLONG_MAX
83
  "lld", "llx", "llo", "llb",
84
#endif
85
#ifdef ULLONG_MAX
86
  "ulld", "ullx", "ullo", "ullb",
87
#endif
88
  "f", "g",
89
  "c",
90
  "s",
91
  "t",
92
  "w",
93
  NULL
94
};
95
96
//------------------------------------------------------------------------
97
98
29.8M
static inline int size(int len) {
99
29.8M
  int delta;
100
332M
  for (delta = 8; delta < len && delta < 0x100000; delta <<= 1) ;
101
29.8M
  if (len > INT_MAX - delta) {
102
0
    gMemError("Integer overflow in GString::size()");
103
0
  }
104
  // this is ((len + 1) + (delta - 1)) & ~(delta - 1)
105
29.8M
  return (len + delta) & ~(delta - 1);
106
29.8M
}
107
108
17.5M
inline void GString::resize(int length1) {
109
17.5M
  char *s1;
110
111
17.5M
  if (length1 < 0) {
112
0
    gMemError("GString::resize() with negative length");
113
0
  }
114
17.5M
  if (!s) {
115
5.26M
    s = new char[size(length1)];
116
12.2M
  } else if (size(length1) != size(length)) {
117
94.7k
    s1 = new char[size(length1)];
118
94.7k
    if (length1 < length) {
119
0
      memcpy(s1, s, length1);
120
0
      s1[length1] = '\0';
121
94.7k
    } else {
122
94.7k
      memcpy(s1, s, length + 1);
123
94.7k
    }
124
94.7k
    delete[] s;
125
94.7k
    s = s1;
126
94.7k
  }
127
17.5M
}
128
129
4.03M
GString::GString() {
130
4.03M
  s = NULL;
131
4.03M
  resize(length = 0);
132
4.03M
  s[0] = '\0';
133
4.03M
}
134
135
1.21M
GString::GString(const char *sA) {
136
1.21M
  int n = (int)strlen(sA);
137
138
1.21M
  s = NULL;
139
1.21M
  resize(length = n);
140
1.21M
  memcpy(s, sA, n + 1);
141
1.21M
}
142
143
12.2k
GString::GString(const char *sA, int lengthA) {
144
12.2k
  s = NULL;
145
12.2k
  resize(length = lengthA);
146
12.2k
  memcpy(s, sA, length * sizeof(char));
147
12.2k
  s[length] = '\0';
148
12.2k
}
149
150
0
GString::GString(GString *str, int idx, int lengthA) {
151
0
  s = NULL;
152
0
  resize(length = lengthA);
153
0
  memcpy(s, str->getCString() + idx, length);
154
0
  s[length] = '\0';
155
0
}
156
157
0
GString::GString(GString *str) {
158
0
  s = NULL;
159
0
  resize(length = str->getLength());
160
0
  memcpy(s, str->getCString(), length + 1);
161
0
}
162
163
0
GString::GString(GString *str1, GString *str2) {
164
0
  int n1 = str1->getLength();
165
0
  int n2 = str2->getLength();
166
167
0
  s = NULL;
168
0
  if (n1 > INT_MAX - n2) {
169
0
    gMemError("Integer overflow in GString::GString()");
170
0
  }
171
0
  resize(length = n1 + n2);
172
0
  memcpy(s, str1->getCString(), n1);
173
0
  memcpy(s + n1, str2->getCString(), n2 + 1);
174
0
}
175
176
0
GString *GString::fromInt(int x) {
177
0
  char buf[24]; // enough space for 64-bit ints plus a little extra
178
0
  const char *p;
179
0
  int len;
180
181
0
  formatInt(x, buf, sizeof(buf), gFalse, 0, 10, &p, &len);
182
0
  return new GString(p, len);
183
0
}
184
185
0
GString *GString::format(const char *fmt, ...) {
186
0
  va_list argList;
187
0
  GString *s;
188
189
0
  s = new GString();
190
0
  va_start(argList, fmt);
191
0
  s->appendfv(fmt, argList);
192
0
  va_end(argList);
193
0
  return s;
194
0
}
195
196
0
GString *GString::formatv(const char *fmt, va_list argList) {
197
0
  GString *s;
198
199
0
  s = new GString();
200
0
  s->appendfv(fmt, argList);
201
0
  return s;
202
0
}
203
204
5.26M
GString::~GString() {
205
5.26M
  delete[] s;
206
5.26M
}
207
208
0
GString *GString::clear() {
209
0
  s[length = 0] = '\0';
210
0
  resize(0);
211
0
  return this;
212
0
}
213
214
10.6M
GString *GString::append(char c) {
215
10.6M
  if (length > INT_MAX - 1) {
216
0
    gMemError("Integer overflow in GString::append()");
217
0
  }
218
10.6M
  resize(length + 1);
219
10.6M
  s[length++] = c;
220
10.6M
  s[length] = '\0';
221
10.6M
  return this;
222
10.6M
}
223
224
1.21M
GString *GString::append(GString *str) {
225
1.21M
  int n = str->getLength();
226
227
1.21M
  if (length > INT_MAX - n) {
228
0
    gMemError("Integer overflow in GString::append()");
229
0
  }
230
1.21M
  resize(length + n);
231
1.21M
  memcpy(s + length, str->getCString(), n + 1);
232
1.21M
  length += n;
233
1.21M
  return this;
234
1.21M
}
235
236
0
GString *GString::append(const char *str) {
237
0
  int n = (int)strlen(str);
238
239
0
  if (length > INT_MAX - n) {
240
0
    gMemError("Integer overflow in GString::append()");
241
0
  }
242
0
  resize(length + n);
243
0
  memcpy(s + length, str, n + 1);
244
0
  length += n;
245
0
  return this;
246
0
}
247
248
403k
GString *GString::append(const char *str, int lengthA) {
249
403k
  if (lengthA < 0 || length > INT_MAX - lengthA) {
250
0
    gMemError("Integer overflow in GString::append()");
251
0
  }
252
403k
  resize(length + lengthA);
253
403k
  memcpy(s + length, str, lengthA);
254
403k
  length += lengthA;
255
403k
  s[length] = '\0';
256
403k
  return this;
257
403k
}
258
259
0
GString *GString::appendf(const char *fmt, ...) {
260
0
  va_list argList;
261
262
0
  va_start(argList, fmt);
263
0
  appendfv(fmt, argList);
264
0
  va_end(argList);
265
0
  return this;
266
0
}
267
268
0
GString *GString::appendfv(const char *fmt, va_list argList) {
269
0
  GStringFormatArg *args;
270
0
  int argsLen, argsSize;
271
0
  GStringFormatArg arg;
272
0
  int idx, width, prec;
273
0
  GBool reverseAlign, zeroFill;
274
0
  GStringFormatType ft;
275
0
  char buf[65];
276
0
  int len, i;
277
0
  const char *p0, *p1;
278
0
  const char *str;
279
280
0
  argsLen = 0;
281
0
  argsSize = 8;
282
0
  args = (GStringFormatArg *)gmallocn(argsSize, sizeof(GStringFormatArg));
283
284
0
  p0 = fmt;
285
0
  while (*p0) {
286
0
    if (*p0 == '{') {
287
0
      ++p0;
288
0
      if (*p0 == '{') {
289
0
  ++p0;
290
0
  append('{');
291
0
      } else {
292
293
  // parse the format string
294
0
  if (!(*p0 >= '0' && *p0 <= '9')) {
295
0
    break;
296
0
  }
297
0
  idx = *p0 - '0';
298
0
  for (++p0; *p0 >= '0' && *p0 <= '9'; ++p0) {
299
0
    idx = 10 * idx + (*p0 - '0');
300
0
  }
301
0
  if (*p0 != ':') {
302
0
    break;
303
0
  }
304
0
  ++p0;
305
0
  if (*p0 == '-') {
306
0
    reverseAlign = gTrue;
307
0
    ++p0;
308
0
  } else {
309
0
    reverseAlign = gFalse;
310
0
  }
311
0
  width = 0;
312
0
  zeroFill = *p0 == '0';
313
0
  for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
314
0
    width = 10 * width + (*p0 - '0');
315
0
  }
316
0
  if (width < 0) {
317
0
    width = 0;
318
0
  }
319
0
  if (*p0 == '.') {
320
0
    ++p0;
321
0
    prec = 0;
322
0
    for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
323
0
      prec = 10 * prec + (*p0 - '0');
324
0
    }
325
0
  } else {
326
0
    prec = 0;
327
0
  }
328
0
  for (ft = (GStringFormatType)0;
329
0
       formatStrings[ft];
330
0
       ft = (GStringFormatType)(ft + 1)) {
331
0
    if (!strncmp(p0, formatStrings[ft], strlen(formatStrings[ft]))) {
332
0
      break;
333
0
    }
334
0
  }
335
0
  if (!formatStrings[ft]) {
336
0
    break;
337
0
  }
338
0
  p0 += strlen(formatStrings[ft]);
339
0
  if (*p0 != '}') {
340
0
    break;
341
0
  }
342
0
  ++p0;
343
344
  // fetch the argument
345
0
  if (idx > argsLen) {
346
0
    break;
347
0
  }
348
0
  if (idx == argsLen) {
349
0
    if (argsLen == argsSize) {
350
0
      argsSize *= 2;
351
0
      args = (GStringFormatArg *)greallocn(args, argsSize,
352
0
             sizeof(GStringFormatArg));
353
0
    }
354
0
    switch (ft) {
355
0
    case fmtIntDecimal:
356
0
    case fmtIntHex:
357
0
    case fmtIntOctal:
358
0
    case fmtIntBinary:
359
0
    case fmtSpace:
360
0
      args[argsLen].i = va_arg(argList, int);
361
0
      break;
362
0
    case fmtUIntDecimal:
363
0
    case fmtUIntHex:
364
0
    case fmtUIntOctal:
365
0
    case fmtUIntBinary:
366
0
      args[argsLen].ui = va_arg(argList, Guint);
367
0
      break;
368
0
    case fmtLongDecimal:
369
0
    case fmtLongHex:
370
0
    case fmtLongOctal:
371
0
    case fmtLongBinary:
372
0
      args[argsLen].l = va_arg(argList, long);
373
0
      break;
374
0
    case fmtULongDecimal:
375
0
    case fmtULongHex:
376
0
    case fmtULongOctal:
377
0
    case fmtULongBinary:
378
0
      args[argsLen].ul = va_arg(argList, Gulong);
379
0
      break;
380
0
#ifdef LLONG_MAX
381
0
    case fmtLongLongDecimal:
382
0
    case fmtLongLongHex:
383
0
    case fmtLongLongOctal:
384
0
    case fmtLongLongBinary:
385
0
      args[argsLen].ll = va_arg(argList, long long);
386
0
      break;
387
0
#endif
388
0
#ifdef ULLONG_MAX
389
0
    case fmtULongLongDecimal:
390
0
    case fmtULongLongHex:
391
0
    case fmtULongLongOctal:
392
0
    case fmtULongLongBinary:
393
0
      args[argsLen].ull = va_arg(argList, unsigned long long);
394
0
      break;
395
0
#endif
396
0
    case fmtDouble:
397
0
    case fmtDoubleTrim:
398
0
      args[argsLen].f = va_arg(argList, double);
399
0
      break;
400
0
    case fmtChar:
401
0
      args[argsLen].c = (char)va_arg(argList, int);
402
0
      break;
403
0
    case fmtString:
404
0
      args[argsLen].s = va_arg(argList, char *);
405
0
      break;
406
0
    case fmtGString:
407
0
      args[argsLen].gs = va_arg(argList, GString *);
408
0
      break;
409
0
    }
410
0
    ++argsLen;
411
0
  }
412
413
  // format the argument
414
0
  arg = args[idx];
415
0
  str = NULL;
416
0
  len = 0;
417
0
  switch (ft) {
418
0
  case fmtIntDecimal:
419
0
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
420
0
    break;
421
0
  case fmtIntHex:
422
0
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
423
0
    break;
424
0
  case fmtIntOctal:
425
0
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
426
0
    break;
427
0
  case fmtIntBinary:
428
0
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
429
0
    break;
430
0
  case fmtUIntDecimal:
431
0
    formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 10,
432
0
         &str, &len);
433
0
    break;
434
0
  case fmtUIntHex:
435
0
    formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 16,
436
0
         &str, &len);
437
0
    break;
438
0
  case fmtUIntOctal:
439
0
    formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
440
0
    break;
441
0
  case fmtUIntBinary:
442
0
    formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
443
0
    break;
444
0
  case fmtLongDecimal:
445
0
    formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
446
0
    break;
447
0
  case fmtLongHex:
448
0
    formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
449
0
    break;
450
0
  case fmtLongOctal:
451
0
    formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
452
0
    break;
453
0
  case fmtLongBinary:
454
0
    formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
455
0
    break;
456
0
  case fmtULongDecimal:
457
0
    formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 10,
458
0
         &str, &len);
459
0
    break;
460
0
  case fmtULongHex:
461
0
    formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 16,
462
0
         &str, &len);
463
0
    break;
464
0
  case fmtULongOctal:
465
0
    formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
466
0
    break;
467
0
  case fmtULongBinary:
468
0
    formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
469
0
    break;
470
0
#ifdef LLONG_MAX
471
0
  case fmtLongLongDecimal:
472
0
    formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
473
0
    break;
474
0
  case fmtLongLongHex:
475
0
    formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
476
0
    break;
477
0
  case fmtLongLongOctal:
478
0
    formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
479
0
    break;
480
0
  case fmtLongLongBinary:
481
0
    formatInt(arg.ll, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
482
0
    break;
483
0
#endif
484
0
#ifdef ULLONG_MAX
485
0
  case fmtULongLongDecimal:
486
0
    formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 10,
487
0
         &str, &len);
488
0
    break;
489
0
  case fmtULongLongHex:
490
0
    formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 16,
491
0
         &str, &len);
492
0
    break;
493
0
  case fmtULongLongOctal:
494
0
    formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 8,
495
0
         &str, &len);
496
0
    break;
497
0
  case fmtULongLongBinary:
498
0
    formatUInt(arg.ull, buf, sizeof(buf), zeroFill, width, 2,
499
0
         &str, &len);
500
0
    break;
501
0
#endif
502
0
  case fmtDouble:
503
0
    formatDouble(arg.f, buf, sizeof(buf), prec, gFalse, &str, &len);
504
0
    break;
505
0
  case fmtDoubleTrim:
506
0
    formatDouble(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len);
507
0
    break;
508
0
  case fmtChar:
509
0
    buf[0] = arg.c;
510
0
    str = buf;
511
0
    len = 1;
512
0
    reverseAlign = !reverseAlign;
513
0
    break;
514
0
  case fmtString:
515
0
    if (arg.s) {
516
0
      str = arg.s;
517
0
      len = (int)strlen(str);
518
0
    } else {
519
0
      str = "(null)";
520
0
      len = 6;
521
0
    }
522
0
    reverseAlign = !reverseAlign;
523
0
    break;
524
0
  case fmtGString:
525
0
    if (arg.gs) {
526
0
      str = arg.gs->getCString();
527
0
      len = arg.gs->getLength();
528
0
    } else {
529
0
      str = "(null)";
530
0
      len = 6;
531
0
    }
532
0
    reverseAlign = !reverseAlign;
533
0
    break;
534
0
  case fmtSpace:
535
0
    str = buf;
536
0
    len = 0;
537
0
    width = arg.i;
538
0
    break;
539
0
  }
540
541
  // append the formatted arg, handling width and alignment
542
0
  if (!reverseAlign && len < width) {
543
0
    for (i = len; i < width; ++i) {
544
0
      append(' ');
545
0
    }
546
0
  }
547
0
  append(str, len);
548
0
  if (reverseAlign && len < width) {
549
0
    for (i = len; i < width; ++i) {
550
0
      append(' ');
551
0
    }
552
0
  }
553
0
      }
554
555
0
    } else if (*p0 == '}') {
556
0
      ++p0;
557
0
      if (*p0 == '}') {
558
0
  ++p0;
559
0
      }
560
0
      append('}');
561
      
562
0
    } else {
563
0
      for (p1 = p0 + 1; *p1 && *p1 != '{' && *p1 != '}'; ++p1) ;
564
0
      append(p0, (int)(p1 - p0));
565
0
      p0 = p1;
566
0
    }
567
0
  }
568
569
0
  gfree(args);
570
0
  return this;
571
0
}
572
573
#ifdef LLONG_MAX
574
void GString::formatInt(long long x, char *buf, int bufSize,
575
      GBool zeroFill, int width, int base,
576
0
      const char **p, int *len) {
577
#else
578
void GString::formatInt(long x, char *buf, int bufSize,
579
      GBool zeroFill, int width, int base,
580
      const char **p, int *len) {
581
#endif
582
0
  static char vals[17] = "0123456789abcdef";
583
0
  GBool neg;
584
0
  int start, i, j;
585
586
0
  i = bufSize;
587
0
  if ((neg = x < 0)) {
588
0
    x = -x;
589
0
  }
590
0
  start = neg ? 1 : 0;
591
0
  if (x == 0) {
592
0
    buf[--i] = '0';
593
0
  } else {
594
0
    while (i > start && x) {
595
0
      buf[--i] = vals[x % base];
596
0
      x /= base;
597
0
    }
598
0
  }
599
0
  if (zeroFill) {
600
0
    for (j = bufSize - i; i > start && j < width - start; ++j) {
601
0
      buf[--i] = '0';
602
0
    }
603
0
  }
604
0
  if (neg) {
605
0
    buf[--i] = '-';
606
0
  }
607
0
  *p = buf + i;
608
0
  *len = bufSize - i;
609
0
}
610
611
#ifdef ULLONG_MAX
612
void GString::formatUInt(unsigned long long x, char *buf, int bufSize,
613
       GBool zeroFill, int width, int base,
614
0
       const char **p, int *len) {
615
#else
616
void GString::formatUInt(Gulong x, char *buf, int bufSize,
617
       GBool zeroFill, int width, int base,
618
       const char **p, int *len) {
619
#endif
620
0
  static char vals[17] = "0123456789abcdef";
621
0
  int i, j;
622
623
0
  i = bufSize;
624
0
  if (x == 0) {
625
0
    buf[--i] = '0';
626
0
  } else {
627
0
    while (i > 0 && x) {
628
0
      buf[--i] = vals[x % base];
629
0
      x /= base;
630
0
    }
631
0
  }
632
0
  if (zeroFill) {
633
0
    for (j = bufSize - i; i > 0 && j < width; ++j) {
634
0
      buf[--i] = '0';
635
0
    }
636
0
  }
637
0
  *p = buf + i;
638
0
  *len = bufSize - i;
639
0
}
640
641
void GString::formatDouble(double x, char *buf, int bufSize, int prec,
642
0
         GBool trim, const char **p, int *len) {
643
0
  GBool neg, started;
644
0
  double x2;
645
0
  int d, i, j;
646
647
0
  if ((neg = x < 0)) {
648
0
    x = -x;
649
0
  }
650
0
  x = floor(x * pow(10.0, prec) + 0.5);
651
0
  i = bufSize;
652
0
  started = !trim;
653
0
  for (j = 0; j < prec && i > 1; ++j) {
654
0
    x2 = floor(0.1 * (x + 0.5));
655
0
    d = (int)floor(x - 10 * x2 + 0.5);
656
0
    if (started || d != 0) {
657
0
      buf[--i] = (char)('0' + d);
658
0
      started = gTrue;
659
0
    }
660
0
    x = x2;
661
0
  }
662
0
  if (i > 1 && started) {
663
0
    buf[--i] = '.';
664
0
  }
665
0
  if (i > 1) {
666
0
    do {
667
0
      x2 = floor(0.1 * (x + 0.5));
668
0
      d = (int)floor(x - 10 * x2 + 0.5);
669
0
      buf[--i] = (char)('0' + d);
670
0
      x = x2;
671
0
    } while (i > 1 && x);
672
0
  }
673
0
  if (neg) {
674
0
    buf[--i] = '-';
675
0
  }
676
0
  *p = buf + i;
677
0
  *len = bufSize - i;
678
0
}
679
680
0
GString *GString::insert(int i, char c) {
681
0
  int j;
682
683
0
  if (length > INT_MAX - 1) {
684
0
    gMemError("Integer overflow in GString::insert()");
685
0
  }
686
0
  resize(length + 1);
687
0
  for (j = length + 1; j > i; --j)
688
0
    s[j] = s[j-1];
689
0
  s[i] = c;
690
0
  ++length;
691
0
  return this;
692
0
}
693
694
0
GString *GString::insert(int i, GString *str) {
695
0
  int n = str->getLength();
696
0
  int j;
697
698
0
  if (length > INT_MAX - n) {
699
0
    gMemError("Integer overflow in GString::insert()");
700
0
  }
701
0
  resize(length + n);
702
0
  for (j = length; j >= i; --j)
703
0
    s[j+n] = s[j];
704
0
  memcpy(s+i, str->getCString(), n);
705
0
  length += n;
706
0
  return this;
707
0
}
708
709
0
GString *GString::insert(int i, const char *str) {
710
0
  int n = (int)strlen(str);
711
0
  int j;
712
713
0
  if (length > INT_MAX - n) {
714
0
    gMemError("Integer overflow in GString::insert()");
715
0
  }
716
0
  resize(length + n);
717
0
  for (j = length; j >= i; --j)
718
0
    s[j+n] = s[j];
719
0
  memcpy(s+i, str, n);
720
0
  length += n;
721
0
  return this;
722
0
}
723
724
0
GString *GString::insert(int i, const char *str, int lengthA) {
725
0
  int j;
726
727
0
  if (lengthA < 0 || length > INT_MAX - lengthA) {
728
0
    gMemError("Integer overflow in GString::insert()");
729
0
  }
730
0
  resize(length + lengthA);
731
0
  for (j = length; j >= i; --j)
732
0
    s[j+lengthA] = s[j];
733
0
  memcpy(s+i, str, lengthA);
734
0
  length += lengthA;
735
0
  return this;
736
0
}
737
738
0
GString *GString::del(int i, int n) {
739
0
  int j;
740
741
0
  if (i >= 0 && n > 0 && i <= INT_MAX - n) {
742
0
    if (i + n > length) {
743
0
      n = length - i;
744
0
    }
745
0
    for (j = i; j <= length - n; ++j) {
746
0
      s[j] = s[j + n];
747
0
    }
748
0
    resize(length -= n);
749
0
  }
750
0
  return this;
751
0
}
752
753
0
GString *GString::upperCase() {
754
0
  int i;
755
756
0
  for (i = 0; i < length; ++i) {
757
0
    if (islower(s[i] & 0xff)) {
758
0
      s[i] = (char)toupper(s[i] & 0xff);
759
0
    }
760
0
  }
761
0
  return this;
762
0
}
763
764
0
GString *GString::lowerCase() {
765
0
  int i;
766
767
0
  for (i = 0; i < length; ++i) {
768
0
    if (isupper(s[i] & 0xff)) {
769
0
      s[i] = (char)tolower(s[i] & 0xff);
770
0
    }
771
0
  }
772
0
  return this;
773
0
}
774
775
0
int GString::cmp(GString *str) {
776
0
  int n1, n2, i, x;
777
0
  char *p1, *p2;
778
779
0
  n1 = length;
780
0
  n2 = str->length;
781
0
  for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {
782
0
    x = (*p1 & 0xff) - (*p2 & 0xff);
783
0
    if (x != 0) {
784
0
      return x;
785
0
    }
786
0
  }
787
0
  return n1 - n2;
788
0
}
789
790
0
int GString::cmpN(GString *str, int n) {
791
0
  int n1, n2, i, x;
792
0
  char *p1, *p2;
793
794
0
  n1 = length;
795
0
  n2 = str->length;
796
0
  for (i = 0, p1 = s, p2 = str->s;
797
0
       i < n1 && i < n2 && i < n;
798
0
       ++i, ++p1, ++p2) {
799
0
    x = (*p1 & 0xff) - (*p2 & 0xff);
800
0
    if (x != 0) {
801
0
      return x;
802
0
    }
803
0
  }
804
0
  if (i == n) {
805
0
    return 0;
806
0
  }
807
0
  return n1 - n2;
808
0
}
809
810
108
int GString::cmp(const char *sA) {
811
108
  int n1, i, x;
812
108
  const char *p1, *p2;
813
814
108
  n1 = length;
815
118
  for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {
816
26
    x = (*p1 & 0xff) - (*p2 & 0xff);
817
26
    if (x != 0) {
818
16
      return x;
819
16
    }
820
26
  }
821
92
  if (i < n1) {
822
1
    return 1;
823
1
  }
824
91
  if (*p2) {
825
90
    return -1;
826
90
  }
827
1
  return 0;
828
91
}
829
830
0
int GString::cmpN(const char *sA, int n) {
831
0
  int n1, i, x;
832
0
  const char *p1, *p2;
833
834
0
  n1 = length;
835
0
  for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {
836
0
    x = (*p1 & 0xff) - (*p2 & 0xff);
837
0
    if (x != 0) {
838
0
      return x;
839
0
    }
840
0
  }
841
0
  if (i == n) {
842
0
    return 0;
843
0
  }
844
0
  if (i < n1) {
845
0
    return 1;
846
0
  }
847
0
  if (*p2) {
848
0
    return -1;
849
0
  }
850
0
  return 0;
851
0
}