1 /* Copyright (C) 2021-2024 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. */
30 #include "StringBuilder.h"
33 StringBuilder::StringBuilder ()
37 value
= (char *) malloc (maxCapacity
);
38 memset (value
, 0, maxCapacity
);
41 StringBuilder::StringBuilder (int capacity
)
44 maxCapacity
= capacity
;
45 value
= (char *) malloc (maxCapacity
);
46 memset (value
, 0, maxCapacity
);
49 StringBuilder::~StringBuilder ()
55 StringBuilder::ensureCapacity (int minimumCapacity
)
57 if (minimumCapacity
> maxCapacity
)
58 expandCapacity (minimumCapacity
);
62 StringBuilder::expandCapacity (int minimumCapacity
)
64 int newCapacity
= (maxCapacity
+ 1) * 2;
67 else if (minimumCapacity
> newCapacity
)
68 newCapacity
= minimumCapacity
;
69 char *newValue
= (char *) malloc (newCapacity
);
70 maxCapacity
= newCapacity
;
71 memcpy (newValue
, value
, count
);
72 memset (newValue
+ count
, 0, maxCapacity
- count
);
78 StringBuilder::trimToSize ()
80 if (count
< maxCapacity
)
82 char *newValue
= (char *) malloc (count
);
84 memcpy (newValue
, value
, count
);
91 StringBuilder::trim ()
95 if (value
[count
- 1] != ' ')
102 StringBuilder::setLength (int newLength
)
106 if (newLength
> maxCapacity
)
107 expandCapacity (newLength
);
108 if (count
< newLength
)
110 for (; count
< newLength
; count
++)
118 StringBuilder::charAt (int index
)
120 if (index
< 0 || index
>= count
)
126 StringBuilder::getChars (int srcBegin
, int srcEnd
, char dst
[], int dstBegin
)
130 if (srcEnd
< 0 || srcEnd
> count
)
132 if (srcBegin
> srcEnd
)
134 memcpy (dst
+ dstBegin
, value
+ srcBegin
, srcEnd
- srcBegin
);
138 StringBuilder::setCharAt (int index
, char ch
)
140 if (index
< 0 || index
>= count
)
146 StringBuilder::append (StringBuilder
*sb
)
149 return append (NTXT ("null"));
151 int newcount
= count
+ len
;
152 if (newcount
> maxCapacity
)
153 expandCapacity (newcount
);
154 sb
->getChars (0, len
, value
, count
);
160 StringBuilder::append (const char str
[])
162 int len
= (int) strlen (str
);
163 int newCount
= count
+ len
;
164 if (newCount
> maxCapacity
)
165 expandCapacity (newCount
);
166 memcpy (value
+ count
, str
, len
);
172 StringBuilder::append (const char str
[], int offset
, int len
)
174 int newCount
= count
+ len
;
175 if (newCount
> maxCapacity
)
176 expandCapacity (newCount
);
177 memcpy (value
+ count
, str
+ offset
, len
);
183 StringBuilder::append (bool b
)
186 append (NTXT ("true"));
188 append (NTXT ("false"));
193 StringBuilder::append (char c
)
195 int newCount
= count
+ 1;
196 if (newCount
> maxCapacity
)
198 expandCapacity (newCount
);
205 StringBuilder::append (int i
)
208 snprintf (buf
, sizeof (buf
), NTXT ("%d"), i
);
214 StringBuilder::append (unsigned int i
)
217 snprintf (buf
, sizeof (buf
), NTXT ("%u"), i
);
223 StringBuilder::append (long lng
)
226 snprintf (buf
, sizeof (buf
), NTXT ("%ld"), lng
);
232 StringBuilder::append (unsigned long lng
)
235 snprintf (buf
, sizeof (buf
), NTXT ("%lu"), lng
);
241 StringBuilder::append (long long lng
)
244 snprintf (buf
, sizeof (buf
), NTXT ("%lld"), lng
);
250 StringBuilder::append (unsigned long long lng
)
253 snprintf (buf
, sizeof (buf
), NTXT ("%llu"), lng
);
259 StringBuilder::append (float f
)
262 snprintf (buf
, sizeof (buf
), NTXT ("%f"), (double) f
);
268 StringBuilder::append (double d
)
271 snprintf (buf
, sizeof (buf
), NTXT ("%f"), d
);
277 StringBuilder::_delete (int start
, int end
)
285 int len
= end
- start
;
288 memcpy (value
+ start
, value
+ start
+ len
, count
- end
);
295 StringBuilder::deleteCharAt (int index
)
297 if (index
< 0 || index
>= count
)
299 memcpy (value
+ index
, value
+ index
+ 1, count
- index
- 1);
305 StringBuilder::endsWith (const char str
[])
313 int len
= (int) strlen (str
);
316 int start
= count
- len
;
319 int res
= strncmp ((const char *) (value
+ start
), str
, len
);
326 StringBuilder::insert (int index
, const char str
[], int offset
, int len
)
328 if (index
< 0 || index
> count
)
330 if (offset
< 0 || len
< 0 || offset
> ((int) strlen (str
)) - len
)
332 int newCount
= count
+ len
;
333 if (newCount
> maxCapacity
)
334 expandCapacity (newCount
);
335 memcpy (value
+ index
+ len
, value
+ index
, count
- index
);
336 memcpy (value
+ index
, str
+ offset
, len
);
342 StringBuilder::insert (int offset
, const char str
[])
344 if (offset
< 0 || offset
> count
)
346 int len
= (int) strlen (str
);
347 int newCount
= count
+ len
;
348 if (newCount
> maxCapacity
)
349 expandCapacity (newCount
);
350 memcpy (value
+ offset
+ len
, value
+ offset
, count
- offset
);
351 memcpy (value
+ offset
, str
, len
);
357 StringBuilder::insert (int offset
, bool b
)
359 return insert (offset
, b
? NTXT ("true") : NTXT ("false"));
363 StringBuilder::insert (int offset
, char c
)
365 int newCount
= count
+ 1;
366 if (newCount
> maxCapacity
)
367 expandCapacity (newCount
);
368 memcpy (value
+ offset
+ 1, value
+ offset
, count
- offset
);
375 StringBuilder::insert (int offset
, int i
)
378 snprintf (buf
, sizeof (buf
), NTXT ("%d"), i
);
379 insert (offset
, buf
);
384 StringBuilder::insert (int offset
, long l
)
387 snprintf (buf
, sizeof (buf
), NTXT ("%ld"), l
);
388 insert (offset
, buf
);
393 StringBuilder::insert (int offset
, float f
)
396 snprintf (buf
, sizeof (buf
), NTXT ("%f"), (double) f
);
397 insert (offset
, buf
);
402 StringBuilder::insert (int offset
, double d
)
405 snprintf (buf
, sizeof (buf
), NTXT ("%f"), d
);
406 insert (offset
, buf
);
411 StringBuilder::reverse ()
414 for (int j
= (n
- 1) >> 1; j
>= 0; --j
)
416 char temp
= value
[j
];
417 char temp2
= value
[n
- j
];
424 //String *StringBuilder::toString();
426 StringBuilder::toString ()
428 char *str
= (char *) malloc (count
+ 1);
429 memcpy (str
, value
, count
);
435 StringBuilder::toFile (FILE *fp
)
439 fprintf (fp
, NTXT ("%s"), value
);
443 StringBuilder::toFileLn (FILE *fp
)
448 fprintf (fp
, NTXT ("%s\n"), value
);
452 StringBuilder::write (int fd
)
455 ::write (fd
, value
, count
);
459 StringBuilder::sprintf (const char *fmt
, ...)
466 cnt
= vsnprintf (value
, maxCapacity
, fmt
, vp
);
468 if (cnt
< maxCapacity
)
474 // Have to count the trailing zero
475 ensureCapacity (cnt
+ 1);
477 count
= vsnprintf (value
, maxCapacity
, fmt
, vp
);
483 StringBuilder::appendf (const char *fmt
, ...)
487 int cnt
= vsnprintf (value
+ count
, maxCapacity
- count
, fmt
, vp
);
489 if (cnt
+ count
< maxCapacity
)
495 // Have to count the trailing zero
496 ensureCapacity (count
+ cnt
+ 1);
498 count
+= vsnprintf (value
+ count
, maxCapacity
- count
, fmt
, vp
);
504 StringBuilder::indexOf (const char str
[])
506 return indexOf (str
, 0);
510 StringBuilder::indexOf (const char str
[], int fromIndex
)
512 int len
= (int) strlen (str
);
513 if (fromIndex
>= count
)
514 return len
== 0 ? count
: -1;
521 int max
= (count
- len
);
523 for (int i
= fromIndex
; i
<= max
; i
++)
525 /* Look for first character. */
526 if (value
[i
] != first
)
527 while (++i
<= max
&& value
[i
] != first
)
529 /* Found first character, now look at the rest of v2 */
533 int end
= j
+ len
- 1;
534 for (int k
= 1; j
< end
&& value
[j
] == str
[k
]; j
++, k
++)
536 if (j
== end
) /* Found whole string. */
544 StringBuilder::lastIndexOf (const char str
[])
546 return lastIndexOf (str
, count
);
550 StringBuilder::lastIndexOf (const char str
[], int fromIndex
)
553 * Check arguments; return immediately where possible. For
554 * consistency, don't check for null str.
556 int len
= (int) strlen (str
);
557 int rightIndex
= count
- len
;
560 if (fromIndex
> rightIndex
)
561 fromIndex
= rightIndex
;
562 /* Empty string always matches. */
566 int strLastIndex
= len
- 1;
567 char strLastChar
= str
[strLastIndex
];
569 int i
= min
+ fromIndex
;
573 while (i
>= min
&& value
[i
] != strLastChar
)
579 int start
= j
- (len
- 1);
580 int k
= strLastIndex
- 1;
583 if (value
[j
--] != str
[k
--])