VirtualBox

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

Last change on this file since 43446 was 42570, checked in by vboxsync, 12 years ago

com/string.h: Added assignEx methods similar to cloneEx that returns HRESULT instead of exceptions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1/* $Id: string.cpp 42570 2012-08-03 09:56:09Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer - UTF-8 and UTF-16 string classes.
4 */
5
6/*
7 * Copyright (C) 2006-2011 Oracle Corporation
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
18#include "VBox/com/string.h"
19
20#include <iprt/err.h>
21#include <iprt/path.h>
22#include <iprt/log.h>
23
24namespace com
25{
26
27// BSTR representing a null wide char with 32 bits of length prefix (0);
28// this will work on Windows as well as other platforms where BSTR does
29// not use length prefixes
30const OLECHAR g_achEmptyBstr[3] = { 0, 0, 0 };
31const BSTR g_bstrEmpty = (BSTR)&g_achEmptyBstr[2];
32
33/* static */
34const Bstr Bstr::Empty; /* default ctor is OK */
35
36void Bstr::copyFromN(const char *a_pszSrc, size_t a_cchMax)
37{
38 /*
39 * Initialie m_bstr first in case of throws further down in the code, then
40 * check for empty input (m_bstr == NULL means empty, there are no NULL
41 * strings).
42 */
43 m_bstr = NULL;
44 if (!a_cchMax || !a_pszSrc || !*a_pszSrc)
45 return;
46
47 /*
48 * Calculate the length and allocate a BSTR string buffer of the right
49 * size, i.e. optimize heap usage.
50 */
51 size_t cwc;
52 int vrc = ::RTStrCalcUtf16LenEx(a_pszSrc, a_cchMax, &cwc);
53 if (RT_FAILURE(vrc))
54 {
55 /* ASSUME: input is valid Utf-8. Fake out of memory error. */
56 AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTStrNLen(a_pszSrc, a_cchMax), a_pszSrc));
57 throw std::bad_alloc();
58 }
59
60 m_bstr = ::SysAllocStringByteLen(NULL, cwc * sizeof(OLECHAR));
61 if (RT_UNLIKELY(!m_bstr))
62 throw std::bad_alloc();
63
64 PRTUTF16 pwsz = (PRTUTF16)m_bstr;
65 vrc = ::RTStrToUtf16Ex(a_pszSrc, a_cchMax, &pwsz, cwc + 1, NULL);
66 if (RT_FAILURE(vrc))
67 {
68 /* This should not happen! */
69 AssertRC(vrc);
70 cleanup();
71 throw std::bad_alloc();
72 }
73}
74
75
76/* static */
77const Utf8Str Utf8Str::Empty; /* default ctor is OK */
78
79#if defined(VBOX_WITH_XPCOM)
80void Utf8Str::cloneTo(char **pstr) const
81{
82 size_t cb = length() + 1;
83 *pstr = (char*)nsMemory::Alloc(cb);
84 if (RT_UNLIKELY(!*pstr))
85 throw std::bad_alloc();
86 memcpy(*pstr, c_str(), cb);
87}
88
89HRESULT Utf8Str::cloneToEx(char **pstr) const
90{
91 size_t cb = length() + 1;
92 *pstr = (char*)nsMemory::Alloc(cb);
93 if (RT_UNLIKELY(!*pstr))
94 return E_OUTOFMEMORY;
95 memcpy(*pstr, c_str(), cb);
96 return S_OK;
97}
98#endif
99
100Utf8Str& Utf8Str::stripTrailingSlash()
101{
102 if (length())
103 {
104 ::RTPathStripTrailingSlash(m_psz);
105 jolt();
106 }
107 return *this;
108}
109
110Utf8Str& Utf8Str::stripFilename()
111{
112 if (length())
113 {
114 RTPathStripFilename(m_psz);
115 jolt();
116 }
117 return *this;
118}
119
120Utf8Str& Utf8Str::stripPath()
121{
122 if (length())
123 {
124 char *pszName = ::RTPathFilename(m_psz);
125 if (pszName)
126 {
127 size_t cchName = length() - (pszName - m_psz);
128 memmove(m_psz, pszName, cchName + 1);
129 jolt();
130 }
131 else
132 cleanup();
133 }
134 return *this;
135}
136
137Utf8Str& Utf8Str::stripExt()
138{
139 if (length())
140 {
141 RTPathStripExt(m_psz);
142 jolt();
143 }
144 return *this;
145}
146
147/**
148 * Internal function used in Utf8Str copy constructors and assignment when
149 * copying from a UTF-16 string.
150 *
151 * As with the RTCString::copyFrom() variants, this unconditionally sets the
152 * members to a copy of the given other strings and makes no assumptions about
153 * previous contents. This can therefore be used both in copy constructors,
154 * when member variables have no defined value, and in assignments after having
155 * called cleanup().
156 *
157 * This variant converts from a UTF-16 string, most probably from
158 * a Bstr assignment.
159 *
160 * @param a_pbstr The source string. The caller guarantees that this
161 * is valid UTF-16.
162 *
163 * @sa RTCString::copyFromN
164 */
165void Utf8Str::copyFrom(CBSTR a_pbstr)
166{
167 if (a_pbstr && *a_pbstr)
168 {
169 int vrc = RTUtf16ToUtf8Ex((PCRTUTF16)a_pbstr,
170 RTSTR_MAX, // size_t cwcString: translate entire string
171 &m_psz, // char **ppsz: output buffer
172 0, // size_t cch: if 0, func allocates buffer in *ppsz
173 &m_cch); // size_t *pcch: receives the size of the output string, excluding the terminator.
174 if (RT_SUCCESS(vrc))
175 m_cbAllocated = m_cch + 1;
176 else
177 {
178 if ( vrc != VERR_NO_STR_MEMORY
179 && vrc != VERR_NO_MEMORY)
180 {
181 /* ASSUME: input is valid Utf-16. Fake out of memory error. */
182 AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTUtf16Len(a_pbstr) * sizeof(RTUTF16), a_pbstr));
183 }
184
185 m_cch = 0;
186 m_cbAllocated = 0;
187 m_psz = NULL;
188
189 throw std::bad_alloc();
190 }
191 }
192 else
193 {
194 m_cch = 0;
195 m_cbAllocated = 0;
196 m_psz = NULL;
197 }
198}
199
200/**
201 * A variant of Utf8Str::copyFrom that does not throw any exceptions but returns
202 * E_OUTOFMEMORY instead.
203 *
204 * @param a_pbstr The source string.
205 * @returns S_OK or E_OUTOFMEMORY.
206 */
207HRESULT Utf8Str::copyFromEx(CBSTR a_pbstr)
208{
209 if (a_pbstr && *a_pbstr)
210 {
211 int vrc = RTUtf16ToUtf8Ex((PCRTUTF16)a_pbstr,
212 RTSTR_MAX, // size_t cwcString: translate entire string
213 &m_psz, // char **ppsz: output buffer
214 0, // size_t cch: if 0, func allocates buffer in *ppsz
215 &m_cch); // size_t *pcch: receives the size of the output string, excluding the terminator.
216 if (RT_SUCCESS(vrc))
217 m_cbAllocated = m_cch + 1;
218 else
219 {
220 if ( vrc != VERR_NO_STR_MEMORY
221 && vrc != VERR_NO_MEMORY)
222 {
223 /* ASSUME: input is valid Utf-16. Fake out of memory error. */
224 AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTUtf16Len(a_pbstr) * sizeof(RTUTF16), a_pbstr));
225 }
226
227 m_cch = 0;
228 m_cbAllocated = 0;
229 m_psz = NULL;
230
231 return E_OUTOFMEMORY;
232 }
233 }
234 else
235 {
236 m_cch = 0;
237 m_cbAllocated = 0;
238 m_psz = NULL;
239 }
240 return S_OK;
241}
242
243
244/**
245 * A variant of Utf8Str::copyFromN that does not throw any exceptions but
246 * returns E_OUTOFMEMORY instead.
247 *
248 * @param a_pcszSrc The source string.
249 * @param a_cchSrc The source string.
250 * @returns S_OK or E_OUTOFMEMORY.
251 *
252 * @remarks This calls cleanup() first, so the caller doesn't have to. (Saves
253 * code space.)
254 */
255HRESULT Utf8Str::copyFromExNComRC(const char *a_pcszSrc, size_t a_cchSrc)
256{
257 cleanup();
258 if (a_cchSrc)
259 {
260 m_psz = RTStrAlloc(a_cchSrc + 1);
261 if (RT_LIKELY(m_psz))
262 {
263 m_cch = a_cchSrc;
264 m_cbAllocated = a_cchSrc + 1;
265 memcpy(m_psz, a_pcszSrc, a_cchSrc);
266 m_psz[a_cchSrc] = '\0';
267 }
268 else
269 {
270 m_cch = 0;
271 m_cbAllocated = 0;
272 return E_OUTOFMEMORY;
273 }
274 }
275 else
276 {
277 m_cch = 0;
278 m_cbAllocated = 0;
279 m_psz = NULL;
280 }
281 return S_OK;
282}
283
284} /* namespace com */
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