VirtualBox

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

Last change on this file since 26550 was 26550, checked in by vboxsync, 15 years ago

Main: Bstr makeover -- make Bstr(NULL) and Bstr() behave the same; resulting cleanup; make some more internal methods use Utf8Str instead of Bstr; fix a lot of CheckComArgNotNull() usage

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