VirtualBox

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

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

backing out r49709 to fix windows burns for now

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 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
310 operator bool() const { return !isNull(); }
311
312protected:
313 /**
314 * Destructor implementation, also used to clean up in operator=()
315 * before assigning a new string.
316 */
317 void cleanup()
318 {
319 if (m_psz)
320 {
321 RTMemFree(m_psz);
322 m_psz = NULL;
323 m_cbLength = 0;
324 m_cbAllocated = 0;
325 }
326 }
327
328 /**
329 * Protected internal helper.
330 * copyFrom() unconditionally sets the members to a copy of the
331 * given other strings and makes no assumptions about previous
332 * contents. Can therefore be used both in copy constructors,
333 * when member variables have no defined value, and in assignments
334 * after having called cleanup().
335 *
336 * This variant copies from another ministring and is fast since
337 * the length of source string is known.
338 *
339 * @param s
340 */
341 void copyFrom(const ministring &s)
342 {
343 if ((m_cbLength = s.m_cbLength))
344 {
345 m_cbAllocated = m_cbLength + 1;
346 m_psz = (char*)RTMemAlloc(m_cbAllocated);
347 memcpy(m_psz, s.m_psz, m_cbAllocated); // include 0 terminator
348 }
349 else
350 {
351 m_cbAllocated = 0;
352 m_psz = NULL;
353 }
354 }
355
356 /**
357 * Protected internal helper.
358 * See copyFrom() above.
359 *
360 * This variant copies from a C string and needs to call strlen()
361 * on it. It's therefore slower than the one above.
362 *
363 * @param pcsz
364 */
365 void copyFrom(const char *pcsz)
366 {
367 if (pcsz)
368 {
369 m_cbLength = strlen(pcsz);
370 m_cbAllocated = m_cbLength + 1;
371 m_psz = (char*)RTMemAlloc(m_cbAllocated);
372 memcpy(m_psz, pcsz, m_cbAllocated); // include 0 terminator
373 }
374 else
375 {
376 m_cbLength = 0;
377 m_cbAllocated = 0;
378 m_psz = NULL;
379 }
380 }
381
382 char *m_psz;
383 size_t m_cbLength; // strlen(m_psz)
384 size_t m_cbAllocated; // size of buffer that m_psz points to; at least m_cbLength + 1
385};
386
387#endif
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