VirtualBox

source: vbox/trunk/src/VBox/Main/glue/string.cpp@ 21529

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

Main: fix length after substr

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1/* $Id: string.cpp 21529 2009-07-13 11:57:28Z vboxsync $ */
2
3/** @file
4 *
5 * MS COM / XPCOM Abstraction Layer:
6 * Smart string classes definition
7 */
8
9/*
10 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.215389.xyz. 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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
21 * Clara, CA 95054 USA or visit http://www.sun.com if you need
22 * additional information or have any questions.
23 */
24
25#include "VBox/com/string.h"
26
27#include <iprt/err.h>
28#include <iprt/path.h>
29
30namespace com
31{
32
33/* static */
34const Bstr Bstr::Null; /* default ctor is OK */
35
36/* static */
37const Utf8Str Utf8Str::Null; /* default ctor is OK */
38
39const size_t Utf8Str::npos = (size_t)-1;
40
41size_t Utf8Str::find(const char *pcszFind,
42 size_t pos /*= 0*/)
43 const
44{
45 const char *pszThis, *p;
46
47 if ( ((pszThis = c_str()))
48 && (pos < length())
49 && ((p = strstr(pszThis + pos, pcszFind)))
50 )
51 return p - pszThis;
52
53 return npos;
54}
55
56Utf8Str Utf8Str::substr(size_t pos /*= 0*/, size_t n /*= npos*/)
57 const
58{
59 Utf8Str ret;
60
61 if (n)
62 {
63 const char *psz;
64
65 if ((psz = c_str()))
66 {
67 RTUNICP cp;
68
69 // walk the UTF-8 characters until where the caller wants to start
70 size_t i = pos;
71 while (*psz && i--)
72 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
73 return ret; // return empty string on bad encoding
74
75 const char *pFirst = psz;
76
77 if (n == npos)
78 // all the rest:
79 ret = pFirst;
80 else
81 {
82 i = n;
83 while (*psz && i--)
84 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
85 return ret; // return empty string on bad encoding
86
87 size_t cbCopy = psz - pFirst;
88 ret.reserve(cbCopy + 1);
89 memcpy(ret.m_psz, pFirst, cbCopy);
90 ret.m_cbLength = cbCopy;
91 ret.m_psz[cbCopy] = '\0';
92 }
93 }
94 }
95
96 return ret;
97}
98
99bool Utf8Str::endsWith(const Utf8Str &that, CaseSensitivity cs /*= CaseSensitive*/) const
100{
101 size_t l1 = length();
102 if (l1 == 0)
103 return false;
104
105 size_t l2 = that.length();
106 if (l1 < l2)
107 return false;
108
109 size_t l = l1 - l2;
110 if (cs == CaseSensitive)
111 return ::RTStrCmp(&m_psz[l], that.m_psz) == 0;
112 else
113 return ::RTStrICmp(&m_psz[l], that.m_psz) == 0;
114}
115
116bool Utf8Str::startsWith(const Utf8Str &that, CaseSensitivity cs /*= CaseSensitive*/) const
117{
118 size_t l1 = length();
119 size_t l2 = that.length();
120 if (l1 == 0 || l2 == 0)
121 return false;
122
123 if (l1 < l2)
124 return false;
125
126 if (cs == CaseSensitive)
127 return ::RTStrNCmp(m_psz, that.m_psz, l2) == 0;
128 else
129 return ::RTStrNICmp(m_psz, that.m_psz, l2) == 0;
130}
131
132bool Utf8Str::contains(const Utf8Str &that, CaseSensitivity cs /*= CaseSensitive*/) const
133{
134 if (cs == CaseSensitive)
135 return ::RTStrStr(m_psz, that.m_psz) != NULL;
136 else
137 return ::RTStrIStr(m_psz, that.m_psz) != NULL;
138}
139
140Utf8Str& Utf8Str::toLower()
141{
142 if (length())
143 ::RTStrToLower(m_psz);
144 return *this;
145}
146
147Utf8Str& Utf8Str::toUpper()
148{
149 if (length())
150 ::RTStrToUpper(m_psz);
151 return *this;
152}
153
154void Utf8Str::stripTrailingSlash()
155{
156 RTPathStripTrailingSlash(m_psz);
157 jolt();
158}
159
160void Utf8Str::stripFilename()
161{
162 RTPathStripFilename(m_psz);
163 jolt();
164}
165
166void Utf8Str::stripExt()
167{
168 RTPathStripExt(m_psz);
169 jolt();
170}
171
172int Utf8Str::toInt(uint64_t &i) const
173{
174 if (!m_psz)
175 return VERR_NO_DIGITS;
176 return RTStrToUInt64Ex(m_psz, NULL, 0, &i);
177}
178
179int Utf8Str::toInt(uint32_t &i) const
180{
181 if (!m_psz)
182 return VERR_NO_DIGITS;
183 return RTStrToUInt32Ex(m_psz, NULL, 0, &i);
184}
185
186struct FormatData
187{
188 static const size_t CacheIncrement = 256;
189 size_t size;
190 size_t pos;
191 char *cache;
192};
193
194void Utf8StrFmt::init (const char *format, va_list args)
195{
196 if (!format)
197 return;
198
199 // assume an extra byte for a terminating zero
200 size_t fmtlen = strlen (format) + 1;
201
202 FormatData data;
203 data.size = FormatData::CacheIncrement;
204 if (fmtlen >= FormatData::CacheIncrement)
205 data.size += fmtlen;
206 data.pos = 0;
207 data.cache = (char *) ::RTMemTmpAllocZ (data.size);
208
209 size_t n = ::RTStrFormatV (strOutput, &data, NULL, NULL, format, args);
210
211 AssertMsg (n == data.pos,
212 ("The number of bytes formatted doesn't match: %d and %d!",
213 n, data.pos));
214 NOREF (n);
215
216 // finalize formatting
217 data.cache [data.pos] = 0;
218 (*static_cast <Utf8Str *> (this)) = data.cache;
219 ::RTMemTmpFree (data.cache);
220}
221
222// static
223DECLCALLBACK(size_t) Utf8StrFmt::strOutput (void *pvArg, const char *pachChars,
224 size_t cbChars)
225{
226 Assert (pvArg);
227 FormatData &data = *(FormatData *) pvArg;
228
229 if (!(pachChars == NULL && cbChars == 0))
230 {
231 Assert (pachChars);
232
233 // append to cache (always assume an extra byte for a terminating zero)
234 size_t needed = cbChars + 1;
235 if (data.pos + needed > data.size)
236 {
237 data.size += FormatData::CacheIncrement;
238 if (needed >= FormatData::CacheIncrement)
239 data.size += needed;
240 data.cache = (char *) ::RTMemRealloc (data.cache, data.size);
241 }
242 strncpy (data.cache + data.pos, pachChars, cbChars);
243 data.pos += cbChars;
244 }
245
246 return cbChars;
247}
248
249
250} /* namespace com */
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