VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/ministring.cpp@ 31157

Last change on this file since 31157 was 30318, checked in by vboxsync, 14 years ago

iprt/cpp/ministring.h: Added a append variant taking a 'const char *' argument to avoid the unnecessary duplication of constant strings. (tstUtf8.cpp: Dropped some of the lisping.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: ministring.cpp 30318 2010-06-21 07:49:28Z vboxsync $ */
2/** @file
3 * IPRT - Mini C++ string class.
4 *
5 * This is a base for both Utf8Str and other places where IPRT may want to use
6 * a lean C++ string class.
7 */
8
9/*
10 * Copyright (C) 2007-2009 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
25 *
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
28 */
29
30#include <iprt/cpp/ministring.h>
31
32using namespace iprt;
33
34const size_t MiniString::npos = ~(size_t)0;
35
36MiniString &MiniString::append(const MiniString &that)
37{
38 size_t lenThat = that.length();
39 if (lenThat)
40 {
41 size_t lenThis = length();
42 size_t cbBoth = lenThis + lenThat + 1;
43
44 reserve(cbBoth);
45 // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
46#ifndef RT_EXCEPTIONS_ENABLED
47 AssertRelease(capacity() >= cbBoth);
48#endif
49
50 memcpy(m_psz + lenThis, that.m_psz, lenThat);
51 m_psz[lenThis + lenThat] = '\0';
52 m_cbLength = cbBoth - 1;
53 }
54 return *this;
55}
56
57MiniString &MiniString::append(const char *pszThat)
58{
59 size_t cchThat = strlen(pszThat);
60 if (cchThat)
61 {
62 size_t cchThis = length();
63 size_t cbBoth = cchThis + cchThat + 1;
64
65 reserve(cbBoth);
66 // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
67#ifndef RT_EXCEPTIONS_ENABLED
68 AssertRelease(capacity() >= cbBoth);
69#endif
70
71 memcpy(m_psz + cchThis, pszThat, cchThat);
72 m_psz[cbBoth - 1] = '\0';
73 m_cbLength = cbBoth - 1;
74 }
75 return *this;
76}
77
78MiniString& MiniString::append(char c)
79{
80 if (c)
81 {
82 // allocate in chunks of 20 in case this gets called several times
83 if (m_cbLength + 1 >= m_cbAllocated)
84 {
85 reserve(m_cbLength + 10);
86 // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
87#ifndef RT_EXCEPTIONS_ENABLED
88 AssertRelease(capacity() >= m_cbLength + 1);
89#endif
90 }
91
92 m_psz[m_cbLength] = c;
93 m_psz[m_cbLength + 1] = '\0';
94 ++m_cbLength;
95 }
96 return *this;
97}
98
99size_t MiniString::find(const char *pcszFind, size_t pos /*= 0*/)
100 const
101{
102 const char *pszThis, *p;
103
104 if ( ((pszThis = c_str()))
105 && (pos < length())
106 && ((p = strstr(pszThis + pos, pcszFind)))
107 )
108 return p - pszThis;
109
110 return npos;
111}
112
113MiniString MiniString::substr(size_t pos /*= 0*/, size_t n /*= npos*/)
114 const
115{
116 MiniString ret;
117
118 if (n)
119 {
120 const char *psz;
121
122 if ((psz = c_str()))
123 {
124 RTUNICP cp;
125
126 // walk the UTF-8 characters until where the caller wants to start
127 size_t i = pos;
128 while (*psz && i--)
129 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
130 return ret; // return empty string on bad encoding
131
132 const char *pFirst = psz;
133
134 if (n == npos)
135 // all the rest:
136 ret = pFirst;
137 else
138 {
139 i = n;
140 while (*psz && i--)
141 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
142 return ret; // return empty string on bad encoding
143
144 size_t cbCopy = psz - pFirst;
145 ret.reserve(cbCopy + 1); // may throw bad_alloc
146#ifndef RT_EXCEPTIONS_ENABLED
147 AssertRelease(capacity() >= cbCopy + 1);
148#endif
149 memcpy(ret.m_psz, pFirst, cbCopy);
150 ret.m_cbLength = cbCopy;
151 ret.m_psz[cbCopy] = '\0';
152 }
153 }
154 }
155
156 return ret;
157}
158
159bool MiniString::endsWith(const MiniString &that, CaseSensitivity cs /*= CaseSensitive*/) const
160{
161 size_t l1 = length();
162 if (l1 == 0)
163 return false;
164
165 size_t l2 = that.length();
166 if (l1 < l2)
167 return false;
168 /** @todo r=bird: If l2 is 0, then m_psz can be NULL and we will crash. See
169 * also handling of l2 == in startsWith. */
170
171 size_t l = l1 - l2;
172 if (cs == CaseSensitive)
173 return ::RTStrCmp(&m_psz[l], that.m_psz) == 0;
174 else
175 return ::RTStrICmp(&m_psz[l], that.m_psz) == 0;
176}
177
178bool MiniString::startsWith(const MiniString &that, CaseSensitivity cs /*= CaseSensitive*/) const
179{
180 size_t l1 = length();
181 size_t l2 = that.length();
182 if (l1 == 0 || l2 == 0) /** @todo r=bird: this differs from endsWith, and I think other IPRT code. If l2 == 0, it matches anything. */
183 return false;
184
185 if (l1 < l2)
186 return false;
187
188 if (cs == CaseSensitive)
189 return ::RTStrNCmp(m_psz, that.m_psz, l2) == 0;
190 else
191 return ::RTStrNICmp(m_psz, that.m_psz, l2) == 0;
192}
193
194bool MiniString::contains(const MiniString &that, CaseSensitivity cs /*= CaseSensitive*/) const
195{
196 /** @todo r-bird: Not checking for NULL strings like startsWith does (and
197 * endsWith only does half way). */
198 if (cs == CaseSensitive)
199 return ::RTStrStr(m_psz, that.m_psz) != NULL;
200 else
201 return ::RTStrIStr(m_psz, that.m_psz) != NULL;
202}
203
204int MiniString::toInt(uint64_t &i) const
205{
206 if (!m_psz)
207 return VERR_NO_DIGITS;
208 return RTStrToUInt64Ex(m_psz, NULL, 0, &i);
209}
210
211int MiniString::toInt(uint32_t &i) const
212{
213 if (!m_psz)
214 return VERR_NO_DIGITS;
215 return RTStrToUInt32Ex(m_psz, NULL, 0, &i);
216}
217
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