VirtualBox

source: vbox/trunk/include/iprt/cpp/ministring.h@ 78286

Last change on this file since 78286 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.9 KB
Line 
1/** @file
2 * IPRT - C++ string class.
3 */
4
5/*
6 * Copyright (C) 2007-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_cpp_ministring_h
27#define IPRT_INCLUDED_cpp_ministring_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/mem.h>
33#include <iprt/string.h>
34#include <iprt/stdarg.h>
35#include <iprt/cpp/list.h>
36
37#include <new>
38
39
40/** @defgroup grp_rt_cpp_string C++ String support
41 * @ingroup grp_rt_cpp
42 * @{
43 */
44
45/** @brief C++ string class.
46 *
47 * This is a C++ string class that does not depend on anything else except IPRT
48 * memory management functions. Semantics are like in std::string, except it
49 * can do a lot less.
50 *
51 * Note that RTCString does not differentiate between NULL strings
52 * and empty strings. In other words, RTCString("") and RTCString(NULL)
53 * behave the same. In both cases, RTCString allocates no memory, reports
54 * a zero length and zero allocated bytes for both, and returns an empty
55 * C-style string from c_str().
56 *
57 * @note RTCString ASSUMES that all strings it deals with are valid UTF-8.
58 * The caller is responsible for not breaking this assumption.
59 */
60#ifdef VBOX
61 /** @remarks Much of the code in here used to be in com::Utf8Str so that
62 * com::Utf8Str can now derive from RTCString and only contain code
63 * that is COM-specific, such as com::Bstr conversions. Compared to
64 * the old Utf8Str though, RTCString always knows the length of its
65 * member string and the size of the buffer so it can use memcpy()
66 * instead of strdup().
67 */
68#endif
69class RT_DECL_CLASS RTCString
70{
71public:
72 /**
73 * Creates an empty string that has no memory allocated.
74 */
75 RTCString()
76 : m_psz(NULL),
77 m_cch(0),
78 m_cbAllocated(0)
79 {
80 }
81
82 /**
83 * Creates a copy of another RTCString.
84 *
85 * This allocates s.length() + 1 bytes for the new instance, unless s is empty.
86 *
87 * @param a_rSrc The source string.
88 *
89 * @throws std::bad_alloc
90 */
91 RTCString(const RTCString &a_rSrc)
92 {
93 copyFromN(a_rSrc.m_psz, a_rSrc.m_cch);
94 }
95
96 /**
97 * Creates a copy of a C-style string.
98 *
99 * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
100 *
101 * @param pcsz The source string.
102 *
103 * @throws std::bad_alloc
104 */
105 RTCString(const char *pcsz)
106 {
107 copyFromN(pcsz, pcsz ? strlen(pcsz) : 0);
108 }
109
110 /**
111 * Create a partial copy of another RTCString.
112 *
113 * @param a_rSrc The source string.
114 * @param a_offSrc The byte offset into the source string.
115 * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
116 * to copy from the source string.
117 */
118 RTCString(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos)
119 {
120 if (a_offSrc < a_rSrc.m_cch)
121 copyFromN(&a_rSrc.m_psz[a_offSrc], RT_MIN(a_cchSrc, a_rSrc.m_cch - a_offSrc));
122 else
123 {
124 m_psz = NULL;
125 m_cch = 0;
126 m_cbAllocated = 0;
127 }
128 }
129
130 /**
131 * Create a partial copy of a C-style string.
132 *
133 * @param a_pszSrc The source string (UTF-8).
134 * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
135 * to copy from the source string. This must not
136 * be '0' as the compiler could easily mistake
137 * that for the va_list constructor.
138 */
139 RTCString(const char *a_pszSrc, size_t a_cchSrc)
140 {
141 size_t cchMax = a_pszSrc ? RTStrNLen(a_pszSrc, a_cchSrc) : 0;
142 copyFromN(a_pszSrc, RT_MIN(a_cchSrc, cchMax));
143 }
144
145 /**
146 * Create a string containing @a a_cTimes repetitions of the character @a
147 * a_ch.
148 *
149 * @param a_cTimes The number of times the character is repeated.
150 * @param a_ch The character to fill the string with.
151 */
152 RTCString(size_t a_cTimes, char a_ch)
153 : m_psz(NULL),
154 m_cch(0),
155 m_cbAllocated(0)
156 {
157 Assert((unsigned)a_ch < 0x80);
158 if (a_cTimes)
159 {
160 reserve(a_cTimes + 1);
161 memset(m_psz, a_ch, a_cTimes);
162 m_psz[a_cTimes] = '\0';
163 m_cch = a_cTimes;
164 }
165 }
166
167 /**
168 * Create a new string given the format string and its arguments.
169 *
170 * @param a_pszFormat Pointer to the format string (UTF-8),
171 * @see pg_rt_str_format.
172 * @param a_va Argument vector containing the arguments
173 * specified by the format string.
174 * @sa printfV
175 * @remarks Not part of std::string.
176 */
177 RTCString(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
178 : m_psz(NULL),
179 m_cch(0),
180 m_cbAllocated(0)
181 {
182 printfV(a_pszFormat, a_va);
183 }
184
185 /**
186 * Destructor.
187 */
188 virtual ~RTCString()
189 {
190 cleanup();
191 }
192
193 /**
194 * String length in bytes.
195 *
196 * Returns the length of the member string in bytes, which is equal to strlen(c_str()).
197 * In other words, this does not count unicode codepoints; use utf8length() for that.
198 * The byte length is always cached so calling this is cheap and requires no
199 * strlen() invocation.
200 *
201 * @returns m_cbLength.
202 */
203 size_t length() const
204 {
205 return m_cch;
206 }
207
208 /**
209 * String length in unicode codepoints.
210 *
211 * As opposed to length(), which returns the length in bytes, this counts
212 * the number of unicode codepoints. This is *not* cached so calling this
213 * is expensive.
214 *
215 * @returns Number of codepoints in the member string.
216 */
217 size_t uniLength() const
218 {
219 return m_psz ? RTStrUniLen(m_psz) : 0;
220 }
221
222 /**
223 * The allocated buffer size (in bytes).
224 *
225 * Returns the number of bytes allocated in the internal string buffer, which is
226 * at least length() + 1 if length() > 0; for an empty string, this returns 0.
227 *
228 * @returns m_cbAllocated.
229 */
230 size_t capacity() const
231 {
232 return m_cbAllocated;
233 }
234
235 /**
236 * Make sure at that least cb of buffer space is reserved.
237 *
238 * Requests that the contained memory buffer have at least cb bytes allocated.
239 * This may expand or shrink the string's storage, but will never truncate the
240 * contained string. In other words, cb will be ignored if it's smaller than
241 * length() + 1.
242 *
243 * @param cb New minimum size (in bytes) of member memory buffer.
244 *
245 * @throws std::bad_alloc On allocation error. The object is left unchanged.
246 */
247 void reserve(size_t cb)
248 {
249 if ( ( cb != m_cbAllocated
250 && cb > m_cch + 1)
251 || ( m_psz == NULL
252 && cb > 0))
253 {
254 int rc = RTStrRealloc(&m_psz, cb);
255 if (RT_SUCCESS(rc))
256 m_cbAllocated = cb;
257#ifdef RT_EXCEPTIONS_ENABLED
258 else
259 throw std::bad_alloc();
260#endif
261 }
262 }
263
264 /**
265 * A C like version of the reserve method, i.e. return code instead of throw.
266 *
267 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
268 * @param cb New minimum size (in bytes) of member memory buffer.
269 */
270 int reserveNoThrow(size_t cb) RT_NOEXCEPT
271 {
272 if ( ( cb != m_cbAllocated
273 && cb > m_cch + 1)
274 || ( m_psz == NULL
275 && cb > 0))
276 {
277 int rc = RTStrRealloc(&m_psz, cb);
278 if (RT_SUCCESS(rc))
279 m_cbAllocated = cb;
280 else
281 return rc;
282 }
283 return VINF_SUCCESS;
284 }
285
286 /**
287 * Deallocates all memory.
288 */
289 inline void setNull()
290 {
291 cleanup();
292 }
293
294 RTMEMEF_NEW_AND_DELETE_OPERATORS();
295
296 /**
297 * Assigns a copy of pcsz to @a this.
298 *
299 * @param pcsz The source string.
300 *
301 * @throws std::bad_alloc On allocation failure. The object is left describing
302 * a NULL string.
303 *
304 * @returns Reference to the object.
305 */
306 RTCString &operator=(const char *pcsz)
307 {
308 if (m_psz != pcsz)
309 {
310 cleanup();
311 copyFromN(pcsz, pcsz ? strlen(pcsz) : 0);
312 }
313 return *this;
314 }
315
316 /**
317 * Assigns a copy of s to @a this.
318 *
319 * @param s The source string.
320 *
321 * @throws std::bad_alloc On allocation failure. The object is left describing
322 * a NULL string.
323 *
324 * @returns Reference to the object.
325 */
326 RTCString &operator=(const RTCString &s)
327 {
328 if (this != &s)
329 {
330 cleanup();
331 copyFromN(s.m_psz, s.m_cch);
332 }
333 return *this;
334 }
335
336 /**
337 * Assigns a copy of another RTCString.
338 *
339 * @param a_rSrc Reference to the source string.
340 * @throws std::bad_alloc On allocation error. The object is left unchanged.
341 */
342 RTCString &assign(const RTCString &a_rSrc);
343
344 /**
345 * Assigns a copy of another RTCString.
346 *
347 * @param a_rSrc Reference to the source string.
348 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
349 */
350 int assignNoThrow(const RTCString &a_rSrc) RT_NOEXCEPT;
351
352 /**
353 * Assigns a copy of a C-style string.
354 *
355 * @param a_pszSrc Pointer to the C-style source string.
356 * @throws std::bad_alloc On allocation error. The object is left unchanged.
357 * @remarks ASSUMES valid
358 */
359 RTCString &assign(const char *a_pszSrc);
360
361 /**
362 * Assigns a copy of a C-style string.
363 *
364 * @param a_pszSrc Pointer to the C-style source string.
365 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
366 * @remarks ASSUMES valid
367 */
368 int assignNoThrow(const char *a_pszSrc) RT_NOEXCEPT;
369
370 /**
371 * Assigns a partial copy of another RTCString.
372 *
373 * @param a_rSrc The source string.
374 * @param a_offSrc The byte offset into the source string.
375 * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
376 * to copy from the source string.
377 * @throws std::bad_alloc On allocation error. The object is left unchanged.
378 */
379 RTCString &assign(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos);
380
381 /**
382 * Assigns a partial copy of another RTCString.
383 *
384 * @param a_rSrc The source string.
385 * @param a_offSrc The byte offset into the source string.
386 * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
387 * to copy from the source string.
388 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
389 */
390 int assignNoThrow(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos) RT_NOEXCEPT;
391
392 /**
393 * Assigns a partial copy of a C-style string.
394 *
395 * @param a_pszSrc The source string (UTF-8).
396 * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
397 * to copy from the source string.
398 * @throws std::bad_alloc On allocation error. The object is left unchanged.
399 */
400 RTCString &assign(const char *a_pszSrc, size_t a_cchSrc);
401
402 /**
403 * Assigns a partial copy of a C-style string.
404 *
405 * @param a_pszSrc The source string (UTF-8).
406 * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
407 * to copy from the source string.
408 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
409 */
410 int assignNoThrow(const char *a_pszSrc, size_t a_cchSrc) RT_NOEXCEPT;
411
412 /**
413 * Assigs a string containing @a a_cTimes repetitions of the character @a a_ch.
414 *
415 * @param a_cTimes The number of times the character is repeated.
416 * @param a_ch The character to fill the string with.
417 * @throws std::bad_alloc On allocation error. The object is left unchanged.
418 */
419 RTCString &assign(size_t a_cTimes, char a_ch);
420
421 /**
422 * Assigs a string containing @a a_cTimes repetitions of the character @a a_ch.
423 *
424 * @param a_cTimes The number of times the character is repeated.
425 * @param a_ch The character to fill the string with.
426 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
427 */
428 int assignNoThrow(size_t a_cTimes, char a_ch) RT_NOEXCEPT;
429
430 /**
431 * Assigns the output of the string format operation (RTStrPrintf).
432 *
433 * @param pszFormat Pointer to the format string,
434 * @see pg_rt_str_format.
435 * @param ... Ellipsis containing the arguments specified by
436 * the format string.
437 *
438 * @throws std::bad_alloc On allocation error. The object is left unchanged.
439 *
440 * @returns Reference to the object.
441 */
442 RTCString &printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
443
444 /**
445 * Assigns the output of the string format operation (RTStrPrintf).
446 *
447 * @param pszFormat Pointer to the format string,
448 * @see pg_rt_str_format.
449 * @param ... Ellipsis containing the arguments specified by
450 * the format string.
451 *
452 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
453 */
454 int printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
455
456 /**
457 * Assigns the output of the string format operation (RTStrPrintfV).
458 *
459 * @param pszFormat Pointer to the format string,
460 * @see pg_rt_str_format.
461 * @param va Argument vector containing the arguments
462 * specified by the format string.
463 *
464 * @throws std::bad_alloc On allocation error. The object is left unchanged.
465 *
466 * @returns Reference to the object.
467 */
468 RTCString &printfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
469
470 /**
471 * Assigns the output of the string format operation (RTStrPrintfV).
472 *
473 * @param pszFormat Pointer to the format string,
474 * @see pg_rt_str_format.
475 * @param va Argument vector containing the arguments
476 * specified by the format string.
477 *
478 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
479 */
480 int printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
481
482 /**
483 * Appends the string @a that to @a rThat.
484 *
485 * @param rThat The string to append.
486 * @throws std::bad_alloc On allocation error. The object is left unchanged.
487 * @returns Reference to the object.
488 */
489 RTCString &append(const RTCString &rThat);
490
491 /**
492 * Appends the string @a that to @a rThat.
493 *
494 * @param rThat The string to append.
495 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
496 */
497 int appendNoThrow(const RTCString &rThat) RT_NOEXCEPT;
498
499 /**
500 * Appends the string @a pszSrc to @a this.
501 *
502 * @param pszSrc The C-style string to append.
503 * @throws std::bad_alloc On allocation error. The object is left unchanged.
504 * @returns Reference to the object.
505 */
506 RTCString &append(const char *pszSrc);
507
508 /**
509 * Appends the string @a pszSrc to @a this.
510 *
511 * @param pszSrc The C-style string to append.
512 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
513 */
514 int appendNoThrow(const char *pszSrc) RT_NOEXCEPT;
515
516 /**
517 * Appends the a substring from @a rThat to @a this.
518 *
519 * @param rThat The string to append a substring from.
520 * @param offStart The start of the substring to append (byte offset,
521 * not codepoint).
522 * @param cchMax The maximum number of bytes to append.
523 * @throws std::bad_alloc On allocation error. The object is left unchanged.
524 * @returns Reference to the object.
525 */
526 RTCString &append(const RTCString &rThat, size_t offStart, size_t cchMax = RTSTR_MAX);
527
528 /**
529 * Appends the a substring from @a rThat to @a this.
530 *
531 * @param rThat The string to append a substring from.
532 * @param offStart The start of the substring to append (byte offset,
533 * not codepoint).
534 * @param cchMax The maximum number of bytes to append.
535 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
536 */
537 int appendNoThrow(const RTCString &rThat, size_t offStart, size_t cchMax = RTSTR_MAX) RT_NOEXCEPT;
538
539 /**
540 * Appends the first @a cchMax chars from string @a pszThat to @a this.
541 *
542 * @param pszThat The C-style string to append.
543 * @param cchMax The maximum number of bytes to append.
544 * @throws std::bad_alloc On allocation error. The object is left unchanged.
545 * @returns Reference to the object.
546 */
547 RTCString &append(const char *pszThat, size_t cchMax);
548
549 /**
550 * Appends the first @a cchMax chars from string @a pszThat to @a this.
551 *
552 * @param pszThat The C-style string to append.
553 * @param cchMax The maximum number of bytes to append.
554 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
555 */
556 int appendNoThrow(const char *pszThat, size_t cchMax) RT_NOEXCEPT;
557
558 /**
559 * Appends the given character to @a this.
560 *
561 * @param ch The character to append.
562 * @throws std::bad_alloc On allocation error. The object is left unchanged.
563 * @returns Reference to the object.
564 */
565 RTCString &append(char ch);
566
567 /**
568 * Appends the given character to @a this.
569 *
570 * @param ch The character to append.
571 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
572 */
573 int appendNoThrow(char ch) RT_NOEXCEPT;
574
575 /**
576 * Appends the given unicode code point to @a this.
577 *
578 * @param uc The unicode code point to append.
579 * @throws std::bad_alloc On allocation error. The object is left unchanged.
580 * @returns Reference to the object.
581 */
582 RTCString &appendCodePoint(RTUNICP uc);
583
584 /**
585 * Appends the given unicode code point to @a this.
586 *
587 * @param uc The unicode code point to append.
588 * @returns VINF_SUCCESS, VERR_INVALID_UTF8_ENCODING or VERR_NO_STRING_MEMORY.
589 */
590 int appendCodePointNoThrow(RTUNICP uc) RT_NOEXCEPT;
591
592 /**
593 * Appends the output of the string format operation (RTStrPrintf).
594 *
595 * @param pszFormat Pointer to the format string,
596 * @see pg_rt_str_format.
597 * @param ... Ellipsis containing the arguments specified by
598 * the format string.
599 *
600 * @throws std::bad_alloc On allocation error. The object is left unchanged.
601 *
602 * @returns Reference to the object.
603 */
604 RTCString &appendPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
605
606 /**
607 * Appends the output of the string format operation (RTStrPrintf).
608 *
609 * @param pszFormat Pointer to the format string,
610 * @see pg_rt_str_format.
611 * @param ... Ellipsis containing the arguments specified by
612 * the format string.
613 *
614 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
615 */
616 int appendPrintfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
617
618 /**
619 * Appends the output of the string format operation (RTStrPrintfV).
620 *
621 * @param pszFormat Pointer to the format string,
622 * @see pg_rt_str_format.
623 * @param va Argument vector containing the arguments
624 * specified by the format string.
625 *
626 * @throws std::bad_alloc On allocation error. The object is left unchanged.
627 *
628 * @returns Reference to the object.
629 */
630 RTCString &appendPrintfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
631
632 /**
633 * Appends the output of the string format operation (RTStrPrintfV).
634 *
635 * @param pszFormat Pointer to the format string,
636 * @see pg_rt_str_format.
637 * @param va Argument vector containing the arguments
638 * specified by the format string.
639 *
640 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
641 */
642 int appendPrintfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
643
644 /**
645 * Shortcut to append(), RTCString variant.
646 *
647 * @param rThat The string to append.
648 * @returns Reference to the object.
649 */
650 RTCString &operator+=(const RTCString &rThat)
651 {
652 return append(rThat);
653 }
654
655 /**
656 * Shortcut to append(), const char* variant.
657 *
658 * @param pszThat The C-style string to append.
659 * @returns Reference to the object.
660 */
661 RTCString &operator+=(const char *pszThat)
662 {
663 return append(pszThat);
664 }
665
666 /**
667 * Shortcut to append(), char variant.
668 *
669 * @param ch The character to append.
670 *
671 * @returns Reference to the object.
672 */
673 RTCString &operator+=(char ch)
674 {
675 return append(ch);
676 }
677
678 /**
679 * Converts the member string to upper case.
680 *
681 * @returns Reference to the object.
682 */
683 RTCString &toUpper() RT_NOEXCEPT
684 {
685 if (length())
686 {
687 /* Folding an UTF-8 string may result in a shorter encoding (see
688 testcase), so recalculate the length afterwards. */
689 ::RTStrToUpper(m_psz);
690 size_t cchNew = strlen(m_psz);
691 Assert(cchNew <= m_cch);
692 m_cch = cchNew;
693 }
694 return *this;
695 }
696
697 /**
698 * Converts the member string to lower case.
699 *
700 * @returns Reference to the object.
701 */
702 RTCString &toLower() RT_NOEXCEPT
703 {
704 if (length())
705 {
706 /* Folding an UTF-8 string may result in a shorter encoding (see
707 testcase), so recalculate the length afterwards. */
708 ::RTStrToLower(m_psz);
709 size_t cchNew = strlen(m_psz);
710 Assert(cchNew <= m_cch);
711 m_cch = cchNew;
712 }
713 return *this;
714 }
715
716 /**
717 * Erases a sequence from the string.
718 *
719 * @returns Reference to the object.
720 * @param offStart Where in @a this string to start erasing.
721 * @param cchLength How much following @a offStart to erase.
722 */
723 RTCString &erase(size_t offStart = 0, size_t cchLength = npos) RT_NOEXCEPT;
724
725 /**
726 * Replaces a span of @a this string with a replacement string.
727 *
728 * @returns Reference to the object.
729 * @param offStart Where in @a this string to start replacing.
730 * @param cchLength How much following @a offStart to replace. npos is
731 * accepted.
732 * @param rStrReplacement The replacement string.
733 *
734 * @throws std::bad_alloc On allocation error. The object is left unchanged.
735 *
736 * @note Non-standard behaviour if offStart is beyond the end of the string.
737 * No change will occure and strict builds hits a debug assertion.
738 */
739 RTCString &replace(size_t offStart, size_t cchLength, const RTCString &rStrReplacement);
740
741 /**
742 * Replaces a span of @a this string with a replacement string.
743 *
744 * @returns VINF_SUCCESS, VERR_OUT_OF_RANGE or VERR_NO_STRING_MEMORY.
745 * @param offStart Where in @a this string to start replacing.
746 * @param cchLength How much following @a offStart to replace. npos is
747 * accepted.
748 * @param rStrReplacement The replacement string.
749 */
750 int replaceNoThrow(size_t offStart, size_t cchLength, const RTCString &rStrReplacement) RT_NOEXCEPT;
751
752 /**
753 * Replaces a span of @a this string with a replacement substring.
754 *
755 * @returns Reference to the object.
756 * @param offStart Where in @a this string to start replacing.
757 * @param cchLength How much following @a offStart to replace. npos is
758 * accepted.
759 * @param rStrReplacement The string from which a substring is taken.
760 * @param offReplacement The offset into @a rStrReplacement where the
761 * replacement substring starts.
762 * @param cchReplacement The maximum length of the replacement substring.
763 *
764 * @throws std::bad_alloc On allocation error. The object is left unchanged.
765 *
766 * @note Non-standard behaviour if offStart or offReplacement is beyond the
767 * end of the repective strings. No change is made in the former case,
768 * while we consider it an empty string in the latter. In both
769 * situation a debug assertion is raised in strict builds.
770 */
771 RTCString &replace(size_t offStart, size_t cchLength, const RTCString &rStrReplacement,
772 size_t offReplacement, size_t cchReplacement);
773
774 /**
775 * Replaces a span of @a this string with a replacement substring.
776 *
777 * @returns VINF_SUCCESS, VERR_OUT_OF_RANGE or VERR_NO_STRING_MEMORY.
778 * @param offStart Where in @a this string to start replacing.
779 * @param cchLength How much following @a offStart to replace. npos is
780 * accepted.
781 * @param rStrReplacement The string from which a substring is taken.
782 * @param offReplacement The offset into @a rStrReplacement where the
783 * replacement substring starts.
784 * @param cchReplacement The maximum length of the replacement substring.
785 */
786 int replaceNoThrow(size_t offStart, size_t cchLength, const RTCString &rStrReplacement,
787 size_t offReplacement, size_t cchReplacement) RT_NOEXCEPT;
788
789 /**
790 * Replaces a span of @a this string with the replacement string.
791 *
792 * @returns Reference to the object.
793 * @param offStart Where in @a this string to start replacing.
794 * @param cchLength How much following @a offStart to replace. npos is
795 * accepted.
796 * @param pszReplacement The replacement string.
797 *
798 * @throws std::bad_alloc On allocation error. The object is left unchanged.
799 *
800 * @note Non-standard behaviour if offStart is beyond the end of the string.
801 * No change will occure and strict builds hits a debug assertion.
802 */
803 RTCString &replace(size_t offStart, size_t cchLength, const char *pszReplacement);
804
805 /**
806 * Replaces a span of @a this string with the replacement string.
807 *
808 * @returns VINF_SUCCESS, VERR_OUT_OF_RANGE or VERR_NO_STRING_MEMORY.
809 * @param offStart Where in @a this string to start replacing.
810 * @param cchLength How much following @a offStart to replace. npos is
811 * accepted.
812 * @param pszReplacement The replacement string.
813 */
814 int replaceNoThrow(size_t offStart, size_t cchLength, const char *pszReplacement) RT_NOEXCEPT;
815
816 /**
817 * Replaces a span of @a this string with the replacement string.
818 *
819 * @returns Reference to the object.
820 * @param offStart Where in @a this string to start replacing.
821 * @param cchLength How much following @a offStart to replace. npos is
822 * accepted.
823 * @param pszReplacement The replacement string.
824 * @param cchReplacement How much of @a pszReplacement to use at most. If a
825 * zero terminator is found before reaching this value,
826 * we'll stop there.
827 *
828 * @throws std::bad_alloc On allocation error. The object is left unchanged.
829 *
830 * @note Non-standard behaviour if offStart is beyond the end of the string.
831 * No change will occure and strict builds hits a debug assertion.
832 */
833 RTCString &replace(size_t offStart, size_t cchLength, const char *pszReplacement, size_t cchReplacement);
834
835 /**
836 * Replaces a span of @a this string with the replacement string.
837 *
838 * @returns VINF_SUCCESS, VERR_OUT_OF_RANGE or VERR_NO_STRING_MEMORY.
839 * @param offStart Where in @a this string to start replacing.
840 * @param cchLength How much following @a offStart to replace. npos is
841 * accepted.
842 * @param pszReplacement The replacement string.
843 * @param cchReplacement How much of @a pszReplacement to use at most. If a
844 * zero terminator is found before reaching this value,
845 * we'll stop there.
846 */
847 int replaceNoThrow(size_t offStart, size_t cchLength, const char *pszReplacement, size_t cchReplacement) RT_NOEXCEPT;
848
849 /**
850 * Index operator.
851 *
852 * Returns the byte at the given index, or a null byte if the index is not
853 * smaller than length(). This does _not_ count codepoints but simply points
854 * into the member C-style string.
855 *
856 * @param i The index into the string buffer.
857 * @returns char at the index or null.
858 */
859 inline char operator[](size_t i) const RT_NOEXCEPT
860 {
861 if (i < length())
862 return m_psz[i];
863 return '\0';
864 }
865
866 /**
867 * Returns the contained string as a const C-style string pointer.
868 *
869 * This never returns NULL; if the string is empty, this returns a pointer to
870 * static null byte.
871 *
872 * @returns const pointer to C-style string.
873 */
874 inline const char *c_str() const RT_NOEXCEPT
875 {
876 return (m_psz) ? m_psz : "";
877 }
878
879 /**
880 * Returns a non-const raw pointer that allows to modify the string directly.
881 * As opposed to c_str() and raw(), this DOES return NULL for an empty string
882 * because we cannot return a non-const pointer to a static "" global.
883 *
884 * @warning
885 * -# Be sure not to modify data beyond the allocated memory! Call
886 * capacity() to find out how large that buffer is.
887 * -# After any operation that modifies the length of the string,
888 * you _must_ call RTCString::jolt(), or subsequent copy operations
889 * may go nowhere. Better not use mutableRaw() at all.
890 */
891 char *mutableRaw() RT_NOEXCEPT
892 {
893 return m_psz;
894 }
895
896 /**
897 * Clean up after using mutableRaw.
898 *
899 * Intended to be called after something has messed with the internal string
900 * buffer (e.g. after using mutableRaw() or Utf8Str::asOutParam()). Resets the
901 * internal lengths correctly. Otherwise subsequent copy operations may go
902 * nowhere.
903 */
904 void jolt() RT_NOEXCEPT
905 {
906 if (m_psz)
907 {
908 m_cch = strlen(m_psz);
909 m_cbAllocated = m_cch + 1; /* (Required for the Utf8Str::asOutParam case) */
910 }
911 else
912 {
913 m_cch = 0;
914 m_cbAllocated = 0;
915 }
916 }
917
918 /**
919 * Returns @c true if the member string has no length.
920 *
921 * This is @c true for instances created from both NULL and "" input
922 * strings.
923 *
924 * This states nothing about how much memory might be allocated.
925 *
926 * @returns @c true if empty, @c false if not.
927 */
928 bool isEmpty() const RT_NOEXCEPT
929 {
930 return length() == 0;
931 }
932
933 /**
934 * Returns @c false if the member string has no length.
935 *
936 * This is @c false for instances created from both NULL and "" input
937 * strings.
938 *
939 * This states nothing about how much memory might be allocated.
940 *
941 * @returns @c false if empty, @c true if not.
942 */
943 bool isNotEmpty() const RT_NOEXCEPT
944 {
945 return length() != 0;
946 }
947
948 /** Case sensitivity selector. */
949 enum CaseSensitivity
950 {
951 CaseSensitive,
952 CaseInsensitive
953 };
954
955 /**
956 * Compares the member string to a C-string.
957 *
958 * @param pcszThat The string to compare with.
959 * @param cs Whether comparison should be case-sensitive.
960 * @returns 0 if equal, negative if this is smaller than @a pcsz, positive
961 * if larger.
962 */
963 int compare(const char *pcszThat, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT
964 {
965 /* This klugde is for m_cch=0 and m_psz=NULL. pcsz=NULL and psz=""
966 are treated the same way so that str.compare(str2.c_str()) works. */
967 if (length() == 0)
968 return pcszThat == NULL || *pcszThat == '\0' ? 0 : -1;
969
970 if (cs == CaseSensitive)
971 return ::RTStrCmp(m_psz, pcszThat);
972 return ::RTStrICmp(m_psz, pcszThat);
973 }
974
975 /**
976 * Compares the member string to another RTCString.
977 *
978 * @param rThat The string to compare with.
979 * @param cs Whether comparison should be case-sensitive.
980 * @returns 0 if equal, negative if this is smaller than @a pcsz, positive
981 * if larger.
982 */
983 int compare(const RTCString &rThat, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT
984 {
985 if (cs == CaseSensitive)
986 return ::RTStrCmp(m_psz, rThat.m_psz);
987 return ::RTStrICmp(m_psz, rThat.m_psz);
988 }
989
990 /**
991 * Compares the two strings.
992 *
993 * @returns true if equal, false if not.
994 * @param rThat The string to compare with.
995 */
996 bool equals(const RTCString &rThat) const RT_NOEXCEPT
997 {
998 return rThat.length() == length()
999 && ( length() == 0
1000 || memcmp(rThat.m_psz, m_psz, length()) == 0);
1001 }
1002
1003 /**
1004 * Compares the two strings.
1005 *
1006 * @returns true if equal, false if not.
1007 * @param pszThat The string to compare with.
1008 */
1009 bool equals(const char *pszThat) const RT_NOEXCEPT
1010 {
1011 /* This klugde is for m_cch=0 and m_psz=NULL. pcsz=NULL and psz=""
1012 are treated the same way so that str.equals(str2.c_str()) works. */
1013 if (length() == 0)
1014 return pszThat == NULL || *pszThat == '\0';
1015 return RTStrCmp(pszThat, m_psz) == 0;
1016 }
1017
1018 /**
1019 * Compares the two strings ignoring differences in case.
1020 *
1021 * @returns true if equal, false if not.
1022 * @param that The string to compare with.
1023 */
1024 bool equalsIgnoreCase(const RTCString &that) const RT_NOEXCEPT
1025 {
1026 /* Unfolded upper and lower case characters may require different
1027 amount of encoding space, so the length optimization doesn't work. */
1028 return RTStrICmp(that.m_psz, m_psz) == 0;
1029 }
1030
1031 /**
1032 * Compares the two strings ignoring differences in case.
1033 *
1034 * @returns true if equal, false if not.
1035 * @param pszThat The string to compare with.
1036 */
1037 bool equalsIgnoreCase(const char *pszThat) const RT_NOEXCEPT
1038 {
1039 /* This klugde is for m_cch=0 and m_psz=NULL. pcsz=NULL and psz=""
1040 are treated the same way so that str.equalsIgnoreCase(str2.c_str()) works. */
1041 if (length() == 0)
1042 return pszThat == NULL || *pszThat == '\0';
1043 return RTStrICmp(pszThat, m_psz) == 0;
1044 }
1045
1046 /** @name Comparison operators.
1047 * @{ */
1048 bool operator==(const RTCString &that) const { return equals(that); }
1049 bool operator!=(const RTCString &that) const { return !equals(that); }
1050 bool operator<( const RTCString &that) const { return compare(that) < 0; }
1051 bool operator>( const RTCString &that) const { return compare(that) > 0; }
1052
1053 bool operator==(const char *pszThat) const { return equals(pszThat); }
1054 bool operator!=(const char *pszThat) const { return !equals(pszThat); }
1055 bool operator<( const char *pszThat) const { return compare(pszThat) < 0; }
1056 bool operator>( const char *pszThat) const { return compare(pszThat) > 0; }
1057 /** @} */
1058
1059 /** Max string offset value.
1060 *
1061 * When returned by a method, this indicates failure. When taken as input,
1062 * typically a default, it means all the way to the string terminator.
1063 */
1064 static const size_t npos;
1065
1066 /**
1067 * Find the given substring.
1068 *
1069 * Looks for @a pszNeedle in @a this starting at @a offStart and returns its
1070 * position as a byte (not codepoint) offset, counting from the beginning of
1071 * @a this as 0.
1072 *
1073 * @param pszNeedle The substring to find.
1074 * @param offStart The (byte) offset into the string buffer to start
1075 * searching.
1076 *
1077 * @returns 0 based position of pszNeedle. npos if not found.
1078 */
1079 size_t find(const char *pszNeedle, size_t offStart = 0) const RT_NOEXCEPT;
1080
1081 /**
1082 * Find the given substring.
1083 *
1084 * Looks for @a pStrNeedle in @a this starting at @a offStart and returns its
1085 * position as a byte (not codepoint) offset, counting from the beginning of
1086 * @a this as 0.
1087 *
1088 * @param pStrNeedle The substring to find.
1089 * @param offStart The (byte) offset into the string buffer to start
1090 * searching.
1091 *
1092 * @returns 0 based position of pStrNeedle. npos if not found or pStrNeedle is
1093 * NULL or an empty string.
1094 */
1095 size_t find(const RTCString *pStrNeedle, size_t offStart = 0) const RT_NOEXCEPT;
1096
1097 /**
1098 * Find the given substring.
1099 *
1100 * Looks for @a rStrNeedle in @a this starting at @a offStart and returns its
1101 * position as a byte (not codepoint) offset, counting from the beginning of
1102 * @a this as 0.
1103 *
1104 * @param rStrNeedle The substring to find.
1105 * @param offStart The (byte) offset into the string buffer to start
1106 * searching.
1107 *
1108 * @returns 0 based position of pStrNeedle. npos if not found or pStrNeedle is
1109 * NULL or an empty string.
1110 */
1111 size_t find(const RTCString &rStrNeedle, size_t offStart = 0) const RT_NOEXCEPT;
1112
1113 /**
1114 * Find the given character (byte).
1115 *
1116 * @returns 0 based position of chNeedle. npos if not found or pStrNeedle is
1117 * NULL or an empty string.
1118 * @param chNeedle The character (byte) to find.
1119 * @param offStart The (byte) offset into the string buffer to start
1120 * searching. Default is start of the string.
1121 *
1122 * @note This searches for a C character value, not a codepoint. Use the
1123 * string version to locate codepoints above U+7F.
1124 */
1125 size_t find(char chNeedle, size_t offStart = 0) const RT_NOEXCEPT;
1126
1127 /**
1128 * Replaces all occurences of cFind with cReplace in the member string.
1129 * In order not to produce invalid UTF-8, the characters must be ASCII
1130 * values less than 128; this is not verified.
1131 *
1132 * @param chFind Character to replace. Must be ASCII < 128.
1133 * @param chReplace Character to replace cFind with. Must be ASCII < 128.
1134 */
1135 void findReplace(char chFind, char chReplace) RT_NOEXCEPT;
1136
1137 /**
1138 * Count the occurences of the specified character in the string.
1139 *
1140 * @param ch What to search for. Must be ASCII < 128.
1141 * @remarks QString::count
1142 */
1143 size_t count(char ch) const RT_NOEXCEPT;
1144
1145 /**
1146 * Count the occurences of the specified sub-string in the string.
1147 *
1148 * @param psz What to search for.
1149 * @param cs Case sensitivity selector.
1150 * @remarks QString::count
1151 */
1152 size_t count(const char *psz, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
1153
1154 /**
1155 * Count the occurences of the specified sub-string in the string.
1156 *
1157 * @param pStr What to search for.
1158 * @param cs Case sensitivity selector.
1159 * @remarks QString::count
1160 */
1161 size_t count(const RTCString *pStr, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
1162
1163 /**
1164 * Strips leading and trailing spaces.
1165 *
1166 * @returns this
1167 */
1168 RTCString &strip() RT_NOEXCEPT;
1169
1170 /**
1171 * Strips leading spaces.
1172 *
1173 * @returns this
1174 */
1175 RTCString &stripLeft() RT_NOEXCEPT;
1176
1177 /**
1178 * Strips trailing spaces.
1179 *
1180 * @returns this
1181 */
1182 RTCString &stripRight() RT_NOEXCEPT;
1183
1184 /**
1185 * Returns a substring of @a this as a new Utf8Str.
1186 *
1187 * Works exactly like its equivalent in std::string. With the default
1188 * parameters "0" and "npos", this always copies the entire string. The
1189 * "pos" and "n" arguments represent bytes; it is the caller's responsibility
1190 * to ensure that the offsets do not copy invalid UTF-8 sequences. When
1191 * used in conjunction with find() and length(), this will work.
1192 *
1193 * @param pos Index of first byte offset to copy from @a this,
1194 * counting from 0.
1195 * @param n Number of bytes to copy, starting with the one at "pos".
1196 * The copying will stop if the null terminator is encountered before
1197 * n bytes have been copied.
1198 */
1199 RTCString substr(size_t pos = 0, size_t n = npos) const
1200 {
1201 return RTCString(*this, pos, n);
1202 }
1203
1204 /**
1205 * Returns a substring of @a this as a new Utf8Str. As opposed to substr(), this
1206 * variant takes codepoint offsets instead of byte offsets.
1207 *
1208 * @param pos Index of first unicode codepoint to copy from
1209 * @a this, counting from 0.
1210 * @param n Number of unicode codepoints to copy, starting with
1211 * the one at "pos". The copying will stop if the null
1212 * terminator is encountered before n codepoints have
1213 * been copied.
1214 */
1215 RTCString substrCP(size_t pos = 0, size_t n = npos) const;
1216
1217 /**
1218 * Returns true if @a this ends with @a that.
1219 *
1220 * @param that Suffix to test for.
1221 * @param cs Case sensitivity selector.
1222 * @returns true if match, false if mismatch.
1223 */
1224 bool endsWith(const RTCString &that, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
1225
1226 /**
1227 * Returns true if @a this begins with @a that.
1228 * @param that Prefix to test for.
1229 * @param cs Case sensitivity selector.
1230 * @returns true if match, false if mismatch.
1231 */
1232 bool startsWith(const RTCString &that, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
1233
1234 /**
1235 * Checks if the string starts with the given word, ignoring leading blanks.
1236 *
1237 * @param pszWord The word to test for.
1238 * @param enmCase Case sensitivity selector.
1239 * @returns true if match, false if mismatch.
1240 */
1241 bool startsWithWord(const char *pszWord, CaseSensitivity enmCase = CaseSensitive) const RT_NOEXCEPT;
1242
1243 /**
1244 * Checks if the string starts with the given word, ignoring leading blanks.
1245 *
1246 * @param rThat Prefix to test for.
1247 * @param enmCase Case sensitivity selector.
1248 * @returns true if match, false if mismatch.
1249 */
1250 bool startsWithWord(const RTCString &rThat, CaseSensitivity enmCase = CaseSensitive) const RT_NOEXCEPT;
1251
1252 /**
1253 * Returns true if @a this contains @a that (strstr).
1254 *
1255 * @param that Substring to look for.
1256 * @param cs Case sensitivity selector.
1257 * @returns true if found, false if not found.
1258 */
1259 bool contains(const RTCString &that, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
1260
1261 /**
1262 * Returns true if @a this contains @a pszNeedle (strstr).
1263 *
1264 * @param pszNeedle Substring to look for.
1265 * @param cs Case sensitivity selector.
1266 * @returns true if found, false if not found.
1267 */
1268 bool contains(const char *pszNeedle, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
1269
1270 /**
1271 * Attempts to convert the member string into a 32-bit integer.
1272 *
1273 * @returns 32-bit unsigned number on success.
1274 * @returns 0 on failure.
1275 */
1276 int32_t toInt32() const RT_NOEXCEPT
1277 {
1278 return RTStrToInt32(c_str());
1279 }
1280
1281 /**
1282 * Attempts to convert the member string into an unsigned 32-bit integer.
1283 *
1284 * @returns 32-bit unsigned number on success.
1285 * @returns 0 on failure.
1286 */
1287 uint32_t toUInt32() const RT_NOEXCEPT
1288 {
1289 return RTStrToUInt32(c_str());
1290 }
1291
1292 /**
1293 * Attempts to convert the member string into an 64-bit integer.
1294 *
1295 * @returns 64-bit unsigned number on success.
1296 * @returns 0 on failure.
1297 */
1298 int64_t toInt64() const RT_NOEXCEPT
1299 {
1300 return RTStrToInt64(c_str());
1301 }
1302
1303 /**
1304 * Attempts to convert the member string into an unsigned 64-bit integer.
1305 *
1306 * @returns 64-bit unsigned number on success.
1307 * @returns 0 on failure.
1308 */
1309 uint64_t toUInt64() const RT_NOEXCEPT
1310 {
1311 return RTStrToUInt64(c_str());
1312 }
1313
1314 /**
1315 * Attempts to convert the member string into an unsigned 64-bit integer.
1316 *
1317 * @param i Where to return the value on success.
1318 * @returns IPRT error code, see RTStrToInt64.
1319 */
1320 int toInt(uint64_t &i) const RT_NOEXCEPT;
1321
1322 /**
1323 * Attempts to convert the member string into an unsigned 32-bit integer.
1324 *
1325 * @param i Where to return the value on success.
1326 * @returns IPRT error code, see RTStrToInt32.
1327 */
1328 int toInt(uint32_t &i) const RT_NOEXCEPT;
1329
1330 /** Splitting behavior regarding empty sections in the string. */
1331 enum SplitMode
1332 {
1333 KeepEmptyParts, /**< Empty parts are added as empty strings to the result list. */
1334 RemoveEmptyParts /**< Empty parts are skipped. */
1335 };
1336
1337 /**
1338 * Splits a string separated by strSep into its parts.
1339 *
1340 * @param a_rstrSep The separator to search for.
1341 * @param a_enmMode How should empty parts be handled.
1342 * @returns separated strings as string list.
1343 * @throws std::bad_alloc On allocation error.
1344 */
1345 RTCList<RTCString, RTCString *> split(const RTCString &a_rstrSep,
1346 SplitMode a_enmMode = RemoveEmptyParts) const;
1347
1348 /**
1349 * Joins a list of strings together using the provided separator and
1350 * an optional prefix for each item in the list.
1351 *
1352 * @param a_rList The list to join.
1353 * @param a_rstrPrefix The prefix used for appending to each item.
1354 * @param a_rstrSep The separator used for joining.
1355 * @returns joined string.
1356 * @throws std::bad_alloc On allocation error.
1357 */
1358 static RTCString joinEx(const RTCList<RTCString, RTCString *> &a_rList,
1359 const RTCString &a_rstrPrefix /* = "" */,
1360 const RTCString &a_rstrSep /* = "" */);
1361
1362 /**
1363 * Joins a list of strings together using the provided separator.
1364 *
1365 * @param a_rList The list to join.
1366 * @param a_rstrSep The separator used for joining.
1367 * @returns joined string.
1368 * @throws std::bad_alloc On allocation error.
1369 */
1370 static RTCString join(const RTCList<RTCString, RTCString *> &a_rList,
1371 const RTCString &a_rstrSep = "");
1372
1373 /**
1374 * Swaps two strings in a fast way.
1375 *
1376 * Exception safe.
1377 *
1378 * @param a_rThat The string to swap with.
1379 */
1380 inline void swap(RTCString &a_rThat) RT_NOEXCEPT
1381 {
1382 char *pszTmp = m_psz;
1383 size_t cchTmp = m_cch;
1384 size_t cbAllocatedTmp = m_cbAllocated;
1385
1386 m_psz = a_rThat.m_psz;
1387 m_cch = a_rThat.m_cch;
1388 m_cbAllocated = a_rThat.m_cbAllocated;
1389
1390 a_rThat.m_psz = pszTmp;
1391 a_rThat.m_cch = cchTmp;
1392 a_rThat.m_cbAllocated = cbAllocatedTmp;
1393 }
1394
1395protected:
1396
1397 /**
1398 * Hide operator bool() to force people to use isEmpty() explicitly.
1399 */
1400 operator bool() const;
1401
1402 /**
1403 * Destructor implementation, also used to clean up in operator=() before
1404 * assigning a new string.
1405 */
1406 void cleanup() RT_NOEXCEPT
1407 {
1408 if (m_psz)
1409 {
1410 RTStrFree(m_psz);
1411 m_psz = NULL;
1412 m_cch = 0;
1413 m_cbAllocated = 0;
1414 }
1415 }
1416
1417 /**
1418 * Protected internal helper to copy a string.
1419 *
1420 * This ignores the previous object state, so either call this from a
1421 * constructor or call cleanup() first. copyFromN() unconditionally sets
1422 * the members to a copy of the given other strings and makes no
1423 * assumptions about previous contents. Can therefore be used both in copy
1424 * constructors, when member variables have no defined value, and in
1425 * assignments after having called cleanup().
1426 *
1427 * @param pcszSrc The source string.
1428 * @param cchSrc The number of chars (bytes) to copy from the
1429 * source strings. RTSTR_MAX is NOT accepted.
1430 *
1431 * @throws std::bad_alloc On allocation failure. The object is left
1432 * describing a NULL string.
1433 */
1434 void copyFromN(const char *pcszSrc, size_t cchSrc)
1435 {
1436 if (cchSrc)
1437 {
1438 m_psz = RTStrAlloc(cchSrc + 1);
1439 if (RT_LIKELY(m_psz))
1440 {
1441 m_cch = cchSrc;
1442 m_cbAllocated = cchSrc + 1;
1443 memcpy(m_psz, pcszSrc, cchSrc);
1444 m_psz[cchSrc] = '\0';
1445 }
1446 else
1447 {
1448 m_cch = 0;
1449 m_cbAllocated = 0;
1450#ifdef RT_EXCEPTIONS_ENABLED
1451 throw std::bad_alloc();
1452#endif
1453 }
1454 }
1455 else
1456 {
1457 m_cch = 0;
1458 m_cbAllocated = 0;
1459 m_psz = NULL;
1460 }
1461 }
1462
1463 /**
1464 * Appends exactly @a cchSrc chars from @a pszSrc to @a this.
1465 *
1466 * This is an internal worker for the append() methods.
1467 *
1468 * @returns Reference to the object.
1469 * @param pszSrc The source string.
1470 * @param cchSrc The source string length (exact).
1471 * @throws std::bad_alloc On allocation error. The object is left unchanged.
1472 *
1473 */
1474 RTCString &appendWorker(const char *pszSrc, size_t cchSrc);
1475
1476 /**
1477 * Appends exactly @a cchSrc chars from @a pszSrc to @a this.
1478 *
1479 * This is an internal worker for the appendNoThrow() methods.
1480 *
1481 * @returns VINF_SUCCESS or VERR_NO_STRING_MEMORY.
1482 * @param pszSrc The source string.
1483 * @param cchSrc The source string length (exact).
1484 */
1485 int appendWorkerNoThrow(const char *pszSrc, size_t cchSrc) RT_NOEXCEPT;
1486
1487 /**
1488 * Replaces exatly @a cchLength chars at @a offStart with @a cchSrc from @a
1489 * pszSrc.
1490 *
1491 * @returns Reference to the object.
1492 * @param offStart Where in @a this string to start replacing.
1493 * @param cchLength How much following @a offStart to replace. npos is
1494 * accepted.
1495 * @param pszSrc The replacement string.
1496 * @param cchSrc The exactly length of the replacement string.
1497 *
1498 * @throws std::bad_alloc On allocation error. The object is left unchanged.
1499 */
1500 RTCString &replaceWorker(size_t offStart, size_t cchLength, const char *pszSrc, size_t cchSrc);
1501
1502 /**
1503 * Replaces exatly @a cchLength chars at @a offStart with @a cchSrc from @a
1504 * pszSrc.
1505 *
1506 * @returns VINF_SUCCESS, VERR_OUT_OF_RANGE or VERR_NO_STRING_MEMORY.
1507 * @param offStart Where in @a this string to start replacing.
1508 * @param cchLength How much following @a offStart to replace. npos is
1509 * accepted.
1510 * @param pszSrc The replacement string.
1511 * @param cchSrc The exactly length of the replacement string.
1512 */
1513 int replaceWorkerNoThrow(size_t offStart, size_t cchLength, const char *pszSrc, size_t cchSrc) RT_NOEXCEPT;
1514
1515 static DECLCALLBACK(size_t) printfOutputCallback(void *pvArg, const char *pachChars, size_t cbChars);
1516 static DECLCALLBACK(size_t) printfOutputCallbackNoThrow(void *pvArg, const char *pachChars, size_t cbChars) RT_NOEXCEPT;
1517
1518 char *m_psz; /**< The string buffer. */
1519 size_t m_cch; /**< strlen(m_psz) - i.e. no terminator included. */
1520 size_t m_cbAllocated; /**< Size of buffer that m_psz points to; at least m_cbLength + 1. */
1521};
1522
1523/** @} */
1524
1525
1526/** @addtogroup grp_rt_cpp_string
1527 * @{
1528 */
1529
1530/**
1531 * Concatenate two strings.
1532 *
1533 * @param a_rstr1 String one.
1534 * @param a_rstr2 String two.
1535 * @returns the concatenate string.
1536 *
1537 * @relates RTCString
1538 */
1539RTDECL(const RTCString) operator+(const RTCString &a_rstr1, const RTCString &a_rstr2);
1540
1541/**
1542 * Concatenate two strings.
1543 *
1544 * @param a_rstr1 String one.
1545 * @param a_psz2 String two.
1546 * @returns the concatenate string.
1547 *
1548 * @relates RTCString
1549 */
1550RTDECL(const RTCString) operator+(const RTCString &a_rstr1, const char *a_psz2);
1551
1552/**
1553 * Concatenate two strings.
1554 *
1555 * @param a_psz1 String one.
1556 * @param a_rstr2 String two.
1557 * @returns the concatenate string.
1558 *
1559 * @relates RTCString
1560 */
1561RTDECL(const RTCString) operator+(const char *a_psz1, const RTCString &a_rstr2);
1562
1563/**
1564 * Class with RTCString::printf as constructor for your convenience.
1565 *
1566 * Constructing a RTCString string object from a format string and a variable
1567 * number of arguments can easily be confused with the other RTCString
1568 * constructors, thus this child class.
1569 *
1570 * The usage of this class is like the following:
1571 * @code
1572 RTCStringFmt strName("program name = %s", argv[0]);
1573 @endcode
1574 */
1575class RTCStringFmt : public RTCString
1576{
1577public:
1578
1579 /**
1580 * Constructs a new string given the format string and the list of the
1581 * arguments for the format string.
1582 *
1583 * @param a_pszFormat Pointer to the format string (UTF-8),
1584 * @see pg_rt_str_format.
1585 * @param ... Ellipsis containing the arguments specified by
1586 * the format string.
1587 */
1588 explicit RTCStringFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1589 {
1590 va_list va;
1591 va_start(va, a_pszFormat);
1592 printfV(a_pszFormat, va);
1593 va_end(va);
1594 }
1595
1596 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1597
1598protected:
1599 RTCStringFmt() {}
1600};
1601
1602/** @} */
1603
1604#endif /* !IPRT_INCLUDED_cpp_ministring_h */
1605
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette