27
27
* terms and conditions of either the GPL or the CDDL or both.
31
/*******************************************************************************
33
*******************************************************************************/
30
34
#include <iprt/cpp/ministring.h>
32
35
using namespace iprt;
38
/*******************************************************************************
40
*******************************************************************************/
34
41
const size_t MiniString::npos = ~(size_t)0;
43
/*******************************************************************************
44
* Defined Constants And Macros *
45
*******************************************************************************/
46
/** Allocation block alignment used when appending bytes to a string. */
47
#define IPRT_MINISTRING_APPEND_ALIGNMENT 64
50
MiniString &MiniString::printf(const char *pszFormat, ...)
53
va_start(va, pszFormat);
54
printfV(pszFormat, va);
60
* Callback used with RTStrFormatV by MiniString::printfV.
62
* @returns The number of bytes added (not used).
64
* @param pvArg The string object.
65
* @param pachChars The characters to append.
66
* @param cbChars The number of characters. 0 on the final callback.
68
/*static*/ DECLCALLBACK(size_t)
69
MiniString::printfOutputCallback(void *pvArg, const char *pachChars, size_t cbChars)
71
MiniString *pThis = (MiniString *)pvArg;
74
size_t cchBoth = pThis->m_cch + cbChars;
75
if (cchBoth >= pThis->m_cbAllocated)
77
/* Double the buffer size, if it's less that _4M. Align sizes like
79
size_t cbAlloc = RT_ALIGN_Z(pThis->m_cbAllocated, IPRT_MINISTRING_APPEND_ALIGNMENT);
80
cbAlloc += RT_MIN(cbAlloc, _4M);
81
if (cbAlloc <= cchBoth)
82
cbAlloc = RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT);
83
pThis->reserve(cbAlloc);
84
#ifndef RT_EXCEPTIONS_ENABLED
85
AssertReleaseReturn(pThis->capacity() > cchBoth, 0);
89
memcpy(&pThis->m_psz[pThis->m_cch], pachChars, cbChars);
90
pThis->m_cch = cchBoth;
91
pThis->m_psz[cchBoth] = '\0';
96
MiniString &MiniString::printfV(const char *pszFormat, va_list va)
99
RTStrFormatV(printfOutputCallback, this, NULL, NULL, pszFormat, va);
36
103
MiniString &MiniString::append(const MiniString &that)
38
size_t lenThat = that.length();
41
size_t lenThis = length();
42
size_t cbBoth = lenThis + lenThat + 1;
45
// calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
46
#ifndef RT_EXCEPTIONS_ENABLED
47
AssertRelease(capacity() >= cbBoth);
50
memcpy(m_psz + lenThis, that.m_psz, lenThat);
51
m_psz[lenThis + lenThat] = '\0';
52
m_cbLength = cbBoth - 1;
57
MiniString& MiniString::append(char c)
105
size_t cchThat = that.length();
108
size_t cchThis = length();
109
size_t cchBoth = cchThis + cchThat;
111
if (cchBoth >= m_cbAllocated)
113
reserve(RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
114
// calls realloc(cchBoth + 1) and sets m_cbAllocated; may throw bad_alloc.
115
#ifndef RT_EXCEPTIONS_ENABLED
116
AssertRelease(capacity() > cchBoth);
120
memcpy(m_psz + cchThis, that.m_psz, cchThat);
121
m_psz[cchBoth] = '\0';
127
MiniString &MiniString::append(const char *pszThat)
129
size_t cchThat = strlen(pszThat);
132
size_t cchThis = length();
133
size_t cchBoth = cchThis + cchThat;
135
if (cchBoth >= m_cbAllocated)
137
reserve(RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
138
// calls realloc(cchBoth + 1) and sets m_cbAllocated; may throw bad_alloc.
139
#ifndef RT_EXCEPTIONS_ENABLED
140
AssertRelease(capacity() > cchBoth);
144
memcpy(&m_psz[cchThis], pszThat, cchThat);
145
m_psz[cchBoth] = '\0';
151
MiniString& MiniString::append(char ch)
153
Assert((unsigned char)ch < 0x80); /* Don't create invalid UTF-8. */
61
156
// allocate in chunks of 20 in case this gets called several times
62
if (m_cbLength + 1 >= m_cbAllocated)
157
if (m_cch + 1 >= m_cbAllocated)
64
reserve(m_cbLength + 10);
159
reserve(RT_ALIGN_Z(m_cch + 2, IPRT_MINISTRING_APPEND_ALIGNMENT));
65
160
// calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
66
161
#ifndef RT_EXCEPTIONS_ENABLED
67
AssertRelease(capacity() >= m_cbLength + 1);
162
AssertRelease(capacity() > m_cch + 1);
71
m_psz[m_cbLength] = c;
72
m_psz[m_cbLength + 1] = '\0';
167
m_psz[++m_cch] = '\0';
172
MiniString &MiniString::appendCodePoint(RTUNICP uc)
175
* Single byte encoding.
178
return MiniString::append((char)uc);
181
* Multibyte encoding.
182
* Assume max encoding length when resizing the string, that's simpler.
184
AssertReturn(uc <= UINT32_C(0x7fffffff), *this);
186
if (m_cch + 6 >= m_cbAllocated)
188
reserve(RT_ALIGN_Z(m_cch + 6 + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
189
// calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
190
#ifndef RT_EXCEPTIONS_ENABLED
191
AssertRelease(capacity() > m_cch + 6);
195
char *pszNext = RTStrPutCp(&m_psz[m_cch], uc);
196
m_cch = pszNext - m_psz;