VirtualBox

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

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

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