VirtualBox

source: vbox/trunk/include/iprt/ministring_cpp.h@ 21399

Last change on this file since 21399 was 21394, checked in by vboxsync, 16 years ago

Backing out r49763 to fix Windows burns.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/** @file
2 * VirtualBox mini C++ string class. This is a base for both Utf8Str and
3 * other places where IPRT may want to use a lean C++ string class.
4 */
5
6/*
7 * Copyright (C) 2007-2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31#ifndef ___VBox_ministring_h
32#define ___VBox_ministring_h
33
34#include <iprt/mem.h>
35#include <iprt/string.h>
36
37/**
38 * "ministring" is a small C++ string class that does not depend on anything
39 * else except IPRT memory management functions. This is used as the base of
40 * both the Utf8Str class that COM uses as well as C++ code in IPRT that
41 * prefers to have a string class, like in xml.cpp.
42 *
43 * Semantics are like in std::string, except it can do a lot less.
44 *
45 * Much of the code in here used to be in com::Utf8Str so that com::Utf8Str
46 * can now derive from ministring and only contain code that is COM-specific,
47 * such as com::Bstr conversions. Compared to the old Utf8Str though, ministring
48 * always knows the length of its member string and the size of the buffer
49 * so it can use memcpy() instead of strdup().
50 */
51
52class RT_DECL_CLASS ministring
53{
54public:
55 /**
56 * Creates an empty string that has no memory allocated.
57 */
58 ministring()
59 : m_psz(NULL),
60 m_cbLength(0),
61 m_cbAllocated(0)
62 {
63 }
64
65 /**
66 * Creates a copy of another ministring. This allocates
67 * s.length() + 1 bytes for the new instance.
68 * @param s
69 */
70 ministring(const ministring &s)
71 {
72 copyFrom(s);
73 }
74
75 /**
76 * Creates a copy of another ministring. This allocates
77 * strlen(pcsz) + 1 bytes for the new instance.
78 * @param pcsz
79 */
80 ministring(const char *pcsz)
81 {
82 copyFrom(pcsz);
83 }
84
85 /**
86 * Destructor.
87 */
88 virtual ~ministring()
89 {
90 cleanup();
91 }
92
93 /**
94 * Returns the length of the member string. This is always cached
95 * so calling this is cheap and requires no strlen() invocation.
96 * @return
97 */
98 size_t length() const
99 {
100 return m_cbLength;
101 }
102
103 /**
104 * Returns the number of bytes allocated in the internal string buffer,
105 * which is at least length() + 1 if length() > 0.
106 * @return
107 */
108 size_t capacity() const
109 {
110 return m_cbAllocated;
111 }
112
113 /**
114 * Requests that the contained memory buffer have at least cb bytes allocated.
115 * This may expand or shrink the string's storage, but will never truncate the
116 * contained string. In other words, cb will be ignored if it's smaller than
117 * length() + 1.
118 * @param cb new minimum size of member memory buffer
119 */
120 void reserve(size_t cb)
121 {
122 if ( (cb != m_cbAllocated)
123 && (cb > m_cbLength + 1)
124 )
125 {
126 m_psz = (char*)RTMemRealloc(m_psz, cb);
127 m_cbAllocated = cb;
128 }
129 }
130
131 /**
132 * Deallocates all memory.
133 */
134 inline void setNull()
135 {
136 cleanup();
137 }
138
139 /**
140 * Returns a non-const raw pointer that allows to modify the string directly.
141 * @warning
142 * 1) Be sure not to modify data beyond the allocated memory! Call
143 * capacity() to find out how large that buffer is.
144 * 2) After any operation that modifies the length of the string,
145 * you _must_ call ministring::jolt(), or subsequent copy operations
146 * may go nowhere. Better not use mutableRaw() at all.
147 */
148 char* mutableRaw()
149 {
150 return m_psz;
151 }
152
153 /**
154 * Intended to be called after something has messed with the internal string
155 * buffer (e.g. after using mutableRaw() or Utf8Str::asOutParam()). Resets
156 * the internal lengths correctly. Otherwise subsequent copy operations may
157 * go nowhere.
158 */
159 void jolt()
160 {
161 if (m_psz)
162 {
163 m_cbLength = strlen(m_psz);
164 m_cbAllocated = m_cbLength + 1;
165 }
166 else
167 {
168 m_cbLength = 0;
169 m_cbAllocated = 0;
170 }
171 }
172
173 /**
174 * Assigns a copy of pcsz to "this".
175 * @param pcsz
176 * @return
177 */
178 ministring& operator=(const char *pcsz)
179 {
180 if (m_psz != pcsz)
181 {
182 cleanup();
183 copyFrom(pcsz);
184 }
185 return *this;
186 }
187
188 /**
189 * Assigns a copy of s to "this".
190 * @param s
191 * @return
192 */
193 ministring& operator=(const ministring &s)
194 {
195 if (this != &s)
196 {
197 cleanup();
198 copyFrom(s);
199 }
200 return *this;
201 }
202
203 /**
204 * Appends a copy of @a that to "this".
205 * @param that
206 */
207 void append(const ministring &that)
208 {
209 size_t cbThis = length();
210 size_t cbThat = that.length();
211
212 if (cbThat)
213 {
214 size_t cbBoth = cbThis + cbThat + 1;
215
216 reserve(cbBoth);
217 // calls realloc(cbBoth) and sets m_cbAllocated
218
219 memcpy(m_psz + cbThis, that.m_psz, cbThat);
220 m_psz[cbThis + cbThat] = '\0';
221 m_cbLength = cbBoth - 1;
222 }
223 }
224
225 /**
226 * Returns the contained string as a C-style const char* pointer.
227 * @return
228 */
229 inline const char* c_str() const
230 {
231 return m_psz;
232 }
233
234 /**
235 * Like c_str(), for compatibility with lots of VirtualBox Main code.
236 * @return
237 */
238 inline const char* raw() const
239 {
240 return m_psz;
241 }
242
243 /** Intended to to pass instances as input (|char *|) parameters to methods. */
244 inline operator const char*() const
245 {
246 return c_str();
247 }
248
249 /**
250 * Returns true if the member string has no length. This states nothing about
251 * how much memory might be allocated.
252 * @return
253 */
254 bool isEmpty() const
255 {
256 return length() == 0;
257 }
258
259 /**
260 * Returns true if no memory is currently allocated.
261 * @return
262 */
263 bool isNull() const
264 {
265 return m_psz == NULL;
266 }
267
268 enum CaseSensitivity
269 {
270 CaseSensitive,
271 CaseInsensitive
272 };
273
274 /**
275 * Compares the member string to pcsz.
276 * @param pcsz
277 * @param cs Whether comparison should be case-sensitive.
278 * @return
279 */
280 int compare(const char *pcsz, CaseSensitivity cs = CaseSensitive) const
281 {
282 if (m_psz == pcsz)
283 return 0;
284 if (m_psz == NULL)
285 return -1;
286 if (pcsz == NULL)
287 return 1;
288
289 if (cs == CaseSensitive)
290 return ::RTStrCmp(m_psz, pcsz);
291 else
292 return ::RTStrICmp(m_psz, pcsz);
293 }
294
295 int compare(const ministring &that, CaseSensitivity cs = CaseSensitive) const
296 {
297 return compare(that.m_psz, cs);
298 }
299
300 bool operator==(const ministring &that) const { return !compare(that); }
301 bool operator!=(const ministring &that) const { return !!compare(that); }
302 bool operator<(const ministring &that) const { return compare(that) < 0; }
303 bool operator>(const ministring &that) const { return compare(that) > 0; }
304
305 bool operator==(const char *that) const { return !compare(that); }
306 bool operator!=(const char *that) const { return !!compare(that); }
307 bool operator<(const char *that) const { return compare(that) < 0; }
308 bool operator>(const char *that) const { return compare(that) > 0; }
309
310protected:
311
312 /**
313 * Hide operator bool() to force people to use isEmpty() explicitly.
314 */
315 operator bool() const { return false; }
316
317 /**
318 * Destructor implementation, also used to clean up in operator=()
319 * before assigning a new string.
320 */
321 void cleanup()
322 {
323 if (m_psz)
324 {
325 RTMemFree(m_psz);
326 m_psz = NULL;
327 m_cbLength = 0;
328 m_cbAllocated = 0;
329 }
330 }
331
332 /**
333 * Protected internal helper.
334 * copyFrom() unconditionally sets the members to a copy of the
335 * given other strings and makes no assumptions about previous
336 * contents. Can therefore be used both in copy constructors,
337 * when member variables have no defined value, and in assignments
338 * after having called cleanup().
339 *
340 * This variant copies from another ministring and is fast since
341 * the length of source string is known.
342 *
343 * @param s
344 */
345 void copyFrom(const ministring &s)
346 {
347 if ((m_cbLength = s.m_cbLength))
348 {
349 m_cbAllocated = m_cbLength + 1;
350 m_psz = (char*)RTMemAlloc(m_cbAllocated);
351 memcpy(m_psz, s.m_psz, m_cbAllocated); // include 0 terminator
352 }
353 else
354 {
355 m_cbAllocated = 0;
356 m_psz = NULL;
357 }
358 }
359
360 /**
361 * Protected internal helper.
362 * See copyFrom() above.
363 *
364 * This variant copies from a C string and needs to call strlen()
365 * on it. It's therefore slower than the one above.
366 *
367 * @param pcsz
368 */
369 void copyFrom(const char *pcsz)
370 {
371 if (pcsz)
372 {
373 m_cbLength = strlen(pcsz);
374 m_cbAllocated = m_cbLength + 1;
375 m_psz = (char*)RTMemAlloc(m_cbAllocated);
376 memcpy(m_psz, pcsz, m_cbAllocated); // include 0 terminator
377 }
378 else
379 {
380 m_cbLength = 0;
381 m_cbAllocated = 0;
382 m_psz = NULL;
383 }
384 }
385
386 char *m_psz;
387 size_t m_cbLength; // strlen(m_psz)
388 size_t m_cbAllocated; // size of buffer that m_psz points to; at least m_cbLength + 1
389};
390
391#endif
Note: See TracBrowser for help on using the repository browser.

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