VirtualBox

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

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

fixed potential uninitialized member of ministring

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 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 Utf8Str so that Utf8Str can now
46 * derive from ministring and only contain code that is COM-specific, such
47 * 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 ministring()
56 : m_psz(NULL),
57 m_cbLength(0),
58 m_cbAllocated(0)
59 {
60 }
61
62 ministring(const ministring &s)
63 : m_psz(NULL)
64 {
65 copyFrom(s);
66 }
67
68 ministring(const char *pcsz)
69 : m_psz(NULL)
70 {
71 copyFrom(pcsz);
72 }
73
74 virtual ~ministring()
75 {
76 cleanup();
77 }
78
79 size_t length() const
80 {
81 return m_cbLength;
82 }
83
84 /**
85 * Returns the no. of bytes allocated in the internal string buffer,
86 * which is at least m_cbLength + 1 if m_cbLength != 0.
87 * @return
88 */
89 size_t capacity() const
90 {
91 return m_cbAllocated;
92 }
93
94 /**
95 * Requests that the contained memory buffer have at least cb bytes allocated.
96 * This may expand or shrink the string's storage, but will never truncate the
97 * contained string.
98 * @param cb new minimum size of member memory buffer
99 */
100 void reserve(size_t cb)
101 {
102 if ( (cb != m_cbAllocated)
103 && (cb > m_cbLength + 1)
104 )
105 {
106 m_psz = (char*)RTMemRealloc(m_psz, cb);
107 m_cbAllocated = cb;
108 }
109 }
110
111 inline void setNull()
112 {
113 cleanup();
114 }
115
116 /**
117 * Returns a non-const raw pointer that allows to modify the string directly.
118 * @warning
119 * 1) Be sure not to modify data beyond the allocated memory! Call
120 * capacity() to find out how large that buffer is.
121 * 2) After any operation that modifies the length of the string,
122 * you _must_ call ministring::jolt(), or subsequent copy operations
123 * may go nowhere. Better not use mutableRaw() at all.
124 */
125 char* mutableRaw()
126 {
127 return m_psz;
128 }
129
130 /**
131 * Intended to be called after something has messed with the internal string
132 * buffer (e.g. after using mutableRaw() or Utf8Str::asOutParam()). Resets
133 * the internal lengths correctly. Otherwise subsequent copy operations may
134 * go nowhere.
135 */
136 void jolt()
137 {
138 if (m_psz)
139 {
140 m_cbLength = strlen(m_psz);
141 m_cbAllocated = m_cbLength + 1;
142 }
143 else
144 {
145 m_cbLength = 0;
146 m_cbAllocated = 0;
147 }
148 }
149
150 ministring& operator=(const char *pcsz)
151 {
152 cleanup();
153 copyFrom(pcsz);
154 return *this;
155 }
156
157 ministring& operator=(const ministring &s)
158 {
159 cleanup();
160 copyFrom(s);
161 return *this;
162 }
163
164 void append(const ministring &that)
165 {
166 size_t cbThis = length();
167 size_t cbThat = that.length();
168
169 if (cbThat)
170 {
171 size_t cbBoth = cbThis + cbThat + 1;
172
173 reserve(cbBoth);
174 // calls realloc(cbBoth) and sets m_cbAllocated
175
176 memcpy(m_psz + cbThis, that.m_psz, cbThat);
177 m_psz[cbThis + cbThat] = '\0';
178 m_cbLength = cbBoth - 1;
179 }
180 }
181
182 inline const char* c_str() const
183 {
184 return m_psz;
185 }
186
187 inline const char* raw() const
188 {
189 return m_psz;
190 }
191
192 /** Intended to to pass instances as input (|char *|) parameters to methods. */
193 inline operator const char*() const
194 {
195 return c_str();
196 }
197
198 bool isEmpty() const
199 {
200 return length() == 0;
201 }
202
203 bool isNull() const
204 {
205 return m_psz == NULL;
206 }
207
208 enum CaseSensitivity
209 {
210 CaseSensitive,
211 CaseInsensitive
212 };
213
214 int compare(const char *pcsz, CaseSensitivity cs = CaseSensitive) const
215 {
216 if (m_psz == pcsz)
217 return 0;
218 if (m_psz == NULL)
219 return -1;
220 if (pcsz == NULL)
221 return 1;
222
223 if (cs == CaseSensitive)
224 return ::RTStrCmp(m_psz, pcsz);
225 else
226 return ::RTStrICmp(m_psz, pcsz);
227 }
228
229 int compare(const ministring &that, CaseSensitivity cs = CaseSensitive) const
230 {
231 return compare(that.m_psz, cs);
232 }
233
234 bool operator==(const ministring &that) const { return !compare(that); }
235 bool operator!=(const ministring &that) const { return !!compare(that); }
236 bool operator<(const ministring &that) const { return compare(that) < 0; }
237 bool operator>(const ministring &that) const { return compare(that) > 0; }
238
239 bool operator==(const char *that) const { return !compare(that); }
240 bool operator!=(const char *that) const { return !!compare(that); }
241 bool operator<(const char *that) const { return compare(that) < 0; }
242 bool operator>(const char *that) const { return compare(that) > 0; }
243
244protected:
245 /**
246 * Destructor implementation, also used to clean up in operator=()
247 * before assigning a new string.
248 */
249 void cleanup()
250 {
251 if (m_psz)
252 {
253 RTMemFree(m_psz);
254 m_psz = NULL;
255 m_cbLength = 0;
256 m_cbAllocated = 0;
257 }
258 }
259
260 /**
261 * copyFrom() unconditionally sets the members to a copy of the
262 * given other strings and makes no assumptions about previous
263 * contents. Can therefore be used both in copy constructors,
264 * when member variables have no defined value, and in assignments
265 * after having called cleanup().
266 *
267 * This variant copies from another ministring and is fast since
268 * the length of source string is known.
269 *
270 * @param s
271 */
272 void copyFrom(const ministring &s)
273 {
274 if (&s != this)
275 {
276 m_cbLength = s.m_cbLength;
277 m_cbAllocated = m_cbLength + 1;
278 m_psz = (char*)RTMemAlloc(m_cbAllocated);
279 memcpy(m_psz, s.m_psz, m_cbAllocated); // include 0 terminator
280 }
281 }
282
283 /**
284 * See copyFrom() above.
285 *
286 * This variant copies from a C string and needs to call strlen()
287 * on it. It's therefore slower than the one above.
288 *
289 * @param pcsz
290 */
291 void copyFrom(const char *pcsz)
292 {
293 if (pcsz != m_psz) // leaves NULL as NULL also
294 {
295 if (pcsz)
296 {
297 m_cbLength = strlen(pcsz);
298 m_cbAllocated = m_cbLength + 1;
299 m_psz = (char*)RTMemAlloc(m_cbAllocated);
300 memcpy(m_psz, pcsz, m_cbAllocated); // include 0 terminator
301 }
302 else
303 {
304 m_cbLength = 0;
305 m_cbAllocated = 0;
306 m_psz = NULL;
307 }
308 }
309 }
310
311 char *m_psz;
312 size_t m_cbLength; // strlen(m_psz)
313 size_t m_cbAllocated; // size of buffer that m_psz points to; at least m_cbLength + 1
314};
315
316#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