VirtualBox

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

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

export to OSE

  • 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 cleanup();
151 copyFrom(pcsz);
152 return *this;
153 }
154
155 ministring& operator=(const ministring &s)
156 {
157 cleanup();
158 copyFrom(s);
159 return *this;
160 }
161
162 void append(const ministring &that)
163 {
164 size_t cbThis = length();
165 size_t cbThat = that.length();
166
167 if (cbThat)
168 {
169 size_t cbBoth = cbThis + cbThat + 1;
170
171 reserve(cbBoth);
172 // calls realloc(cbBoth) and sets m_cbAllocated
173
174 memcpy(m_psz + cbThis, that.m_psz, cbThat);
175 m_psz[cbThis + cbThat] = '\0';
176 m_cbLength = cbBoth - 1;
177 }
178 }
179
180 inline const char* c_str() const
181 {
182 return m_psz;
183 }
184
185 inline const char* raw() const
186 {
187 return m_psz;
188 }
189
190 /** Intended to to pass instances as input (|char *|) parameters to methods. */
191 inline operator const char*() const
192 {
193 return c_str();
194 }
195
196 bool isEmpty() const
197 {
198 return length() == 0;
199 }
200
201 bool isNull() const
202 {
203 return m_psz == NULL;
204 }
205
206 enum CaseSensitivity
207 {
208 CaseSensitive,
209 CaseInsensitive
210 };
211
212 int compare(const char *pcsz, CaseSensitivity cs = CaseSensitive) const
213 {
214 if (m_psz == pcsz)
215 return 0;
216 if (m_psz == NULL)
217 return -1;
218 if (pcsz == NULL)
219 return 1;
220
221 if (cs == CaseSensitive)
222 return ::RTStrCmp(m_psz, pcsz);
223 else
224 return ::RTStrICmp(m_psz, pcsz);
225 }
226
227 int compare(const ministring &that, CaseSensitivity cs = CaseSensitive) const
228 {
229 return compare(that.m_psz, cs);
230 }
231
232 bool operator==(const ministring &that) const { return !compare(that); }
233 bool operator!=(const ministring &that) const { return !!compare(that); }
234 bool operator<(const ministring &that) const { return compare(that) < 0; }
235 bool operator>(const ministring &that) const { return compare(that) > 0; }
236
237 bool operator==(const char *that) const { return !compare(that); }
238 bool operator!=(const char *that) const { return !!compare(that); }
239 bool operator<(const char *that) const { return compare(that) < 0; }
240 bool operator>(const char *that) const { return compare(that) > 0; }
241
242protected:
243 /**
244 * Destructor implementation, also used to clean up in operator=()
245 * before assigning a new string.
246 */
247 void cleanup()
248 {
249 if (m_psz)
250 {
251 RTMemFree(m_psz);
252 m_psz = NULL;
253 m_cbLength = 0;
254 m_cbAllocated = 0;
255 }
256 }
257
258 /**
259 * copyFrom() unconditionally sets the members to a copy of the
260 * given other strings and makes no assumptions about previous
261 * contents. Can therefore be used both in copy constructors,
262 * when member variables have no defined value, and in assignments
263 * after having called cleanup().
264 *
265 * This variant copies from another ministring and is fast since
266 * the length of source string is known.
267 *
268 * @param s
269 */
270 void copyFrom(const ministring &s)
271 {
272 if (&s != this)
273 {
274 m_cbLength = s.m_cbLength;
275 m_cbAllocated = m_cbLength + 1;
276 m_psz = (char*)RTMemAlloc(m_cbAllocated);
277 memcpy(m_psz, s.m_psz, m_cbAllocated); // include 0 terminator
278 }
279 }
280
281 /**
282 * See copyFrom() above.
283 *
284 * This variant copies from a C string and needs to call strlen()
285 * on it. It's therefore slower than the one above.
286 *
287 * @param pcsz
288 */
289 void copyFrom(const char *pcsz)
290 {
291 if (pcsz != m_psz) // leaves NULL as NULL also
292 {
293 if (pcsz)
294 {
295 m_cbLength = strlen(pcsz);
296 m_cbAllocated = m_cbLength + 1;
297 m_psz = (char*)RTMemAlloc(m_cbAllocated);
298 memcpy(m_psz, pcsz, m_cbAllocated); // include 0 terminator
299 }
300 else
301 {
302 m_cbLength = 0;
303 m_cbAllocated = 0;
304 m_psz = NULL;
305 }
306 }
307 }
308
309 char *m_psz;
310 size_t m_cbLength; // strlen(m_psz)
311 size_t m_cbAllocated; // size of buffer that m_psz points to; at least m_cbLength + 1
312};
313
314#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