]> Git Repo - binutils.git/blob - gprofng/src/StringBuilder.cc
Automatic date update in version.in
[binutils.git] / gprofng / src / StringBuilder.cc
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2    Contributed by Oracle.
3
4    This file is part of GNU Binutils.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "config.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <values.h>
26 #include <stdarg.h>
27
28 #include "gp-defs.h"
29 #include "StringBuilder.h"
30 #include "i18n.h"
31
32 StringBuilder::StringBuilder ()
33 {
34   count = 0;
35   maxCapacity = 16;
36   value = (char *) malloc (maxCapacity);
37   memset (value, 0, maxCapacity);
38 }
39
40 StringBuilder::StringBuilder (int capacity)
41 {
42   count = 0;
43   maxCapacity = capacity;
44   value = (char *) malloc (maxCapacity);
45   memset (value, 0, maxCapacity);
46 }
47
48 StringBuilder::~StringBuilder ()
49 {
50   free (value);
51 }
52
53 void
54 StringBuilder::ensureCapacity (int minimumCapacity)
55 {
56   if (minimumCapacity > maxCapacity)
57     expandCapacity (minimumCapacity);
58 }
59
60 void
61 StringBuilder::expandCapacity (int minimumCapacity)
62 {
63   int newCapacity = (maxCapacity + 1) * 2;
64   if (newCapacity < 0)
65     newCapacity = MAXINT;
66   else if (minimumCapacity > newCapacity)
67     newCapacity = minimumCapacity;
68   char *newValue = (char *) malloc (newCapacity);
69   maxCapacity = newCapacity;
70   memcpy (newValue, value, count);
71   memset (newValue + count, 0, maxCapacity - count);
72   free (value);
73   value = newValue;
74 }
75
76 void
77 StringBuilder::trimToSize ()
78 {
79   if (count < maxCapacity)
80     {
81       char *newValue = (char *) malloc (count);
82       maxCapacity = count;
83       memcpy (newValue, value, count);
84       free (value);
85       value = newValue;
86     }
87 }
88
89 void
90 StringBuilder::trim ()
91 {
92   while (count > 0)
93     {
94       if (value[count - 1] != ' ')
95         break;
96       count--;
97     }
98 }
99
100 void
101 StringBuilder::setLength (int newLength)
102 {
103   if (newLength < 0)
104     return;
105   if (newLength > maxCapacity)
106     expandCapacity (newLength);
107   if (count < newLength)
108     {
109       for (; count < newLength; count++)
110         value[count] = '\0';
111     }
112   else
113     count = newLength;
114 }
115
116 char
117 StringBuilder::charAt (int index)
118 {
119   if (index < 0 || index >= count)
120     return 0;
121   return value[index];
122 }
123
124 void
125 StringBuilder::getChars (int srcBegin, int srcEnd, char dst[], int dstBegin)
126 {
127   if (srcBegin < 0)
128     return;
129   if (srcEnd < 0 || srcEnd > count)
130     return;
131   if (srcBegin > srcEnd)
132     return;
133   memcpy (dst + dstBegin, value + srcBegin, srcEnd - srcBegin);
134 }
135
136 void
137 StringBuilder::setCharAt (int index, char ch)
138 {
139   if (index < 0 || index >= count)
140     return;
141   value[index] = ch;
142 }
143
144 StringBuilder *
145 StringBuilder::append (StringBuilder *sb)
146 {
147   if (sb == NULL)
148     return append (NTXT ("null"));
149   int len = sb->count;
150   int newcount = count + len;
151   if (newcount > maxCapacity)
152     expandCapacity (newcount);
153   sb->getChars (0, len, value, count);
154   count = newcount;
155   return this;
156 }
157
158 StringBuilder *
159 StringBuilder::append (const char str[])
160 {
161   int len = (int) strlen (str);
162   int newCount = count + len;
163   if (newCount > maxCapacity)
164     expandCapacity (newCount);
165   memcpy (value + count, str, len);
166   count = newCount;
167   return this;
168 }
169
170 StringBuilder *
171 StringBuilder::append (const char str[], int offset, int len)
172 {
173   int newCount = count + len;
174   if (newCount > maxCapacity)
175     expandCapacity (newCount);
176   memcpy (value + count, str + offset, len);
177   count = newCount;
178   return this;
179 }
180
181 StringBuilder *
182 StringBuilder::append (bool b)
183 {
184   if (b)
185     append (NTXT ("true"));
186   else
187     append (NTXT ("false"));
188   return this;
189 }
190
191 StringBuilder *
192 StringBuilder::append (char c)
193 {
194   int newCount = count + 1;
195   if (newCount > maxCapacity)
196     {
197       expandCapacity (newCount);
198     }
199   value[count++] = c;
200   return this;
201 }
202
203 StringBuilder *
204 StringBuilder::append (int i)
205 {
206   char buf[16];
207   snprintf (buf, sizeof (buf), NTXT ("%d"), i);
208   append (buf);
209   return this;
210 }
211
212 StringBuilder *
213 StringBuilder::append (unsigned int i)
214 {
215   char buf[16];
216   snprintf (buf, sizeof (buf), NTXT ("%u"), i);
217   append (buf);
218   return this;
219 }
220
221 StringBuilder *
222 StringBuilder::append (long lng)
223 {
224   char buf[32];
225   snprintf (buf, sizeof (buf), NTXT ("%ld"), lng);
226   append (buf);
227   return this;
228 }
229
230 StringBuilder *
231 StringBuilder::append (unsigned long lng)
232 {
233   char buf[32];
234   snprintf (buf, sizeof (buf), NTXT ("%lu"), lng);
235   append (buf);
236   return this;
237 }
238
239 StringBuilder *
240 StringBuilder::append (long long lng)
241 {
242   char buf[32];
243   snprintf (buf, sizeof (buf), NTXT ("%lld"), lng);
244   append (buf);
245   return this;
246 }
247
248 StringBuilder *
249 StringBuilder::append (unsigned long long lng)
250 {
251   char buf[32];
252   snprintf (buf, sizeof (buf), NTXT ("%llu"), lng);
253   append (buf);
254   return this;
255 }
256
257 StringBuilder *
258 StringBuilder::append (float f)
259 {
260   char buf[32];
261   snprintf (buf, sizeof (buf), NTXT ("%f"), (double) f);
262   append (buf);
263   return this;
264 }
265
266 StringBuilder *
267 StringBuilder::append (double d)
268 {
269   char buf[32];
270   snprintf (buf, sizeof (buf), NTXT ("%f"), d);
271   append (buf);
272   return this;
273 }
274
275 StringBuilder *
276 StringBuilder::_delete (int start, int end)
277 {
278   if (start < 0)
279     return this;
280   if (end > count)
281     end = count;
282   if (start > end)
283     return this;
284   int len = end - start;
285   if (len > 0)
286     {
287       memcpy (value + start, value + start + len, count - end);
288       count -= len;
289     }
290   return this;
291 }
292
293 StringBuilder *
294 StringBuilder::deleteCharAt (int index)
295 {
296   if (index < 0 || index >= count)
297     return this;
298   memcpy (value + index, value + index + 1, count - index - 1);
299   count--;
300   return this;
301 }
302
303 bool
304 StringBuilder::endsWith (const char str[])
305 {
306   if (str == NULL)
307     {
308       if (count == 0)
309         return true;
310       return false;
311     }
312   int len = (int) strlen (str);
313   if (len == 0)
314     return true;
315   int start = count - len;
316   if (start < 0)
317     return false;
318   int res = strncmp ((const char *) (value + start), str, len);
319   if (res != 0)
320     return false;
321   return true;
322 }
323
324 StringBuilder *
325 StringBuilder::insert (int index, const char str[], int offset, int len)
326 {
327   if (index < 0 || index > count)
328     return this;
329   if (offset < 0 || len < 0 || offset > ((int) strlen (str)) - len)
330     return this;
331   int newCount = count + len;
332   if (newCount > maxCapacity)
333     expandCapacity (newCount);
334   memcpy (value + index + len, value + index, count - index);
335   memcpy (value + index, str + offset, len);
336   count = newCount;
337   return this;
338 }
339
340 StringBuilder *
341 StringBuilder::insert (int offset, const char str[])
342 {
343   if (offset < 0 || offset > count)
344     return this;
345   int len = (int) strlen (str);
346   int newCount = count + len;
347   if (newCount > maxCapacity)
348     expandCapacity (newCount);
349   memcpy (value + offset + len, value + offset, count - offset);
350   memcpy (value + offset, str, len);
351   count = newCount;
352   return this;
353 }
354
355 StringBuilder *
356 StringBuilder::insert (int offset, bool b)
357 {
358   return insert (offset, b ? NTXT ("true") : NTXT ("false"));
359 }
360
361 StringBuilder *
362 StringBuilder::insert (int offset, char c)
363 {
364   int newCount = count + 1;
365   if (newCount > maxCapacity)
366     expandCapacity (newCount);
367   memcpy (value + offset + 1, value + offset, count - offset);
368   value[offset] = c;
369   count = newCount;
370   return this;
371 }
372
373 StringBuilder *
374 StringBuilder::insert (int offset, int i)
375 {
376   char buf[16];
377   snprintf (buf, sizeof (buf), NTXT ("%d"), i);
378   insert (offset, buf);
379   return this;
380 }
381
382 StringBuilder *
383 StringBuilder::insert (int offset, long l)
384 {
385   char buf[32];
386   snprintf (buf, sizeof (buf), NTXT ("%ld"), l);
387   insert (offset, buf);
388   return this;
389 }
390
391 StringBuilder *
392 StringBuilder::insert (int offset, float f)
393 {
394   char buf[32];
395   snprintf (buf, sizeof (buf), NTXT ("%f"), (double) f);
396   insert (offset, buf);
397   return this;
398 }
399
400 StringBuilder *
401 StringBuilder::insert (int offset, double d)
402 {
403   char buf[32];
404   snprintf (buf, sizeof (buf), NTXT ("%f"), d);
405   insert (offset, buf);
406   return this;
407 }
408
409 StringBuilder *
410 StringBuilder::reverse ()
411 {
412   int n = count - 1;
413   for (int j = (n - 1) >> 1; j >= 0; --j)
414     {
415       char temp = value[j];
416       char temp2 = value[n - j];
417       value[j] = temp2;
418       value[n - j] = temp;
419     }
420   return this;
421 }
422
423 //String *StringBuilder::toString();
424 char *
425 StringBuilder::toString ()
426 {
427   char *str = (char *) malloc (count + 1);
428   memcpy (str, value, count);
429   str[count] = '\0';
430   return str;
431 }
432
433 void
434 StringBuilder::toFile (FILE *fp)
435 {
436   append ('\0');
437   count--;
438   fprintf (fp, NTXT ("%s"), value);
439 }
440
441 void
442 StringBuilder::toFileLn (FILE *fp)
443 {
444   trim ();
445   append ('\0');
446   count--;
447   fprintf (fp, NTXT ("%s\n"), value);
448 }
449
450 StringBuilder *
451 StringBuilder::sprintf (const char *fmt, ...)
452 {
453   int cnt;
454   setLength (0);
455
456   va_list vp;
457   va_start (vp, fmt);
458   cnt = vsnprintf (value, maxCapacity, fmt, vp);
459   va_end (vp);
460   if (cnt < maxCapacity)
461     {
462       count = cnt;
463       return this;
464     }
465
466   // Have to count the trailing zero
467   ensureCapacity (cnt + 1);
468   va_start (vp, fmt);
469   count = vsnprintf (value, maxCapacity, fmt, vp);
470   va_end (vp);
471   return this;
472 }
473
474 StringBuilder *
475 StringBuilder::appendf (const char *fmt, ...)
476 {
477   va_list vp;
478   va_start (vp, fmt);
479   int cnt = vsnprintf (value + count, maxCapacity - count, fmt, vp);
480   va_end (vp);
481   if (cnt + count < maxCapacity)
482     {
483       count += cnt;
484       return this;
485     }
486
487   // Have to count the trailing zero
488   ensureCapacity (count + cnt + 1);
489   va_start (vp, fmt);
490   count += vsnprintf (value + count, maxCapacity - count, fmt, vp);
491   va_end (vp);
492   return this;
493 }
494
495 int
496 StringBuilder::indexOf (const char str[])
497 {
498   return indexOf (str, 0);
499 }
500
501 int
502 StringBuilder::indexOf (const char str[], int fromIndex)
503 {
504   int len = (int) strlen (str);
505   if (fromIndex >= count)
506     return len == 0 ? count : -1;
507   if (fromIndex < 0)
508     fromIndex = 0;
509   if (len == 0)
510     return fromIndex;
511
512   char first = str[0];
513   int max = (count - len);
514
515   for (int i = fromIndex; i <= max; i++)
516     {
517       /* Look for first character. */
518       if (value[i] != first)
519         while (++i <= max && value[i] != first)
520           ;
521       /* Found first character, now look at the rest of v2 */
522       if (i <= max)
523         {
524           int j = i + 1;
525           int end = j + len - 1;
526           for (int k = 1; j < end && value[j] == str[k]; j++, k++)
527             ;
528           if (j == end)     /* Found whole string. */
529             return i;
530         }
531     }
532   return -1;
533 }
534
535 int
536 StringBuilder::lastIndexOf (const char str[])
537 {
538   return lastIndexOf (str, count);
539 }
540
541 int
542 StringBuilder::lastIndexOf (const char str[], int fromIndex)
543 {
544   /*
545    * Check arguments; return immediately where possible. For
546    * consistency, don't check for null str.
547    */
548   int len = (int) strlen (str);
549   int rightIndex = count - len;
550   if (fromIndex < 0)
551     return -1;
552   if (fromIndex > rightIndex)
553     fromIndex = rightIndex;
554   /* Empty string always matches. */
555   if (len == 0)
556     return fromIndex;
557
558   int strLastIndex = len - 1;
559   char strLastChar = str[strLastIndex];
560   int min = len - 1;
561   int i = min + fromIndex;
562
563   while (true)
564     {
565       while (i >= min && value[i] != strLastChar)
566         i--;
567       if (i < min)
568         return -1;
569
570       int j = i - 1;
571       int start = j - (len - 1);
572       int k = strLastIndex - 1;
573       while (j > start)
574         {
575           if (value[j--] != str[k--])
576             {
577               i--;
578               break;
579             }
580         }
581       if (j == start)
582         return start + 1;
583     }
584 }
585
This page took 0.056732 seconds and 4 git commands to generate.