43 explicit String() noexcept
46 fBufferAlloc(
false) {}
51 explicit String(
const char c) noexcept
56 const char ch[2] = { c,
'\0' };
63 explicit String(
char*
const strBuf,
const bool reallocData =
true) noexcept
68 if (reallocData || strBuf ==
nullptr)
75 fBufferLen = std::strlen(strBuf);
83 explicit String(
const char*
const strBuf) noexcept
91 #if __cplusplus >= 201703L
95 explicit String(
const std::string_view& strView) noexcept
100 _dup(strView.data(), strView.size());
107 explicit String(
const int value) noexcept
113 std::snprintf(strBuf, 0xff,
"%d", value);
122 explicit String(
const unsigned int value,
const bool hexadecimal =
false) noexcept
128 std::snprintf(strBuf, 0xff, hexadecimal ?
"0x%x" :
"%u", value);
137 explicit String(
const long value) noexcept
143 std::snprintf(strBuf, 0xff,
"%ld", value);
152 explicit String(
const unsigned long value,
const bool hexadecimal =
false) noexcept
158 std::snprintf(strBuf, 0xff, hexadecimal ?
"0x%lx" :
"%lu", value);
167 explicit String(
const long long value) noexcept
173 std::snprintf(strBuf, 0xff,
"%lld", value);
182 explicit String(
const unsigned long long value,
const bool hexadecimal =
false) noexcept
188 std::snprintf(strBuf, 0xff, hexadecimal ?
"0x%llx" :
"%llu", value);
197 explicit String(
const float value) noexcept
206 std::snprintf(strBuf, 0xff,
"%.12g",
static_cast<double>(value));
217 explicit String(
const double value) noexcept
226 std::snprintf(strBuf, 0xff,
"%.24g", value);
240 String(
const String& str) noexcept
256 DAF_SAFE_ASSERT_RETURN(fBuffer !=
nullptr,);
263 fBufferAlloc =
false;
272 size_t length()
const noexcept
280 bool isEmpty()
const noexcept
282 return (fBufferLen == 0);
288 bool isNotEmpty()
const noexcept
290 return (fBufferLen != 0);
296 bool contains(
const char c)
const noexcept
298 for (
size_t i=0; i<fBufferLen; ++i)
310 bool contains(
const char*
const strBuf,
const bool ignoreCase =
false)
const noexcept
312 DAF_SAFE_ASSERT_RETURN(strBuf !=
nullptr,
false);
317 return (strcasestr(fBuffer, strBuf) !=
nullptr);
319 String tmp1(fBuffer), tmp2(strBuf);
322 if (tmp1.fBuffer == _null() || tmp2.fBuffer == _null())
327 return (std::strstr(tmp1, tmp2) !=
nullptr);
331 return (std::strstr(fBuffer, strBuf) !=
nullptr);
337 bool isDigit(
const size_t pos)
const noexcept
339 DAF_SAFE_ASSERT_RETURN(pos < fBufferLen,
false);
341 return (fBuffer[pos] >=
'0' && fBuffer[pos] <=
'9');
347 bool startsWith(
const char c)
const noexcept
349 DAF_SAFE_ASSERT_RETURN(c !=
'\0',
false);
351 return (fBufferLen > 0 && fBuffer[0] == c);
357 bool startsWith(
const char*
const prefix)
const noexcept
359 DAF_SAFE_ASSERT_RETURN(prefix !=
nullptr,
false);
361 const size_t prefixLen(std::strlen(prefix));
363 if (fBufferLen < prefixLen)
366 return (std::strncmp(fBuffer, prefix, prefixLen) == 0);
372 bool endsWith(
const char c)
const noexcept
374 DAF_SAFE_ASSERT_RETURN(c !=
'\0',
false);
376 return (fBufferLen > 0 && fBuffer[fBufferLen-1] == c);
382 bool endsWith(
const char*
const suffix)
const noexcept
384 DAF_SAFE_ASSERT_RETURN(suffix !=
nullptr,
false);
386 const size_t suffixLen(std::strlen(suffix));
388 if (fBufferLen < suffixLen)
391 return (std::strncmp(fBuffer + (fBufferLen-suffixLen), suffix, suffixLen) == 0);
398 size_t find(
const char c,
bool*
const found =
nullptr)
const noexcept
400 if (fBufferLen == 0 || c ==
'\0')
402 if (found !=
nullptr)
407 for (
size_t i=0; i < fBufferLen; ++i)
411 if (found !=
nullptr)
417 if (found !=
nullptr)
426 size_t find(
const char*
const strBuf,
bool*
const found =
nullptr)
const noexcept
428 if (fBufferLen == 0 || strBuf ==
nullptr || strBuf[0] ==
'\0')
430 if (found !=
nullptr)
435 if (
char*
const subStrBuf = std::strstr(fBuffer, strBuf))
437 const ssize_t ret(subStrBuf - fBuffer);
442 d_safe_assert_int(
"ret >= 0", __FILE__, __LINE__,
int(ret));
444 if (found !=
nullptr)
449 if (found !=
nullptr)
451 return static_cast<size_t>(ret);
454 if (found !=
nullptr)
463 size_t rfind(
const char c,
bool*
const found =
nullptr)
const noexcept
465 if (fBufferLen == 0 || c ==
'\0')
467 if (found !=
nullptr)
472 for (
size_t i=fBufferLen; i > 0; --i)
474 if (fBuffer[i-1] == c)
476 if (found !=
nullptr)
482 if (found !=
nullptr)
491 size_t rfind(
const char*
const strBuf,
bool*
const found =
nullptr)
const noexcept
493 if (found !=
nullptr)
496 if (fBufferLen == 0 || strBuf ==
nullptr || strBuf[0] ==
'\0')
499 const size_t strBufLen(std::strlen(strBuf));
501 size_t ret = fBufferLen;
502 const char* tmpBuf = fBuffer;
504 for (
size_t i=0; i < fBufferLen; ++i)
506 if (std::strstr(tmpBuf+1, strBuf) ==
nullptr && std::strncmp(tmpBuf, strBuf, strBufLen) == 0)
508 if (found !=
nullptr)
517 return fBufferLen-ret;
523 void clear()
noexcept
531 String& replace(
const char before,
const char after)
noexcept
533 DAF_SAFE_ASSERT_RETURN(before !=
'\0' , *
this);
535 for (
size_t i=0; i < fBufferLen; ++i)
537 if (fBuffer[i] == before)
547 String& remove(
const char c)
noexcept
549 DAF_SAFE_ASSERT_RETURN(c !=
'\0', *
this);
554 for (
size_t i=0; i < fBufferLen; ++i)
559 std::memmove(fBuffer+i, fBuffer+i+1, fBufferLen-i);
563 fBuffer[fBufferLen] =
'\0';
570 String& truncate(
const size_t n)
noexcept
584 String& toBasic()
noexcept
586 for (
size_t i=0; i < fBufferLen; ++i)
588 if (fBuffer[i] >=
'0' && fBuffer[i] <=
'9')
590 if (fBuffer[i] >=
'A' && fBuffer[i] <=
'Z')
592 if (fBuffer[i] >=
'a' && fBuffer[i] <=
'z')
594 if (fBuffer[i] ==
'_')
606 String& toLower()
noexcept
608 static constexpr const char kCharDiff =
'a' -
'A';
610 for (
size_t i=0; i < fBufferLen; ++i)
612 if (fBuffer[i] >=
'A' && fBuffer[i] <=
'Z')
613 fBuffer[i] =
static_cast<char>(fBuffer[i] + kCharDiff);
622 String& toUpper()
noexcept
624 static constexpr const char kCharDiff =
'a' -
'A';
626 for (
size_t i=0; i < fBufferLen; ++i)
628 if (fBuffer[i] >=
'a' && fBuffer[i] <=
'z')
629 fBuffer[i] =
static_cast<char>(fBuffer[i] - kCharDiff);
639 String asBasic()
const noexcept
649 String asLower()
const noexcept
659 String asUpper()
const noexcept
668 const char* buffer()
const noexcept
678 char* getAndReleaseBuffer()
noexcept
680 char* ret = fBufferLen > 0 ? fBuffer :
nullptr;
683 fBufferAlloc =
false;
691 static String asBase64(
const void*
const data,
const size_t dataSize)
693 static constexpr const char*
const kBase64Chars =
694 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
695 "abcdefghijklmnopqrstuvwxyz"
698 const size_t strBufSize = std::min(d_nextPowerOf2(
static_cast<uint32_t
>(dataSize/3)), 65536U);
699 char* strBuf =
static_cast<char*
>(std::malloc(strBufSize));
700 DAF_SAFE_ASSERT_RETURN(strBuf !=
nullptr, String());
702 strBuf[strBufSize] =
'\0';
703 size_t strBufIndex = 0;
705 const uchar* bytesToEncode =
static_cast<const uchar*
>(data);
708 uint charArray3[3], charArray4[4];
712 for (
size_t s = 0; s < dataSize; ++s)
714 charArray3[i++] = *(bytesToEncode++);
718 charArray4[0] = (charArray3[0] & 0xfc) >> 2;
719 charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
720 charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
721 charArray4[3] = charArray3[2] & 0x3f;
723 for (i = 0; i < 4; ++i)
724 strBuf[strBufIndex++] = kBase64Chars[charArray4[i]];
726 if (strBufIndex >= strBufSize - 7)
728 strBuf[strBufIndex] =
'\0';
739 for (j = i; j < 3; ++j)
740 charArray3[j] =
'\0';
742 charArray4[0] = (charArray3[0] & 0xfc) >> 2;
743 charArray4[1] = ((charArray3[0] & 0x03) << 4) + ((charArray3[1] & 0xf0) >> 4);
744 charArray4[2] = ((charArray3[1] & 0x0f) << 2) + ((charArray3[2] & 0xc0) >> 6);
745 charArray4[3] = charArray3[2] & 0x3f;
747 for (j = 0; j < 4 && i < 3 && j < i + 1; ++j)
748 strBuf[strBufIndex++] = kBase64Chars[charArray4[j]];
751 strBuf[strBufIndex++] =
'=';
754 if (strBufIndex != 0)
756 strBuf[strBufIndex] =
'\0';
767 String& urlEncode()
noexcept
769 static constexpr const char*
const kHexChars =
"0123456789ABCDEF";
774 char*
const newbuf =
static_cast<char*
>(std::malloc(fBufferLen * 3 + 1));
775 DAF_SAFE_ASSERT_RETURN(newbuf !=
nullptr, *
this);
777 char* newbufptr = newbuf;
779 for (
size_t i=0; i < fBufferLen; ++i)
781 const char c = fBuffer[i];
873 *newbufptr++ = kHexChars[(c >> 4) & 0xf];
874 *newbufptr++ = kHexChars[c & 0xf];
883 fBufferLen = std::strlen(newbuf);
892 String& urlDecode()
noexcept
897 char*
const newbuf =
static_cast<char*
>(std::malloc(fBufferLen + 1));
898 DAF_SAFE_ASSERT_RETURN(newbuf !=
nullptr, *
this);
900 char* newbufptr = newbuf;
902 for (
size_t i=0; i < fBufferLen; ++i)
904 const char c = fBuffer[i];
908 DAF_SAFE_ASSERT_CONTINUE(fBufferLen > i + 2);
910 char c1 = fBuffer[i + 1];
911 char c2 = fBuffer[i + 2];
914 if (c1 >=
'0' && c1 <=
'9')
916 else if (c1 >=
'A' && c1 <=
'Z')
918 else if (c1 >=
'a' && c1 <=
'z')
923 if (c2 >=
'0' && c2 <=
'9')
925 else if (c2 >=
'A' && c2 <=
'Z')
927 else if (c2 >=
'a' && c2 <=
'z')
932 *newbufptr++ = c1 << 4 | c2;
944 fBufferLen = std::strlen(newbuf);
953 operator const char*()
const noexcept
958 char operator[](
const size_t pos)
const noexcept
960 if (pos < fBufferLen)
963 d_safe_assert(
"pos < fBufferLen", __FILE__, __LINE__);
967 char& operator[](
const size_t pos)
noexcept
969 if (pos < fBufferLen)
972 d_safe_assert(
"pos < fBufferLen", __FILE__, __LINE__);
974 static char fallback;
979 bool operator==(
const char*
const strBuf)
const noexcept
981 return (strBuf !=
nullptr && std::strcmp(fBuffer, strBuf) == 0);
984 bool operator==(
const String& str)
const noexcept
986 return operator==(str.fBuffer);
989 bool operator!=(
const char*
const strBuf)
const noexcept
991 return !operator==(strBuf);
994 bool operator!=(
const String& str)
const noexcept
996 return !operator==(str.fBuffer);
999 String& operator=(
const char*
const strBuf)
noexcept
1006 String& operator=(
const String& str)
noexcept
1013 String& operator+=(
const char*
const strBuf)
noexcept
1015 if (strBuf ==
nullptr || strBuf[0] ==
'\0')
1018 const size_t strBufLen = std::strlen(strBuf);
1023 _dup(strBuf, strBufLen);
1028 char*
const newBuf =
static_cast<char*
>(std::realloc(fBufferAlloc ? fBuffer :
nullptr, fBufferLen + strBufLen + 1));
1029 DAF_SAFE_ASSERT_RETURN(newBuf !=
nullptr, *
this);
1031 std::memcpy(newBuf + fBufferLen, strBuf, strBufLen + 1);
1034 fBufferLen += strBufLen;
1035 fBufferAlloc =
true;
1040 String& operator+=(
const String& str)
noexcept
1042 return operator+=(str.fBuffer);
1045 String operator+(
const char*
const strBuf)
noexcept
1047 if (strBuf ==
nullptr || strBuf[0] ==
'\0')
1050 return String(strBuf);
1052 const size_t strBufLen = std::strlen(strBuf);
1053 const size_t newBufSize = fBufferLen + strBufLen;
1054 char*
const newBuf =
static_cast<char*
>(std::malloc(newBufSize + 1));
1055 DAF_SAFE_ASSERT_RETURN(newBuf !=
nullptr, String());
1057 std::memcpy(newBuf, fBuffer, fBufferLen);
1058 std::memcpy(newBuf + fBufferLen, strBuf, strBufLen + 1);
1060 return String(newBuf,
false);
1063 String operator+(
const String& str)
noexcept
1065 return operator+(str.fBuffer);
1069 bool operator<(
const String& str)
const noexcept
1071 return std::strcmp(fBuffer, str.fBuffer) < 0;
1085 static char* _null()
noexcept
1087 static char sNull =
'\0';
1099 void _dup(
const char*
const strBuf,
const size_t size = 0)
noexcept
1101 if (strBuf !=
nullptr)
1104 if (std::strcmp(fBuffer, strBuf) == 0)
1110 fBufferLen = (size > 0) ? size : std::strlen(strBuf);
1111 fBuffer =
static_cast<char*
>(std::malloc(fBufferLen + 1));
1113 if (fBuffer ==
nullptr)
1117 fBufferAlloc =
false;
1121 fBufferAlloc =
true;
1123 std::strcpy(fBuffer, strBuf);
1124 fBuffer[fBufferLen] =
'\0';
1128 DAF_SAFE_ASSERT_UINT(size == 0,
static_cast<uint
>(size));
1134 DAF_SAFE_ASSERT(fBuffer !=
nullptr);
1139 fBufferAlloc =
false;
1143 DAF_PREVENT_HEAP_ALLOCATION