25#ifdef __DCL_COMPILE_UNICODE__
27 #define CHAR_T wchar_t
28 #define UCHAR_T wint_t
29 #define BUFFER_T CharBuffer
30 #define STRING_T String
31 #define ARRAY_T StringArray
32 #define STRING_BUILDER_T StringBuilder
34 #define STRLEN(s) wcslen(s)
35 #define STRCMP(s1, s2) wcscmp(s1, s2)
36 #define STRNCMP(s1, s2, n) wcsncmp(s1, s2, n)
39 #define STRCASECMP(s1, s2) _wcsicmp(s1, s2)
40 #define STRNCASECMP(s1, s2, n) _wcsnicmp(s1, s2, n)
41 #define VSNPRINTF(buf, len, fmt, args) _vsnwprintf(buf, len, fmt, args)
43 #define STRCASECMP(s1, s2) wcscasecmp(s1, s2)
44 #define STRNCASECMP(s1, s2, n) wcsncasecmp(s1, s2, n)
45 #define VSNPRINTF(buf, len, fmt, args) vswprintf(buf, len, fmt, args)
48 #define STRCHR(s, c) wcschr(s, c)
49 #define STRSTR(s, cs) wcsstr(s, cs)
50 #define ISSPACE(c) iswspace(c)
51 #define ISALNUM(c) iswalnum(c)
52 #define TOUPPER(c) towupper(c)
53 #define TOLOWER(c) towlower(c)
54 #define TOUPPER_L(c, l) towupper(c, l)
55 #define TOLOWER_L(c, l) towlower(c, l)
59 #define UCHAR_T unsigned char
60 #define BUFFER_T ByteBuffer
61 #define STRING_T ByteString
62 #define ARRAY_T ByteStringArray
63 #define STRING_BUILDER_T ByteStringBuilder
65 #define STRLEN(s) strlen(s)
66 #define STRCMP(s1, s2) strcmp(s1, s2)
67 #define STRNCMP(s1, s2, n) strncmp(s1, s2, n)
70 #define STRCASECMP(s1, s2) _stricmp(s1, s2)
71 #define STRNCASECMP(s1, s2, n) _strnicmp(s1, s2, n)
72 #define VSNPRINTF(buf, len, fmt, args) _vsnprintf(buf, len, fmt, args)
74 #define STRCASECMP(s1, s2) strcasecmp(s1, s2)
75 #define STRNCASECMP(s1, s2, n) strncasecmp(s1, s2, n)
76 #define VSNPRINTF(buf, len, fmt, args) vsnprintf(buf, len, fmt, args)
79 #define STRCHR(s, c) strchr(s, c)
80 #define STRSTR(s, cs) strstr(s, cs)
81 #define ISSPACE(c) isspace(c)
82 #define ISALNUM(c) isalnum(c)
83 #define TOUPPER(c) toupper(c)
84 #define TOLOWER(c) tolower(c)
85 #define TOUPPER_L(c, l) toupper_l(c, l)
86 #define TOLOWER_L(c, l) tolower_l(c, l)
89#if __DCL_HAVE_THIS_FILE__
93 #define __THIS_FILE__ __CONCAT(__sz_STRING_T_cpp, CHAR_T)
111#ifndef __EXTENDED_LENGTH_DEFINED
112#define __EXTENDED_LENGTH_DEFINED
115 if (_allocLength <= 32)
117 else if (_allocLength <= 64)
119 else if (_allocLength <= 128)
121 else if (_allocLength <= 256)
123 else if (_allocLength <= 512)
125 else if (_allocLength <= 1024)
128 size_t m = _allocLength / 2048;
129 if (_allocLength % 2048)
131 _allocLength = m * 2048;
137#if defined(__GNUC__) && !defined(__clang__)
138#pragma GCC diagnostic push
139#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
145#if defined(__GNUC__) && !defined(__clang__)
146#pragma GCC diagnostic pop
227 write(_buf, &_ch, 1);
234#if defined(__DCL_COMPILE_UNICODE__) && defined(_MSC_VER)
236 if (
STRSTR(_format, L
"%s")) {
237 __DCL_TRACE3(L
"Warning!! vformat _format [%ls] included [%ls]. replaced to [%ls]\n",
238 _format, L
"%s", L
"%hs");
239 format.assign(_format);
240 format = format.replace(L
"%s", L
"%hs");
245#define __EXTENDED_MAX 1024 * 1024
246#define __EXTEND_MIN 32
256 va_copy(arglist, _arglist);
296#define __EMPTY_STR __CONCAT(__empty, CHAR_T)
301#define __EMPTY __EMPTY_STR()
310 buf = BUFFER_T::create(_len);
315 buf = BUFFER_T::create(_len);
359 assign(_psz, _start, _len);
411 CHAR_T* _end = p + _repeat;
415 __buf()->__dataLength = _repeat;
430 memcpy(
__psz, _ps + _start, _len *
sizeof(
CHAR_T));
432 __buf()->__dataLength = _len;
443 if (_len == (
size_t)-1)
445 return assign(_psz, 0, _len);
451 return assign(_begin, 0, _end - _begin);
455 const CHAR_T* _ps1,
size_t _len1,
456 const CHAR_T* _ps2,
size_t _len2
461 size_t _len = _len1 + _len2;
466 memcpy(
__psz + _len1, _ps2, _len2 *
sizeof(
CHAR_T));
468 __buf()->__dataLength = _len;
493 r.assign(_str, _str.
length(), &_ch, 1);
500 r.assign(&_ch, 1, _str, _str.
length());
593 const CHAR_T* psz2,
size_t _len
598 if (_len == (
size_t)-1)
599 return STRCMP(psz1, psz2);
601 return STRNCMP(psz1, psz2, _len);
606 const CHAR_T* psz2,
size_t _len
611 if (_len == (
size_t)-1)
618 size_t _first,
size_t _len
623 if (_len == (
size_t)-1)
628 if (_first == 0 && _len ==
length())
652 BUFFER_T* buf = BUFFER_T::create(_len);
667 end = buf->
data() + _len;
685 BUFFER_T* buf = BUFFER_T::create(_len);
694 end = buf->
data() + _len;
714 BUFFER_T* buf = BUFFER_T::create(_len);
724 end = buf->
data() + _len;
737 size_t _start,
size_t _len,
738 const CHAR_T* _new,
size_t _newlen
744 if (_newlen == (
size_t)-1)
747 size_t len =
length() - _len + _newlen;
748 BUFFER_T* buf = BUFFER_T::create(len);
751 *(p + len) =
_T(
'\0');
754 memcpy(p + _start, _new, _newlen *
sizeof(
CHAR_T));
755 memcpy(p + _start + _newlen,
__psz + _start + _len,
766 size_t _start,
size_t _len,
767 const CHAR_T* _new,
size_t _newlen
772 return replace(
length() - _start - _len, _len, _new, _newlen);
790 *dst++ = *src == _old ? _new : *src;
801 const CHAR_T* _old,
size_t _oldlen,
802 const CHAR_T* _new,
size_t _newlen
817 _start = _sub + _oldlen;
824 size_t allocLength =
length() + (count * _newlen) - (count * _oldlen);
825 BUFFER_T* buf = BUFFER_T::create(allocLength);
828 *(dst + allocLength) =
_T(
'\0');
832 _len = _sub - _start;
833 memcpy(dst, _start, _len *
sizeof(
CHAR_T));
835 memcpy(dst, _new, _newlen *
sizeof(
CHAR_T));
838 _start = _sub + _oldlen;
840 _len = _end - _start;
841 memcpy(dst, _start, _len *
sizeof(
CHAR_T));
872 _regex.__psz, _regex.__psz + _regex.length(),
897 _regex.__psz, _regex.__psz + _regex.length(),
922 _regex.__psz, _regex.__psz + _regex.length(),
947 _regex.__psz, _regex.__psz + _regex.length(),
955 const CHAR_T* _replacment,
979 _regex.__psz, _regex.__psz + _regex.length(),
981 _replacement.__psz, _replacement.__psz + _replacement.length(),
1012 _regex.__psz, _regex.__psz + _regex.length(),
1026 while (src < _end) {
1045 while (src < _end) {
1058#ifdef __DCL_INCLUDED_LOCALE_H
1059STRING_T STRING_T::toUpperCase(locale_t _locale)
const
1061 BUFFER_T* buf = BUFFER_T::create(length());
1063 const CHAR_T* src = __psz;
1064 const CHAR_T* _end = __psz + length();
1065 while (src < _end) {
1084 while (src < _end) {
1098#ifdef __DCL_COMPILE_UNICODE__
1106 return String::toHexString(*
this, 20);
1115 while(first < last) {
1121 while(first < last) {
1130 size_t len = last - first;
1132 BUFFER_T* buf = BUFFER_T::create(len);
1135 *(p + len) =
_T(
'\0');
1136 memcpy(p, first, len *
sizeof(
CHAR_T));
1151 while (first < last) {
1157 if (
__psz < first) {
1158 size_t len = last - first;
1160 BUFFER_T* buf = BUFFER_T::create(len);
1163 *(p + len) =
_T(
'\0');
1164 memcpy(p, first, len *
sizeof(
CHAR_T));
1179 while(first < last) {
1186 size_t len = last - first;
1188 BUFFER_T* buf = BUFFER_T::create(len);
1191 *(p + len) =
_T(
'\0');
1192 memcpy(p, first, len *
sizeof(
CHAR_T));
1207 while (first < last) {
1213 while (first < last) {
1222 size_t len = last - first;
1224 BUFFER_T* buf = BUFFER_T::create(len);
1227 *(p + len) =
_T(
'\0');
1228 memcpy(p, first, len *
sizeof(
CHAR_T));
1244 while (first < last) {
1250 if (
__psz < first) {
1251 size_t len = last - first;
1254 BUFFER_T* buf = BUFFER_T::create(len);
1257 *(p + len) =
_T(
'\0');
1258 memcpy(p, first, len *
sizeof(
CHAR_T));
1273 while (first < last) {
1280 size_t len = last - first;
1282 BUFFER_T* buf = BUFFER_T::create(len);
1285 *(p + len) =
_T(
'\0');
1286 memcpy(p, first, len *
sizeof(
CHAR_T));
1301 return __psz[_index];
1312 while (*_psz++ &&
r < _max) {
1321 BUFFER_T* buf = BUFFER_T::create_e(len);
1324 va_start(arglist, _format);
1325 int __UNUSED__ n = BUFFER_T::vformat(buf, _format, arglist);
1337#ifndef __A_HEX_DEFINED
1338#define __A_HEX_DEFINED
1339static const CHAR_T __hex__[] =
_T(
"0123456789abcdef");
1342#define ASCII_32 _T(' ')
1343#define ASCII_126 _T('~')
1348 if (_flag == STRING_T::ESCAPE_DEFAULT) {
1350 || c ==
_T(
'\"') || c ==
_T(
'\'') || c ==
_T(
'\\'));
1352 else if (_flag == STRING_T::ESCAPE_EXTENDED) {
1377 BUFFER_T* buf = BUFFER_T::create(_len * 4);
1379 const UCHAR_T* _end = src + _len;
1382 for( ; src < _end; src++) {
1385 case _T(
'&') : BUFFER_T::write(buf,
_T(
"&"), 5);
break;
1386 case _T(
'<') : BUFFER_T::write(buf,
_T(
"<"), 4);
break;
1387 case _T(
'>') : BUFFER_T::write(buf,
_T(
">"), 4);
break;
1388 case _T(
'\"') : BUFFER_T::write(buf,
_T(
"""), 6);
break;
1389 case _T(
'\'') : BUFFER_T::write(buf,
_T(
"'"), 5);
break;
1391 BUFFER_T::write(buf, c);
1397 for ( ; src < _end; src++) {
1398 unsigned int c = *src;
1400 BUFFER_T::write(buf,
_T(
'\\'));
1402 case _T(
'\0') : BUFFER_T::write(buf,
_T(
'0'));
break;
1403 case _T(
'\a') : BUFFER_T::write(buf,
_T(
'a'));
break;
1404 case _T(
'\b') : BUFFER_T::write(buf,
_T(
'b'));
break;
1405 case _T(
'\t') : BUFFER_T::write(buf,
_T(
't'));
break;
1406 case _T(
'\n') : BUFFER_T::write(buf,
_T(
'n'));
break;
1407 case _T(
'\v') : BUFFER_T::write(buf,
_T(
'v'));
break;
1408 case _T(
'\f') : BUFFER_T::write(buf,
_T(
'f'));
break;
1409 case _T(
'\r') : BUFFER_T::write(buf,
_T(
'r'));
break;
1413 BUFFER_T::write(buf, c);
1417 BUFFER_T::write(buf,
_T(
'x'));
1418 BUFFER_T::write(buf, __hex__[c >> 4]);
1419 BUFFER_T::write(buf, __hex__[c & 0x0f]);
1421 else if (c <= 0xffff) {
1423 BUFFER_T::write(buf,
_T(
'u'));
1433 for(
int i = 0; i < 4; i++)
1434 BUFFER_T::write(buf, __hex__[a[i]]);
1437 BUFFER_T::write(buf, c);
1442 BUFFER_T::write(buf, c);
1446 BUFFER_T::shrink(buf);
1453static int __hex2int(
CHAR_T _c)
1455 if (
_T(
'0') <= _c && _c <=
_T(
'9'))
1456 return _c -
_T(
'0');
1457 else if (
_T(
'A') <= _c && _c <=
_T(
'F'))
1458 return _c -
_T(
'A') + 10;
1459 else if (
_T(
'a') <= _c && _c <=
_T(
'f'))
1460 return _c -
_T(
'a') + 10;
1472 if (_len == (
size_t)-1)
1478 BUFFER_T* buf = BUFFER_T::create(_len);
1480 const CHAR_T* end = src + _len;
1482 for ( ; src < end; src++) {
1483 if (*src ==
_T(
'\\') && (src + 1) < end) {
1485 case _T(
'0') : BUFFER_T::write(buf,
_T(
'\0'));
break;
1486 case _T(
'a') : BUFFER_T::write(buf,
_T(
'\a'));
break;
1487 case _T(
'b') : BUFFER_T::write(buf,
_T(
'\b'));
break;
1488 case _T(
't') : BUFFER_T::write(buf,
_T(
'\t'));
break;
1489 case _T(
'n') : BUFFER_T::write(buf,
_T(
'\n'));
break;
1490 case _T(
'v') : BUFFER_T::write(buf,
_T(
'\v'));
break;
1491 case _T(
'f') : BUFFER_T::write(buf,
_T(
'\f'));
break;
1492 case _T(
'r') : BUFFER_T::write(buf,
_T(
'\r'));
break;
1497 BUFFER_T::write(buf, *src);
1501 if ((src + 2) < end) {
1502 int high = __hex2int(src[1]);
1503 int low = __hex2int(src[2]);
1504 if (high >= 0 && low >= 0)
1506 BUFFER_T::write(buf, (high << 4) | low);
1514 if ((src + 4) < end) {
1517#ifdef __DCL_COMPILE_UNICODE__
1518 for (
int i = 1; i <= 4; i++) {
1519 if ((n = __hex2int(src[i])) < 0)
1524 for (
int i = 1; i <= 4; i++) {
1525 if ((n = __hex2int(src[i])) < 0)
1529 BUFFER_T::write(buf, c);
1534 BUFFER_T::write(buf, c);
1540 BUFFER_T::write(buf,
_T(
'\\'));
1541 BUFFER_T::write(buf, *src);
1546 BUFFER_T::write(buf, *src);
1549 BUFFER_T::shrink(buf);
1565 size_t len =
__MIN(_len, _max);
1573 size_t dstlen = len * 2 + 5;
1575 BUFFER_T* buf = BUFFER_T::create(dstlen);
1583 const byte_t* end = src + len;
1586 *dst++ = __hex__[*src >> 4];
1587 *dst++ = __hex__[*src & 0x0f];
1618 size_t len =
__MIN(_len, _max);
1624 size_t dstlen = len * 4 + 3;
1626 BUFFER_T* buf = BUFFER_T::create(dstlen);
1629 const byte_t* end = src + len;
1632 if (isprint(*src)) {
1638 *dst++ = __hex__[*src >> 4];
1639 *dst++ = __hex__[*src & 0x0f];
1668 while (_begin < _end) {
1684 while (_begin <= --_end) {
1701 const CHAR_T* subbegin = _sub;
1702 const CHAR_T* subend = _sub + _sublen;
1704 if (_begin == _end) {
1705 if (subbegin == subend)
1711 while (_begin < _end) {
1712 if (c == *_begin++) {
1714 const CHAR_T* s = _begin;
1715 const CHAR_T* _sub = subbegin;
1716 while (s < _end && _sub < subend && *s == *_sub)
1721 return (
CHAR_T*)--_begin;
1739 const CHAR_T* subbegin = _sub;
1740 const CHAR_T* subend = _sub + _sublen;
1742 if (_begin == _end) {
1743 if (subbegin == subend)
1750 while (_begin <= _end) {
1753 const CHAR_T* s = _end; s++;
1754 const CHAR_T* _sub = subbegin;
1755 while (_sub < subend && *s == *_sub)
1769 const CHAR_T* _delimiter,
1770 size_t _delimiterlen,
1776 while (_begin < _end && count < _limit) {
1780 _begin = s + _delimiterlen;
1787 if ((count < _limit) && ((_begin < _end) || (count == 0 && _begin == _end))) {
1804 while (_begin < _end && count < _limit) {
1815 if ((count < _limit) && ((_begin < _end) || (count == 0 && _begin == _end))) {
1830 ARRAY_T::ConstIterator it = _array.
begin();
1831 if (it != _array.
end()) {
1835 if (++it == _array.
end()) {
1855 return _b ?
_T(
"true") :
_T(
"false");
1860#ifdef __DCL_COMPILE_UNICODE__
1869#ifdef __DCL_COMPILE_UNICODE__
1878#ifdef __DCL_COMPILE_UNICODE__
1887#ifdef __DCL_COMPILE_UNICODE__
1896#ifdef __DCL_COMPILE_UNICODE__
1905#ifdef __DCL_COMPILE_UNICODE__
1915#ifdef __DCL_COMPILE_UNICODE__
1921#ifdef __DCL_COMPILE_UNICODE__
1932#ifdef __DCL_COMPILE_UNICODE__
1938#ifdef __DCL_COMPILE_UNICODE__
1948#ifdef __DCL_COMPILE_UNICODE__
1957#ifdef __DCL_COMPILE_UNICODE__
1966#ifdef __DCL_COMPILE_UNICODE__
1967 return String::format(L
"%.8g", _n);
1969 return ByteString::format(
"%.8g", _n);
1975#ifdef __DCL_COMPILE_UNICODE__
1976 return String::format(L
"%.16g", _n);
1978 return ByteString::format(
"%.16g", _n);
1984#ifdef __DCL_COMPILE_UNICODE__
1985 return String::format(L
"%.32Lg", _n);
1987 return ByteString::format(
"%.32Lg", _n);
1991#if __DCL_HAVE_THIS_FILE__
1992 #undef __THIS_FILE__
#define STRCASECMP(s1, s2)
size_t __extended_length(size_t _allocLength)
#define STRNCMP(s1, s2, n)
#define VSNPRINTF(buf, len, fmt, args)
bool __escapeable(unsigned int c, STRING_T::EscapeFlags _flag)
DCLCAPI STRING_T operator+(const STRING_T &_str1, const STRING_T &_str2)
#define STRNCASECMP(s1, s2, n)
StringArray & __regex_split(const wchar_t *_regex, const wchar_t *_regexend, const wchar_t *_begin, const wchar_t *_end, bool _icase, StringArray &_results, size_t _limit=(size_t) -1) __DCL_THROWS1(RegexException *)
bool __regex_search(regex_handle _handle, const wchar_t *_begin, const wchar_t *_end, match_result **_results, unsigned int _flags)
String __regex_substring(const wchar_t *_regex, const wchar_t *_regexend, const wchar_t *_begin, const wchar_t *_end, bool _icase) __DCL_THROWS1(RegexException *)
bool __regex_matches(const wchar_t *_regex, const wchar_t *_regexend, const wchar_t *_begin, const wchar_t *_end, bool _icase) __DCL_THROWS1(RegexException *)
String __regex_replace(const wchar_t *_regex, const wchar_t *_regexend, const wchar_t *_begin, const wchar_t *_end, const wchar_t *_replacement, const wchar_t *_replacementend, bool _icase, size_t _limit=(size_t) -1) __DCL_THROWS1(RegexException *)
#define __DCL_ASSERT_PARAM(expr)
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
#define __CONCAT_TEXT(str, expr)
#define __DCL_ASSERT(expr)
#define __DCL_TRACE2(fmt, arg1, arg2)
ARRAY_T & add(CONST_ELEMENT_REF _element)
ConstIterator end() const
ConstIterator begin() const
static ByteString toByteString(int32_t _n, unsigned _base=10)
String toString(unsigned _base=10) const
static ByteString toByteString(int64_t _n, unsigned _base=10)
String toString(unsigned _base=10) const
int compare(const CHAR_T *_psz, size_t _len=(size_t) -1) const
STRING_T padCenter(size_t _len, CHAR_T _ch) const
STRING_T toUpperCase() const
static STRING_T escape(const CHAR_T *_ps, size_t _len, EscapeFlags _flag=ESCAPE_DEFAULT)
static size_t split(const CHAR_T *_begin, const CHAR_T *_end, const CHAR_T *_delimiter, size_t _delimiterlen, ARRAY_T &_results, size_t _limit=(size_t) -1)
const CHAR_T * data() const
static STRING_T toHexString(const char *_bytes, size_t _len, size_t _max=(size_t) -1, bool _prefix=true)
size_t lastIndexOf(CHAR_T _ch, size_t _start=0) const
static STRING_T tryString(const char *_bytes, size_t _len, size_t _max=(size_t) -1)
static CHAR_T * rfind(const CHAR_T *_begin, const CHAR_T *_end, CHAR_T _ch)
static STRING_T join(const ARRAY_T &_array, CHAR_T _delimiter, bool _hasEmpty=false)
STRING_T mid(size_t _first, size_t _len=(size_t) -1) const
STRING_T trimLeft() const
ARRAY_T & split_r(const CHAR_T *_regex, bool _icase, ARRAY_T &_results, size_t _limit=(size_t) -1) const __DCL_THROWS1(RegexException *)
STRING_T trimRight() const
STRING_T padRight(size_t _len, CHAR_T _ch) const
friend class STRING_BUILDER_T
STRING_T padLeft(size_t _len, CHAR_T _ch) const
STRING_T replace(size_t _start, size_t _len, const CHAR_T *_new, size_t _newlen=(size_t) -1) const
bool matches(const CHAR_T *_regex, bool _icase) const __DCL_THROWS1(RegexException *)
void assignAlloc(size_t _len)
static STRING_T format(const CHAR_T *_format,...)
static CHAR_T * find(const CHAR_T *_begin, const CHAR_T *_end, CHAR_T _ch)
STRING_T left(size_t _len) const
static STRING_T unescape(const CHAR_T *_psz, size_t _len)
STRING_T replace_r(const CHAR_T *_regex, const CHAR_T *_replacment, bool _icase, size_t _limit=(size_t) -1) const __DCL_THROWS1(RegexException *)
CHAR_T operator[](size_t _index) const
int compareNoCase(const CHAR_T *_psz, size_t _len=(size_t) -1) const
size_t indexOf(CHAR_T _ch, size_t _start=0) const
STRING_T right(size_t _len) const
bool searches(const CHAR_T *_regex, bool _icase) const __DCL_THROWS1(RegexException *)
size_t search(const CHAR_T *_regex, bool _icase) const __DCL_THROWS1(RegexException *)
STRING_T toLowerCase() const
static STRING_T valueOf(bool _b)
STRING_T & assign(const STRING_T &_str)
STRING_T substring(size_t _first) const
STRING_T rreplace(size_t _start, size_t _len, const CHAR_T *_new, size_t _newlen=(size_t) -1) const
static long incrementAndGet(volatile long &_n)
static long decrementAndGet(volatile long &_n)
static ByteString toByteString(uint32_t _u, unsigned _base=10)
String toString(unsigned _base=10) const
static ByteString toByteString(uint64_t _u, unsigned _base=10)
String toString(unsigned _base=10) const
size_t __MAX(size_t x, size_t y)
size_t __MIN(size_t x, size_t y)
static void destroy(BUFFER_T *_buf)
static BUFFER_T * create(size_t _len)
static void extend(BUFFER_T *&_buf, size_t _len)
static BUFFER_T * create_e(size_t _len)
static void write(BUFFER_T *&_buf, const CHAR_T *_str, size_t _len)
static void shrink(BUFFER_T *&_buf)
static int vformat(BUFFER_T *&_buf, const CHAR_T *_format, va_list _arglist)