Coverage Report

Created: 2023-09-25 06:30

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