1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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)
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.
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. */
29 #include "StringBuilder.h"
32 StringBuilder::StringBuilder ()
36 value = (char *) malloc (maxCapacity);
37 memset (value, 0, maxCapacity);
40 StringBuilder::StringBuilder (int capacity)
43 maxCapacity = capacity;
44 value = (char *) malloc (maxCapacity);
45 memset (value, 0, maxCapacity);
48 StringBuilder::~StringBuilder ()
54 StringBuilder::ensureCapacity (int minimumCapacity)
56 if (minimumCapacity > maxCapacity)
57 expandCapacity (minimumCapacity);
61 StringBuilder::expandCapacity (int minimumCapacity)
63 int newCapacity = (maxCapacity + 1) * 2;
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);
77 StringBuilder::trimToSize ()
79 if (count < maxCapacity)
81 char *newValue = (char *) malloc (count);
83 memcpy (newValue, value, count);
90 StringBuilder::trim ()
94 if (value[count - 1] != ' ')
101 StringBuilder::setLength (int newLength)
105 if (newLength > maxCapacity)
106 expandCapacity (newLength);
107 if (count < newLength)
109 for (; count < newLength; count++)
117 StringBuilder::charAt (int index)
119 if (index < 0 || index >= count)
125 StringBuilder::getChars (int srcBegin, int srcEnd, char dst[], int dstBegin)
129 if (srcEnd < 0 || srcEnd > count)
131 if (srcBegin > srcEnd)
133 memcpy (dst + dstBegin, value + srcBegin, srcEnd - srcBegin);
137 StringBuilder::setCharAt (int index, char ch)
139 if (index < 0 || index >= count)
145 StringBuilder::append (StringBuilder *sb)
148 return append (NTXT ("null"));
150 int newcount = count + len;
151 if (newcount > maxCapacity)
152 expandCapacity (newcount);
153 sb->getChars (0, len, value, count);
159 StringBuilder::append (const char str[])
161 int len = (int) strlen (str);
162 int newCount = count + len;
163 if (newCount > maxCapacity)
164 expandCapacity (newCount);
165 memcpy (value + count, str, len);
171 StringBuilder::append (const char str[], int offset, int len)
173 int newCount = count + len;
174 if (newCount > maxCapacity)
175 expandCapacity (newCount);
176 memcpy (value + count, str + offset, len);
182 StringBuilder::append (bool b)
185 append (NTXT ("true"));
187 append (NTXT ("false"));
192 StringBuilder::append (char c)
194 int newCount = count + 1;
195 if (newCount > maxCapacity)
197 expandCapacity (newCount);
204 StringBuilder::append (int i)
207 snprintf (buf, sizeof (buf), NTXT ("%d"), i);
213 StringBuilder::append (unsigned int i)
216 snprintf (buf, sizeof (buf), NTXT ("%u"), i);
222 StringBuilder::append (long lng)
225 snprintf (buf, sizeof (buf), NTXT ("%ld"), lng);
231 StringBuilder::append (unsigned long lng)
234 snprintf (buf, sizeof (buf), NTXT ("%lu"), lng);
240 StringBuilder::append (long long lng)
243 snprintf (buf, sizeof (buf), NTXT ("%lld"), lng);
249 StringBuilder::append (unsigned long long lng)
252 snprintf (buf, sizeof (buf), NTXT ("%llu"), lng);
258 StringBuilder::append (float f)
261 snprintf (buf, sizeof (buf), NTXT ("%f"), (double) f);
267 StringBuilder::append (double d)
270 snprintf (buf, sizeof (buf), NTXT ("%f"), d);
276 StringBuilder::_delete (int start, int end)
284 int len = end - start;
287 memcpy (value + start, value + start + len, count - end);
294 StringBuilder::deleteCharAt (int index)
296 if (index < 0 || index >= count)
298 memcpy (value + index, value + index + 1, count - index - 1);
304 StringBuilder::endsWith (const char str[])
312 int len = (int) strlen (str);
315 int start = count - len;
318 int res = strncmp ((const char *) (value + start), str, len);
325 StringBuilder::insert (int index, const char str[], int offset, int len)
327 if (index < 0 || index > count)
329 if (offset < 0 || len < 0 || offset > ((int) strlen (str)) - len)
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);
341 StringBuilder::insert (int offset, const char str[])
343 if (offset < 0 || offset > count)
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);
356 StringBuilder::insert (int offset, bool b)
358 return insert (offset, b ? NTXT ("true") : NTXT ("false"));
362 StringBuilder::insert (int offset, char c)
364 int newCount = count + 1;
365 if (newCount > maxCapacity)
366 expandCapacity (newCount);
367 memcpy (value + offset + 1, value + offset, count - offset);
374 StringBuilder::insert (int offset, int i)
377 snprintf (buf, sizeof (buf), NTXT ("%d"), i);
378 insert (offset, buf);
383 StringBuilder::insert (int offset, long l)
386 snprintf (buf, sizeof (buf), NTXT ("%ld"), l);
387 insert (offset, buf);
392 StringBuilder::insert (int offset, float f)
395 snprintf (buf, sizeof (buf), NTXT ("%f"), (double) f);
396 insert (offset, buf);
401 StringBuilder::insert (int offset, double d)
404 snprintf (buf, sizeof (buf), NTXT ("%f"), d);
405 insert (offset, buf);
410 StringBuilder::reverse ()
413 for (int j = (n - 1) >> 1; j >= 0; --j)
415 char temp = value[j];
416 char temp2 = value[n - j];
423 //String *StringBuilder::toString();
425 StringBuilder::toString ()
427 char *str = (char *) malloc (count + 1);
428 memcpy (str, value, count);
434 StringBuilder::toFile (FILE *fp)
438 fprintf (fp, NTXT ("%s"), value);
442 StringBuilder::toFileLn (FILE *fp)
447 fprintf (fp, NTXT ("%s\n"), value);
451 StringBuilder::sprintf (const char *fmt, ...)
458 cnt = vsnprintf (value, maxCapacity, fmt, vp);
460 if (cnt < maxCapacity)
466 // Have to count the trailing zero
467 ensureCapacity (cnt + 1);
469 count = vsnprintf (value, maxCapacity, fmt, vp);
475 StringBuilder::appendf (const char *fmt, ...)
479 int cnt = vsnprintf (value + count, maxCapacity - count, fmt, vp);
481 if (cnt + count < maxCapacity)
487 // Have to count the trailing zero
488 ensureCapacity (count + cnt + 1);
490 count += vsnprintf (value + count, maxCapacity - count, fmt, vp);
496 StringBuilder::indexOf (const char str[])
498 return indexOf (str, 0);
502 StringBuilder::indexOf (const char str[], int fromIndex)
504 int len = (int) strlen (str);
505 if (fromIndex >= count)
506 return len == 0 ? count : -1;
513 int max = (count - len);
515 for (int i = fromIndex; i <= max; i++)
517 /* Look for first character. */
518 if (value[i] != first)
519 while (++i <= max && value[i] != first)
521 /* Found first character, now look at the rest of v2 */
525 int end = j + len - 1;
526 for (int k = 1; j < end && value[j] == str[k]; j++, k++)
528 if (j == end) /* Found whole string. */
536 StringBuilder::lastIndexOf (const char str[])
538 return lastIndexOf (str, count);
542 StringBuilder::lastIndexOf (const char str[], int fromIndex)
545 * Check arguments; return immediately where possible. For
546 * consistency, don't check for null str.
548 int len = (int) strlen (str);
549 int rightIndex = count - len;
552 if (fromIndex > rightIndex)
553 fromIndex = rightIndex;
554 /* Empty string always matches. */
558 int strLastIndex = len - 1;
559 char strLastChar = str[strLastIndex];
561 int i = min + fromIndex;
565 while (i >= min && value[i] != strLastChar)
571 int start = j - (len - 1);
572 int k = strLastIndex - 1;
575 if (value[j--] != str[k--])