Coverage Report

Created: 2026-07-16 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.06/goo/GString.cc
Line
Count
Source
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
189M
static inline int size(int len) {
99
189M
  int delta;
100
1.47G
  for (delta = 8; delta < len && delta < 0x100000; delta <<= 1) ;
101
189M
  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
189M
  return (len + delta) & ~(delta - 1);
106
189M
}
107
108
113M
inline void GString::resize(int length1) {
109
113M
  char *s1;
110
111
113M
  if (length1 < 0) {
112
0
    gMemError("GString::resize() with negative length");
113
0
  }
114
113M
  if (!s) {
115
39.1M
    s = new char[size(length1)];
116
73.9M
  } else if (size(length1) != size(length)) {
117
2.14M
    s1 = new char[size(length1)];
118
2.14M
    if (length1 < length) {
119
0
      memcpy(s1, s, length1);
120
0
      s1[length1] = '\0';
121
2.14M
    } else {
122
2.14M
      memcpy(s1, s, length + 1);
123
2.14M
    }
124
2.14M
    delete[] s;
125
2.14M
    s = s1;
126
2.14M
  }
127
113M
}
128
129
1.89M
GString::GString() {
130
1.89M
  s = NULL;
131
1.89M
  resize(length = 0);
132
1.89M
  s[0] = '\0';
133
1.89M
}
134
135
5.91M
GString::GString(const char *sA) {
136
5.91M
  int n = (int)strlen(sA);
137
138
5.91M
  s = NULL;
139
5.91M
  resize(length = n);
140
5.91M
  memcpy(s, sA, n + 1);
141
5.91M
}
142
143
15.4M
GString::GString(const char *sA, int lengthA) {
144
15.4M
  s = NULL;
145
15.4M
  resize(length = lengthA);
146
15.4M
  memcpy(s, sA, length * sizeof(char));
147
15.4M
  s[length] = '\0';
148
15.4M
}
149
150
52.3k
GString::GString(GString *str, int idx, int lengthA) {
151
52.3k
  s = NULL;
152
52.3k
  resize(length = lengthA);
153
52.3k
  memcpy(s, str->getCString() + idx, length);
154
52.3k
  s[length] = '\0';
155
52.3k
}
156
157
15.8M
GString::GString(GString *str) {
158
15.8M
  s = NULL;
159
15.8M
  resize(length = str->getLength());
160
15.8M
  memcpy(s, str->getCString(), length + 1);
161
15.8M
}
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
182k
GString *GString::format(const char *fmt, ...) {
186
182k
  va_list argList;
187
182k
  GString *s;
188
189
182k
  s = new GString();
190
182k
  va_start(argList, fmt);
191
182k
  s->appendfv(fmt, argList);
192
182k
  va_end(argList);
193
182k
  return s;
194
182k
}
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
39.1M
GString::~GString() {
205
39.1M
  delete[] s;
206
39.1M
}
207
208
1.91k
GString *GString::clear() {
209
1.91k
  s[length = 0] = '\0';
210
1.91k
  resize(0);
211
1.91k
  return this;
212
1.91k
}
213
214
41.5M
GString *GString::append(char c) {
215
41.5M
  if (length > INT_MAX - 1) {
216
0
    gMemError("Integer overflow in GString::append()");
217
0
  }
218
41.5M
  resize(length + 1);
219
41.5M
  s[length++] = c;
220
41.5M
  s[length] = '\0';
221
41.5M
  return this;
222
41.5M
}
223
224
437k
GString *GString::append(GString *str) {
225
437k
  int n = str->getLength();
226
227
437k
  if (length > INT_MAX - n) {
228
0
    gMemError("Integer overflow in GString::append()");
229
0
  }
230
437k
  resize(length + n);
231
437k
  memcpy(s + length, str->getCString(), n + 1);
232
437k
  length += n;
233
437k
  return this;
234
437k
}
235
236
2.23M
GString *GString::append(const char *str) {
237
2.23M
  int n = (int)strlen(str);
238
239
2.23M
  if (length > INT_MAX - n) {
240
0
    gMemError("Integer overflow in GString::append()");
241
0
  }
242
2.23M
  resize(length + n);
243
2.23M
  memcpy(s + length, str, n + 1);
244
2.23M
  length += n;
245
2.23M
  return this;
246
2.23M
}
247
248
29.7M
GString *GString::append(const char *str, int lengthA) {
249
29.7M
  if (lengthA < 0 || length > INT_MAX - lengthA) {
250
0
    gMemError("Integer overflow in GString::append()");
251
0
  }
252
29.7M
  resize(length + lengthA);
253
29.7M
  memcpy(s + length, str, lengthA);
254
29.7M
  length += lengthA;
255
29.7M
  s[length] = '\0';
256
29.7M
  return this;
257
29.7M
}
258
259
183k
GString *GString::appendf(const char *fmt, ...) {
260
183k
  va_list argList;
261
262
183k
  va_start(argList, fmt);
263
183k
  appendfv(fmt, argList);
264
183k
  va_end(argList);
265
183k
  return this;
266
183k
}
267
268
366k
GString *GString::appendfv(const char *fmt, va_list argList) {
269
366k
  GStringFormatArg *args;
270
366k
  int argsLen, argsSize;
271
366k
  GStringFormatArg arg;
272
366k
  int idx, width, prec;
273
366k
  GBool reverseAlign, zeroFill;
274
366k
  GStringFormatType ft;
275
366k
  char buf[65];
276
366k
  int len, i;
277
366k
  const char *p0, *p1;
278
366k
  const char *str;
279
280
366k
  argsLen = 0;
281
366k
  argsSize = 8;
282
366k
  args = (GStringFormatArg *)gmallocn(argsSize, sizeof(GStringFormatArg));
283
284
366k
  p0 = fmt;
285
1.71M
  while (*p0) {
286
1.34M
    if (*p0 == '{') {
287
573k
      ++p0;
288
573k
      if (*p0 == '{') {
289
0
  ++p0;
290
0
  append('{');
291
573k
      } else {
292
293
  // parse the format string
294
573k
  if (!(*p0 >= '0' && *p0 <= '9')) {
295
0
    break;
296
0
  }
297
573k
  idx = *p0 - '0';
298
573k
  for (++p0; *p0 >= '0' && *p0 <= '9'; ++p0) {
299
0
    idx = 10 * idx + (*p0 - '0');
300
0
  }
301
573k
  if (*p0 != ':') {
302
0
    break;
303
0
  }
304
573k
  ++p0;
305
573k
  if (*p0 == '-') {
306
0
    reverseAlign = gTrue;
307
0
    ++p0;
308
573k
  } else {
309
573k
    reverseAlign = gFalse;
310
573k
  }
311
573k
  width = 0;
312
573k
  zeroFill = *p0 == '0';
313
731k
  for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
314
157k
    width = 10 * width + (*p0 - '0');
315
157k
  }
316
573k
  if (width < 0) {
317
0
    width = 0;
318
0
  }
319
573k
  if (*p0 == '.') {
320
80.3k
    ++p0;
321
80.3k
    prec = 0;
322
160k
    for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
323
80.3k
      prec = 10 * prec + (*p0 - '0');
324
80.3k
    }
325
493k
  } else {
326
493k
    prec = 0;
327
493k
  }
328
573k
  for (ft = (GStringFormatType)0;
329
8.54M
       formatStrings[ft];
330
8.54M
       ft = (GStringFormatType)(ft + 1)) {
331
8.54M
    if (!strncmp(p0, formatStrings[ft], strlen(formatStrings[ft]))) {
332
573k
      break;
333
573k
    }
334
8.54M
  }
335
573k
  if (!formatStrings[ft]) {
336
0
    break;
337
0
  }
338
573k
  p0 += strlen(formatStrings[ft]);
339
573k
  if (*p0 != '}') {
340
0
    break;
341
0
  }
342
573k
  ++p0;
343
344
  // fetch the argument
345
573k
  if (idx > argsLen) {
346
0
    break;
347
0
  }
348
573k
  if (idx == argsLen) {
349
573k
    if (argsLen == argsSize) {
350
0
      argsSize *= 2;
351
0
      args = (GStringFormatArg *)greallocn(args, argsSize,
352
0
             sizeof(GStringFormatArg));
353
0
    }
354
573k
    switch (ft) {
355
197k
    case fmtIntDecimal:
356
197k
    case fmtIntHex:
357
275k
    case fmtIntOctal:
358
275k
    case fmtIntBinary:
359
275k
    case fmtSpace:
360
275k
      args[argsLen].i = va_arg(argList, int);
361
275k
      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
69.4k
    case fmtDouble:
397
79.8k
    case fmtDoubleTrim:
398
79.8k
      args[argsLen].f = va_arg(argList, double);
399
79.8k
      break;
400
33.7k
    case fmtChar:
401
33.7k
      args[argsLen].c = (char)va_arg(argList, int);
402
33.7k
      break;
403
156k
    case fmtString:
404
156k
      args[argsLen].s = va_arg(argList, char *);
405
156k
      break;
406
27.4k
    case fmtGString:
407
27.4k
      args[argsLen].gs = va_arg(argList, GString *);
408
27.4k
      break;
409
573k
    }
410
573k
    ++argsLen;
411
573k
  }
412
413
  // format the argument
414
573k
  arg = args[idx];
415
573k
  str = NULL;
416
573k
  len = 0;
417
573k
  switch (ft) {
418
197k
  case fmtIntDecimal:
419
197k
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
420
197k
    break;
421
0
  case fmtIntHex:
422
0
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
423
0
    break;
424
78.7k
  case fmtIntOctal:
425
78.7k
    formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
426
78.7k
    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
69.9k
  case fmtDouble:
503
69.9k
    formatDouble(arg.f, buf, sizeof(buf), prec, gFalse, &str, &len);
504
69.9k
    break;
505
10.3k
  case fmtDoubleTrim:
506
10.3k
    formatDouble(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len);
507
10.3k
    break;
508
33.7k
  case fmtChar:
509
33.7k
    buf[0] = arg.c;
510
33.7k
    str = buf;
511
33.7k
    len = 1;
512
33.7k
    reverseAlign = !reverseAlign;
513
33.7k
    break;
514
156k
  case fmtString:
515
156k
    if (arg.s) {
516
156k
      str = arg.s;
517
156k
      len = (int)strlen(str);
518
156k
    } else {
519
0
      str = "(null)";
520
0
      len = 6;
521
0
    }
522
156k
    reverseAlign = !reverseAlign;
523
156k
    break;
524
27.4k
  case fmtGString:
525
27.4k
    if (arg.gs) {
526
27.4k
      str = arg.gs->getCString();
527
27.4k
      len = arg.gs->getLength();
528
27.4k
    } else {
529
0
      str = "(null)";
530
0
      len = 6;
531
0
    }
532
27.4k
    reverseAlign = !reverseAlign;
533
27.4k
    break;
534
0
  case fmtSpace:
535
0
    str = buf;
536
0
    len = 0;
537
0
    width = arg.i;
538
0
    break;
539
573k
  }
540
541
  // append the formatted arg, handling width and alignment
542
573k
  if (!reverseAlign && len < width) {
543
0
    for (i = len; i < width; ++i) {
544
0
      append(' ');
545
0
    }
546
0
  }
547
573k
  append(str, len);
548
573k
  if (reverseAlign && len < width) {
549
0
    for (i = len; i < width; ++i) {
550
0
      append(' ');
551
0
    }
552
0
  }
553
573k
      }
554
555
771k
    } else if (*p0 == '}') {
556
0
      ++p0;
557
0
      if (*p0 == '}') {
558
0
  ++p0;
559
0
      }
560
0
      append('}');
561
      
562
771k
    } else {
563
2.30M
      for (p1 = p0 + 1; *p1 && *p1 != '{' && *p1 != '}'; ++p1) ;
564
771k
      append(p0, (int)(p1 - p0));
565
771k
      p0 = p1;
566
771k
    }
567
1.34M
  }
568
569
366k
  gfree(args);
570
366k
  return this;
571
366k
}
572
573
#ifdef LLONG_MAX
574
void GString::formatInt(long long x, char *buf, int bufSize,
575
      GBool zeroFill, int width, int base,
576
275k
      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
275k
  static char vals[17] = "0123456789abcdef";
583
275k
  GBool neg;
584
275k
  int start, i, j;
585
586
275k
  i = bufSize;
587
275k
  if ((neg = x < 0)) {
588
446
    x = -x;
589
446
  }
590
275k
  start = neg ? 1 : 0;
591
275k
  if (x == 0) {
592
29.6k
    buf[--i] = '0';
593
246k
  } else {
594
843k
    while (i > start && x) {
595
597k
      buf[--i] = vals[x % base];
596
597k
      x /= base;
597
597k
    }
598
246k
  }
599
275k
  if (zeroFill) {
600
125k
    for (j = bufSize - i; i > start && j < width - start; ++j) {
601
47.0k
      buf[--i] = '0';
602
47.0k
    }
603
78.7k
  }
604
275k
  if (neg) {
605
446
    buf[--i] = '-';
606
446
  }
607
275k
  *p = buf + i;
608
275k
  *len = bufSize - i;
609
275k
}
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
80.3k
         GBool trim, const char **p, int *len) {
643
80.3k
  GBool neg, started;
644
80.3k
  double x2;
645
80.3k
  int d, i, j;
646
647
80.3k
  if ((neg = x < 0)) {
648
12.7k
    x = -x;
649
12.7k
  }
650
80.3k
  x = floor(x * pow(10.0, prec) + 0.5);
651
80.3k
  i = bufSize;
652
80.3k
  started = !trim;
653
414k
  for (j = 0; j < prec && i > 1; ++j) {
654
334k
    x2 = floor(0.1 * (x + 0.5));
655
334k
    d = (int)floor(x - 10 * x2 + 0.5);
656
334k
    if (started || d != 0) {
657
279k
      buf[--i] = (char)('0' + d);
658
279k
      started = gTrue;
659
279k
    }
660
334k
    x = x2;
661
334k
  }
662
80.3k
  if (i > 1 && started) {
663
71.4k
    buf[--i] = '.';
664
71.4k
  }
665
80.3k
  if (i > 1) {
666
163k
    do {
667
163k
      x2 = floor(0.1 * (x + 0.5));
668
163k
      d = (int)floor(x - 10 * x2 + 0.5);
669
163k
      buf[--i] = (char)('0' + d);
670
163k
      x = x2;
671
163k
    } while (i > 1 && x);
672
80.3k
  }
673
80.3k
  if (neg) {
674
12.7k
    buf[--i] = '-';
675
12.7k
  }
676
80.3k
  *p = buf + i;
677
80.3k
  *len = bufSize - i;
678
80.3k
}
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
6.31k
GString *GString::del(int i, int n) {
739
6.31k
  int j;
740
741
6.31k
  if (i >= 0 && n > 0 && i <= INT_MAX - n) {
742
6.31k
    if (i + n > length) {
743
0
      n = length - i;
744
0
    }
745
17.4M
    for (j = i; j <= length - n; ++j) {
746
17.4M
      s[j] = s[j + n];
747
17.4M
    }
748
6.31k
    resize(length -= n);
749
6.31k
  }
750
6.31k
  return this;
751
6.31k
}
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
49.1k
int GString::cmp(GString *str) {
776
49.1k
  int n1, n2, i, x;
777
49.1k
  char *p1, *p2;
778
779
49.1k
  n1 = length;
780
49.1k
  n2 = str->length;
781
37.1M
  for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {
782
37.1M
    x = (*p1 & 0xff) - (*p2 & 0xff);
783
37.1M
    if (x != 0) {
784
8.13k
      return x;
785
8.13k
    }
786
37.1M
  }
787
41.0k
  return n1 - n2;
788
49.1k
}
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
1.74M
int GString::cmp(const char *sA) {
811
1.74M
  int n1, i, x;
812
1.74M
  const char *p1, *p2;
813
814
1.74M
  n1 = length;
815
5.01M
  for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {
816
4.35M
    x = (*p1 & 0xff) - (*p2 & 0xff);
817
4.35M
    if (x != 0) {
818
1.08M
      return x;
819
1.08M
    }
820
4.35M
  }
821
653k
  if (i < n1) {
822
12.6k
    return 1;
823
12.6k
  }
824
640k
  if (*p2) {
825
139k
    return -1;
826
139k
  }
827
501k
  return 0;
828
640k
}
829
830
55
int GString::cmpN(const char *sA, int n) {
831
55
  int n1, i, x;
832
55
  const char *p1, *p2;
833
834
55
  n1 = length;
835
101
  for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {
836
67
    x = (*p1 & 0xff) - (*p2 & 0xff);
837
67
    if (x != 0) {
838
21
      return x;
839
21
    }
840
67
  }
841
34
  if (i == n) {
842
10
    return 0;
843
10
  }
844
24
  if (i < n1) {
845
0
    return 1;
846
0
  }
847
24
  if (*p2) {
848
24
    return -1;
849
24
  }
850
0
  return 0;
851
24
}