VirtualBox

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

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

iprt/ministring_cpp.h -> iprt/cpp/ministring.h

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