diff options
Diffstat (limited to 'gprofng/src/StringBuilder.cc')
-rw-r--r-- | gprofng/src/StringBuilder.cc | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/gprofng/src/StringBuilder.cc b/gprofng/src/StringBuilder.cc new file mode 100644 index 00000000000..a9656d9b9ae --- /dev/null +++ b/gprofng/src/StringBuilder.cc @@ -0,0 +1,585 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <values.h> +#include <stdarg.h> + +#include "gp-defs.h" +#include "StringBuilder.h" +#include "i18n.h" + +StringBuilder::StringBuilder () +{ + count = 0; + maxCapacity = 16; + value = (char *) malloc (maxCapacity); + memset (value, 0, maxCapacity); +} + +StringBuilder::StringBuilder (int capacity) +{ + count = 0; + maxCapacity = capacity; + value = (char *) malloc (maxCapacity); + memset (value, 0, maxCapacity); +} + +StringBuilder::~StringBuilder () +{ + free (value); +} + +void +StringBuilder::ensureCapacity (int minimumCapacity) +{ + if (minimumCapacity > maxCapacity) + expandCapacity (minimumCapacity); +} + +void +StringBuilder::expandCapacity (int minimumCapacity) +{ + int newCapacity = (maxCapacity + 1) * 2; + if (newCapacity < 0) + newCapacity = MAXINT; + else if (minimumCapacity > newCapacity) + newCapacity = minimumCapacity; + char *newValue = (char *) malloc (newCapacity); + maxCapacity = newCapacity; + memcpy (newValue, value, count); + memset (newValue + count, 0, maxCapacity - count); + free (value); + value = newValue; +} + +void +StringBuilder::trimToSize () +{ + if (count < maxCapacity) + { + char *newValue = (char *) malloc (count); + maxCapacity = count; + memcpy (newValue, value, count); + free (value); + value = newValue; + } +} + +void +StringBuilder::trim () +{ + while (count > 0) + { + if (value[count - 1] != ' ') + break; + count--; + } +} + +void +StringBuilder::setLength (int newLength) +{ + if (newLength < 0) + return; + if (newLength > maxCapacity) + expandCapacity (newLength); + if (count < newLength) + { + for (; count < newLength; count++) + value[count] = '\0'; + } + else + count = newLength; +} + +char +StringBuilder::charAt (int index) +{ + if (index < 0 || index >= count) + return 0; + return value[index]; +} + +void +StringBuilder::getChars (int srcBegin, int srcEnd, char dst[], int dstBegin) +{ + if (srcBegin < 0) + return; + if (srcEnd < 0 || srcEnd > count) + return; + if (srcBegin > srcEnd) + return; + memcpy (dst + dstBegin, value + srcBegin, srcEnd - srcBegin); +} + +void +StringBuilder::setCharAt (int index, char ch) +{ + if (index < 0 || index >= count) + return; + value[index] = ch; +} + +StringBuilder * +StringBuilder::append (StringBuilder *sb) +{ + if (sb == NULL) + return append (NTXT ("null")); + int len = sb->count; + int newcount = count + len; + if (newcount > maxCapacity) + expandCapacity (newcount); + sb->getChars (0, len, value, count); + count = newcount; + return this; +} + +StringBuilder * +StringBuilder::append (const char str[]) +{ + int len = (int) strlen (str); + int newCount = count + len; + if (newCount > maxCapacity) + expandCapacity (newCount); + memcpy (value + count, str, len); + count = newCount; + return this; +} + +StringBuilder * +StringBuilder::append (const char str[], int offset, int len) +{ + int newCount = count + len; + if (newCount > maxCapacity) + expandCapacity (newCount); + memcpy (value + count, str + offset, len); + count = newCount; + return this; +} + +StringBuilder * +StringBuilder::append (bool b) +{ + if (b) + append (NTXT ("true")); + else + append (NTXT ("false")); + return this; +} + +StringBuilder * +StringBuilder::append (char c) +{ + int newCount = count + 1; + if (newCount > maxCapacity) + { + expandCapacity (newCount); + } + value[count++] = c; + return this; +} + +StringBuilder * +StringBuilder::append (int i) +{ + char buf[16]; + snprintf (buf, sizeof (buf), NTXT ("%d"), i); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (unsigned int i) +{ + char buf[16]; + snprintf (buf, sizeof (buf), NTXT ("%u"), i); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (long lng) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%ld"), lng); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (unsigned long lng) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%lu"), lng); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (long long lng) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%lld"), lng); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (unsigned long long lng) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%llu"), lng); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (float f) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%f"), (double) f); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::append (double d) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%f"), d); + append (buf); + return this; +} + +StringBuilder * +StringBuilder::_delete (int start, int end) +{ + if (start < 0) + return this; + if (end > count) + end = count; + if (start > end) + return this; + int len = end - start; + if (len > 0) + { + memcpy (value + start, value + start + len, count - end); + count -= len; + } + return this; +} + +StringBuilder * +StringBuilder::deleteCharAt (int index) +{ + if (index < 0 || index >= count) + return this; + memcpy (value + index, value + index + 1, count - index - 1); + count--; + return this; +} + +bool +StringBuilder::endsWith (const char str[]) +{ + if (str == NULL) + { + if (count == 0) + return true; + return false; + } + int len = (int) strlen (str); + if (len == 0) + return true; + int start = count - len; + if (start < 0) + return false; + int res = strncmp ((const char *) (value + start), str, len); + if (res != 0) + return false; + return true; +} + +StringBuilder * +StringBuilder::insert (int index, const char str[], int offset, int len) +{ + if (index < 0 || index > count) + return this; + if (offset < 0 || len < 0 || offset > ((int) strlen (str)) - len) + return this; + int newCount = count + len; + if (newCount > maxCapacity) + expandCapacity (newCount); + memcpy (value + index + len, value + index, count - index); + memcpy (value + index, str + offset, len); + count = newCount; + return this; +} + +StringBuilder * +StringBuilder::insert (int offset, const char str[]) +{ + if (offset < 0 || offset > count) + return this; + int len = (int) strlen (str); + int newCount = count + len; + if (newCount > maxCapacity) + expandCapacity (newCount); + memcpy (value + offset + len, value + offset, count - offset); + memcpy (value + offset, str, len); + count = newCount; + return this; +} + +StringBuilder * +StringBuilder::insert (int offset, bool b) +{ + return insert (offset, b ? NTXT ("true") : NTXT ("false")); +} + +StringBuilder * +StringBuilder::insert (int offset, char c) +{ + int newCount = count + 1; + if (newCount > maxCapacity) + expandCapacity (newCount); + memcpy (value + offset + 1, value + offset, count - offset); + value[offset] = c; + count = newCount; + return this; +} + +StringBuilder * +StringBuilder::insert (int offset, int i) +{ + char buf[16]; + snprintf (buf, sizeof (buf), NTXT ("%d"), i); + insert (offset, buf); + return this; +} + +StringBuilder * +StringBuilder::insert (int offset, long l) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%ld"), l); + insert (offset, buf); + return this; +} + +StringBuilder * +StringBuilder::insert (int offset, float f) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%f"), (double) f); + insert (offset, buf); + return this; +} + +StringBuilder * +StringBuilder::insert (int offset, double d) +{ + char buf[32]; + snprintf (buf, sizeof (buf), NTXT ("%f"), d); + insert (offset, buf); + return this; +} + +StringBuilder * +StringBuilder::reverse () +{ + int n = count - 1; + for (int j = (n - 1) >> 1; j >= 0; --j) + { + char temp = value[j]; + char temp2 = value[n - j]; + value[j] = temp2; + value[n - j] = temp; + } + return this; +} + +//String *StringBuilder::toString(); +char * +StringBuilder::toString () +{ + char *str = (char *) malloc (count + 1); + memcpy (str, value, count); + str[count] = '\0'; + return str; +} + +void +StringBuilder::toFile (FILE *fp) +{ + append ('\0'); + count--; + fprintf (fp, NTXT ("%s"), value); +} + +void +StringBuilder::toFileLn (FILE *fp) +{ + trim (); + append ('\0'); + count--; + fprintf (fp, NTXT ("%s\n"), value); +} + +StringBuilder * +StringBuilder::sprintf (const char *fmt, ...) +{ + int cnt; + setLength (0); + + va_list vp; + va_start (vp, fmt); + cnt = vsnprintf (value, maxCapacity, fmt, vp); + va_end (vp); + if (cnt < maxCapacity) + { + count = cnt; + return this; + } + + // Have to count the trailing zero + ensureCapacity (cnt + 1); + va_start (vp, fmt); + count = vsnprintf (value, maxCapacity, fmt, vp); + va_end (vp); + return this; +} + +StringBuilder * +StringBuilder::appendf (const char *fmt, ...) +{ + va_list vp; + va_start (vp, fmt); + int cnt = vsnprintf (value + count, maxCapacity - count, fmt, vp); + va_end (vp); + if (cnt + count < maxCapacity) + { + count += cnt; + return this; + } + + // Have to count the trailing zero + ensureCapacity (count + cnt + 1); + va_start (vp, fmt); + count += vsnprintf (value + count, maxCapacity - count, fmt, vp); + va_end (vp); + return this; +} + +int +StringBuilder::indexOf (const char str[]) +{ + return indexOf (str, 0); +} + +int +StringBuilder::indexOf (const char str[], int fromIndex) +{ + int len = (int) strlen (str); + if (fromIndex >= count) + return len == 0 ? count : -1; + if (fromIndex < 0) + fromIndex = 0; + if (len == 0) + return fromIndex; + + char first = str[0]; + int max = (count - len); + + for (int i = fromIndex; i <= max; i++) + { + /* Look for first character. */ + if (value[i] != first) + while (++i <= max && value[i] != first) + ; + /* Found first character, now look at the rest of v2 */ + if (i <= max) + { + int j = i + 1; + int end = j + len - 1; + for (int k = 1; j < end && value[j] == str[k]; j++, k++) + ; + if (j == end) /* Found whole string. */ + return i; + } + } + return -1; +} + +int +StringBuilder::lastIndexOf (const char str[]) +{ + return lastIndexOf (str, count); +} + +int +StringBuilder::lastIndexOf (const char str[], int fromIndex) +{ + /* + * Check arguments; return immediately where possible. For + * consistency, don't check for null str. + */ + int len = (int) strlen (str); + int rightIndex = count - len; + if (fromIndex < 0) + return -1; + if (fromIndex > rightIndex) + fromIndex = rightIndex; + /* Empty string always matches. */ + if (len == 0) + return fromIndex; + + int strLastIndex = len - 1; + char strLastChar = str[strLastIndex]; + int min = len - 1; + int i = min + fromIndex; + + while (true) + { + while (i >= min && value[i] != strLastChar) + i--; + if (i < min) + return -1; + + int j = i - 1; + int start = j - (len - 1); + int k = strLastIndex - 1; + while (j > start) + { + if (value[j--] != str[k--]) + { + i--; + break; + } + } + if (j == start) + return start + 1; + } +} + |