VirtualBox

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

Last change on this file since 33073 was 33073, checked in by vboxsync, 14 years ago

Main: partly reverted r66582

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 KB
Line 
1/** @file
2 * IPRT - Mini C++ string class.
3 */
4
5/*
6 * Copyright (C) 2007-2009 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 ___VBox_ministring_h
27#define ___VBox_ministring_h
28
29#include <iprt/mem.h>
30#include <iprt/string.h>
31
32#include <new>
33
34namespace iprt
35{
36
37/**
38 * @brief Mini C++ string class.
39 *
40 * "MiniString" is a small C++ string class that does not depend on anything
41 * else except IPRT memory management functions. Semantics are like in
42 * std::string, except it can do a lot less.
43 *
44 * Note that MiniString does not differentiate between NULL strings and
45 * empty strings. In other words, MiniString("") and MiniString(NULL)
46 * behave the same. In both cases, MiniString allocates no memory, reports
47 * a zero length and zero allocated bytes for both, and returns an empty
48 * C string from c_str().
49 */
50#ifdef VBOX
51 /** @remarks Much of the code in here used to be in com::Utf8Str so that
52 * com::Utf8Str can now derive from MiniString and only contain code
53 * that is COM-specific, such as com::Bstr conversions. Compared to
54 * the old Utf8Str though, MiniString always knows the length of its
55 * member string and the size of the buffer so it can use memcpy()
56 * instead of strdup().
57 */
58#endif
59class RT_DECL_CLASS MiniString
60{
61public:
62 /**
63 * Creates an empty string that has no memory allocated.
64 */
65 MiniString()
66 : m_psz(NULL),
67 m_cbLength(0),
68 m_cbAllocated(0)
69 {
70 }
71
72 /**
73 * Creates a copy of another MiniString.
74 *
75 * This allocates s.length() + 1 bytes for the new instance, unless s is empty.
76 *
77 * @param s The source string.
78 *
79 * @throws std::bad_alloc
80 */
81 MiniString(const MiniString &s)
82 {
83 copyFrom(s);
84 }
85
86 /**
87 * Creates a copy of a C string.
88 *
89 * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
90 *
91 * @param pcsz The source string.
92 *
93 * @throws std::bad_alloc
94 */
95 MiniString(const char *pcsz)
96 {
97 copyFrom(pcsz);
98 }
99
100 /**
101 * Destructor.
102 */
103 virtual ~MiniString()
104 {
105 cleanup();
106 }
107
108 /**
109 * String length in bytes.
110 *
111 * Returns the length of the member string, which is equal to strlen(c_str()).
112 * In other words, this does not count unicode codepoints but returns the number
113 * of bytes. This is always cached so calling this is cheap and requires no
114 * strlen() invocation.
115 *
116 * @returns m_cbLength.
117 */
118 size_t length() const
119 {
120 return m_cbLength;
121 }
122
123 /**
124 * The allocated buffer size (in bytes).
125 *
126 * Returns the number of bytes allocated in the internal string buffer, which is
127 * at least length() + 1 if length() > 0; for an empty string, this returns 0.
128 *
129 * @returns m_cbAllocated.
130 */
131 size_t capacity() const
132 {
133 return m_cbAllocated;
134 }
135
136 /**
137 * Make sure at that least cb of buffer space is reserved.
138 *
139 * Requests that the contained memory buffer have at least cb bytes allocated.
140 * This may expand or shrink the string's storage, but will never truncate the
141 * contained string. In other words, cb will be ignored if it's smaller than
142 * length() + 1.
143 *
144 * @param cb New minimum size (in bytes) of member memory buffer.
145 *
146 * @throws std::bad_alloc On allocation error. The object is left unchanged.
147 */
148 void reserve(size_t cb)
149 {
150 if ( cb != m_cbAllocated
151 && cb > m_cbLength + 1
152 )
153 {
154 int vrc = RTStrRealloc(&m_psz, cb);
155 if (RT_SUCCESS(vrc))
156 m_cbAllocated = cb;
157#ifdef RT_EXCEPTIONS_ENABLED
158 else
159 throw std::bad_alloc();
160#endif
161 }
162 }
163
164 /**
165 * Deallocates all memory.
166 */
167 inline void setNull()
168 {
169 cleanup();
170 }
171
172 /**
173 * Assigns a copy of pcsz to "this".
174 *
175 * @param pcsz The source string.
176 *
177 * @throws std::bad_alloc On allocation failure. The object is left describing
178 * a NULL string.
179 *
180 * @returns Reference to the object.
181 */
182 MiniString &operator=(const char *pcsz)
183 {
184 if (m_psz != pcsz)
185 {
186 cleanup();
187 copyFrom(pcsz);
188 }
189 return *this;
190 }
191
192 /**
193 * Assigns a copy of s to "this".
194 *
195 * @param s The source string.
196 *
197 * @throws std::bad_alloc On allocation failure. The object is left describing
198 * a NULL string.
199 *
200 * @returns Reference to the object.
201 */
202 MiniString &operator=(const MiniString &s)
203 {
204 if (this != &s)
205 {
206 cleanup();
207 copyFrom(s);
208 }
209 return *this;
210 }
211
212 /**
213 * Appends the string "that" to "this".
214 *
215 * @param that The string to append.
216 *
217 * @throws std::bad_alloc On allocation error. The object is left unchanged.
218 *
219 * @returns Reference to the object.
220 */
221 MiniString &append(const MiniString &that);
222
223 /**
224 * Appends the string "that" to "this".
225 *
226 * @param pszThat The C string to append.
227 *
228 * @throws std::bad_alloc On allocation error. The object is left unchanged.
229 *
230 * @returns Reference to the object.
231 */
232 MiniString &append(const char *pszThat);
233
234 /**
235 * Appends the given character to "this".
236 *
237 * @param c The character to append.
238 *
239 * @throws std::bad_alloc On allocation error. The object is left unchanged.
240 *
241 * @returns Reference to the object.
242 */
243 MiniString &append(char c);
244
245 /**
246 * Shortcut to append(), MiniString variant.
247 *
248 * @param that The string to append.
249 *
250 * @returns Reference to the object.
251 */
252 MiniString &operator+=(const MiniString &that)
253 {
254 return append(that);
255 }
256
257 /**
258 * Shortcut to append(), const char* variant.
259 *
260 * @param pszThat The C string to append.
261 *
262 * @returns Reference to the object.
263 */
264 MiniString &operator+=(const char *pszThat)
265 {
266 return append(pszThat);
267 }
268
269 /**
270 * Shortcut to append(), char variant.
271 *
272 * @param pszThat The character to append.
273 *
274 * @returns Reference to the object.
275 */
276 MiniString &operator+=(char c)
277 {
278 return append(c);
279 }
280
281 /**
282 * Converts the member string to upper case.
283 *
284 * @returns Reference to the object.
285 */
286 MiniString &toUpper()
287 {
288 if (length())
289 ::RTStrToUpper(m_psz);
290 return *this;
291 }
292
293 /**
294 * Converts the member string to lower case.
295 *
296 * @returns Reference to the object.
297 */
298 MiniString& toLower()
299 {
300 if (length())
301 ::RTStrToLower(m_psz);
302 return *this;
303 }
304
305 /**
306 * Index operator.
307 *
308 * Returns the byte at the given index, or a null byte if the index is not
309 * smaller than length(). This does _not_ count codepoints but simply points
310 * into the member C string.
311 *
312 * @param i The index into the string buffer.
313 * @returns char at the index or null.
314 */
315 inline char operator[](size_t i) const
316 {
317 if (i < length())
318 return m_psz[i];
319 return '\0';
320 }
321
322 /**
323 * Returns the contained string as a C-style const char* pointer.
324 * This never returns NULL; if the string is empty, this returns a
325 * pointer to static null byte.
326 *
327 * @returns const pointer to C-style string.
328 */
329 inline const char *c_str() const
330 {
331 return (m_psz) ? m_psz : "";
332 }
333
334 /**
335 * Returns a non-const raw pointer that allows to modify the string directly.
336 * As opposed to c_str() and raw(), this DOES return NULL for an empty string
337 * because we cannot return a non-const pointer to a static "" global.
338 *
339 * @warning
340 * -# Be sure not to modify data beyond the allocated memory! Call
341 * capacity() to find out how large that buffer is.
342 * -# After any operation that modifies the length of the string,
343 * you _must_ call MiniString::jolt(), or subsequent copy operations
344 * may go nowhere. Better not use mutableRaw() at all.
345 */
346 char *mutableRaw()
347 {
348 return m_psz;
349 }
350
351 /**
352 * Clean up after using mutableRaw.
353 *
354 * Intended to be called after something has messed with the internal string
355 * buffer (e.g. after using mutableRaw() or Utf8Str::asOutParam()). Resets the
356 * internal lengths correctly. Otherwise subsequent copy operations may go
357 * nowhere.
358 */
359 void jolt()
360 {
361 if (m_psz)
362 {
363 m_cbLength = strlen(m_psz);
364 m_cbAllocated = m_cbLength + 1; /* (Required for the Utf8Str::asOutParam case) */
365 }
366 else
367 {
368 m_cbLength = 0;
369 m_cbAllocated = 0;
370 }
371 }
372
373 /**
374 * Returns @c true if the member string has no length.
375 *
376 * This is @c true for instances created from both NULL and "" input
377 * strings.
378 *
379 * This states nothing about how much memory might be allocated.
380 *
381 * @returns @c true if empty, @c false if not.
382 */
383 bool isEmpty() const
384 {
385 return length() == 0;
386 }
387
388 /**
389 * Returns @c false if the member string has no length.
390 *
391 * This is @c false for instances created from both NULL and "" input
392 * strings.
393 *
394 * This states nothing about how much memory might be allocated.
395 *
396 * @returns @c false if empty, @c true if not.
397 */
398 bool isNotEmpty() const
399 {
400 return length() != 0;
401 }
402
403 /** Case sensitivity selector. */
404 enum CaseSensitivity
405 {
406 CaseSensitive,
407 CaseInsensitive
408 };
409
410 /**
411 * Compares the member string to pcsz.
412 * @param pcsz
413 * @param cs Whether comparison should be case-sensitive.
414 * @return
415 */
416 int compare(const char *pcsz, CaseSensitivity cs = CaseSensitive) const
417 {
418 if (m_psz == pcsz)
419 return 0;
420 if (m_psz == NULL)
421 return -1;
422 if (pcsz == NULL)
423 return 1;
424
425 if (cs == CaseSensitive)
426 return ::RTStrCmp(m_psz, pcsz);
427 else
428 return ::RTStrICmp(m_psz, pcsz);
429 }
430
431 int compare(const MiniString &that, CaseSensitivity cs = CaseSensitive) const
432 {
433 return compare(that.m_psz, cs);
434 }
435
436 /** @name Comparison operators.
437 * @{ */
438 bool operator==(const MiniString &that) const { return !compare(that); }
439 bool operator!=(const MiniString &that) const { return !!compare(that); }
440 bool operator<( const MiniString &that) const { return compare(that) < 0; }
441 bool operator>( const MiniString &that) const { return compare(that) > 0; }
442
443 bool operator==(const char *that) const { return !compare(that); }
444 bool operator!=(const char *that) const { return !!compare(that); }
445 bool operator<( const char *that) const { return compare(that) < 0; }
446 bool operator>( const char *that) const { return compare(that) > 0; }
447 /** @} */
448
449 /** Max string offset value.
450 *
451 * When returned by a method, this indicates failure. When taken as input,
452 * typically a default, it means all the way to the string terminator.
453 */
454 static const size_t npos;
455
456 /**
457 * Find the given substring.
458 *
459 * Looks for pcszFind in "this" starting at "pos" and returns its position,
460 * counting from the beginning of "this" at 0.
461 *
462 * @param pcszFind The substring to find.
463 * @param pos The (byte) offset into the string buffer to start
464 * searching.
465 *
466 * @returns 0 based position of pcszFind. npos if not found.
467 */
468 size_t find(const char *pcszFind, size_t pos = 0) const;
469
470 /**
471 * Returns a substring of "this" as a new Utf8Str.
472 *
473 * Works exactly like its equivalent in std::string except that this interprets
474 * pos and n as unicode codepoints instead of bytes. With the default
475 * parameters "0" and "npos", this always copies the entire string.
476 *
477 * @param pos Index of first unicode codepoint to copy from
478 * "this", counting from 0.
479 * @param n Number of unicode codepoints to copy, starting with
480 * the one at "pos". The copying will stop if the null
481 * terminator is encountered before n codepoints have
482 * been copied.
483 *
484 * @remarks This works on code points, not bytes!
485 */
486 iprt::MiniString substr(size_t pos = 0, size_t n = npos) const;
487
488 /**
489 * Returns true if "this" ends with "that".
490 *
491 * @param that Suffix to test for.
492 * @param cs Case sensitivity selector.
493 * @returns true if match, false if mismatch.
494 */
495 bool endsWith(const iprt::MiniString &that, CaseSensitivity cs = CaseSensitive) const;
496
497 /**
498 * Returns true if "this" begins with "that".
499 * @param that Prefix to test for.
500 * @param cs Case sensitivity selector.
501 * @returns true if match, false if mismatch.
502 */
503 bool startsWith(const iprt::MiniString &that, CaseSensitivity cs = CaseSensitive) const;
504
505 /**
506 * Returns true if "this" contains "that" (strstr).
507 *
508 * @param that Substring to look for.
509 * @param cs Case sensitivity selector.
510 * @returns true if match, false if mismatch.
511 */
512 bool contains(const iprt::MiniString &that, CaseSensitivity cs = CaseSensitive) const;
513
514 /**
515 * Attempts to convert the member string into an 64-bit integer.
516 *
517 * @returns 64-bit unsigned number on success.
518 * @returns 0 on failure.
519 */
520 int64_t toInt64() const
521 {
522 return RTStrToInt64(m_psz);
523 }
524
525 /**
526 * Attempts to convert the member string into an unsigned 64-bit integer.
527 *
528 * @returns 64-bit unsigned number on success.
529 * @returns 0 on failure.
530 */
531 uint64_t toUInt64() const
532 {
533 return RTStrToUInt64(m_psz);
534 }
535
536 /**
537 * Attempts to convert the member string into an unsigned 64-bit integer.
538 *
539 * @param i Where to return the value on success.
540 * @returns IPRT error code, see RTStrToInt64.
541 */
542 int toInt(uint64_t &i) const;
543
544 /**
545 * Attempts to convert the member string into an unsigned 32-bit integer.
546 *
547 * @param i Where to return the value on success.
548 * @returns IPRT error code, see RTStrToInt32.
549 */
550 int toInt(uint32_t &i) const;
551
552protected:
553
554 /**
555 * Hide operator bool() to force people to use isEmpty() explicitly.
556 */
557 operator bool() const;
558
559 /**
560 * Destructor implementation, also used to clean up in operator=() before
561 * assigning a new string.
562 */
563 void cleanup()
564 {
565 if (m_psz)
566 {
567 RTStrFree(m_psz);
568 m_psz = NULL;
569 m_cbLength = 0;
570 m_cbAllocated = 0;
571 }
572 }
573
574 /**
575 * Protected internal helper to copy a string. This ignores the previous object
576 * state, so either call this from a constructor or call cleanup() first.
577 *
578 * copyFrom() unconditionally sets the members to a copy of the given other
579 * strings and makes no assumptions about previous contents. Can therefore be
580 * used both in copy constructors, when member variables have no defined value,
581 * and in assignments after having called cleanup().
582 *
583 * This variant copies from another MiniString and is fast since
584 * the length of the source string is known.
585 *
586 * @param s The source string.
587 *
588 * @throws std::bad_alloc On allocation failure. The object is left describing
589 * a NULL string.
590 */
591 void copyFrom(const MiniString &s)
592 {
593 if ((m_cbLength = s.m_cbLength))
594 {
595 m_cbAllocated = m_cbLength + 1;
596 m_psz = (char *)RTStrAlloc(m_cbAllocated);
597 if (RT_LIKELY(m_psz))
598 memcpy(m_psz, s.m_psz, m_cbAllocated); // include 0 terminator
599 else
600 {
601 m_cbLength = 0;
602 m_cbAllocated = 0;
603#ifdef RT_EXCEPTIONS_ENABLED
604 throw std::bad_alloc();
605#endif
606 }
607 }
608 else
609 {
610 m_cbAllocated = 0;
611 m_psz = NULL;
612 }
613 }
614
615 /**
616 * Protected internal helper to copy a string. This ignores the previous object
617 * state, so either call this from a constructor or call cleanup() first.
618 *
619 * See copyFrom() above.
620 *
621 * This variant copies from a C string and needs to call strlen()
622 * on it. It's therefore slower than the one above.
623 *
624 * @param pcsz The source string.
625 *
626 * @throws std::bad_alloc On allocation failure. The object is left describing
627 * a NULL string.
628 */
629 void copyFrom(const char *pcsz)
630 {
631 if (pcsz && *pcsz)
632 {
633 m_cbLength = strlen(pcsz);
634 m_cbAllocated = m_cbLength + 1;
635 m_psz = (char *)RTStrAlloc(m_cbAllocated);
636 if (RT_LIKELY(m_psz))
637 memcpy(m_psz, pcsz, m_cbAllocated); // include 0 terminator
638 else
639 {
640 m_cbLength = 0;
641 m_cbAllocated = 0;
642#ifdef RT_EXCEPTIONS_ENABLED
643 throw std::bad_alloc();
644#endif
645 }
646 }
647 else
648 {
649 m_cbLength = 0;
650 m_cbAllocated = 0;
651 m_psz = NULL;
652 }
653 }
654
655 char *m_psz; /**< The string buffer. */
656 size_t m_cbLength; /**< strlen(m_psz) - i.e. no terminator included. */
657 size_t m_cbAllocated; /**< Size of buffer that m_psz points to; at least m_cbLength + 1. */
658};
659
660} // namespace iprt
661
662#endif
663
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