VirtualBox

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

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

Fixed a VCC warning.

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