VirtualBox

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

Last change on this file since 52320 was 52312, checked in by vboxsync, 10 years ago

6219: New parameters related to file size / recording time limitation for VM Video Capture have been added (vcpmaxtime, vcpmaxsize and vcpoptions - special codec options in key=value format). EbmlWriter has been refactored. Removed some redundant code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: string.cpp 52312 2014-08-07 12:54:38Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer - UTF-8 and UTF-16 string classes.
4 */
5
6/*
7 * Copyright (C) 2006-2012 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, (unsigned)(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::stripSuffix()
138{
139 if (length())
140 {
141 RTPathStripSuffix(m_psz);
142 jolt();
143 }
144 return *this;
145}
146
147size_t Utf8Str::parseKeyValue(Utf8Str &key, Utf8Str &value, size_t pos, const Utf8Str &pairSeparator, const Utf8Str &keyValueSeparator) const
148{
149 size_t start = pos;
150 while(start == (pos = find(pairSeparator.c_str(), pos)))
151 start = ++pos;
152
153 size_t kvSepPos = find(keyValueSeparator.c_str(), start);
154 if (kvSepPos < pos)
155 {
156 key = substr(start, kvSepPos - start);
157 value = substr(kvSepPos + 1, pos - kvSepPos - 1);
158 }
159 else
160 {
161 key = value = "";
162 }
163 return pos;
164}
165
166/**
167 * Internal function used in Utf8Str copy constructors and assignment when
168 * copying from a UTF-16 string.
169 *
170 * As with the RTCString::copyFrom() variants, this unconditionally sets the
171 * members to a copy of the given other strings and makes no assumptions about
172 * previous contents. This can therefore be used both in copy constructors,
173 * when member variables have no defined value, and in assignments after having
174 * called cleanup().
175 *
176 * This variant converts from a UTF-16 string, most probably from
177 * a Bstr assignment.
178 *
179 * @param a_pbstr The source string. The caller guarantees that this
180 * is valid UTF-16.
181 *
182 * @sa RTCString::copyFromN
183 */
184void Utf8Str::copyFrom(CBSTR a_pbstr)
185{
186 if (a_pbstr && *a_pbstr)
187 {
188 int vrc = RTUtf16ToUtf8Ex((PCRTUTF16)a_pbstr,
189 RTSTR_MAX, // size_t cwcString: translate entire string
190 &m_psz, // char **ppsz: output buffer
191 0, // size_t cch: if 0, func allocates buffer in *ppsz
192 &m_cch); // size_t *pcch: receives the size of the output string, excluding the terminator.
193 if (RT_SUCCESS(vrc))
194 m_cbAllocated = m_cch + 1;
195 else
196 {
197 if ( vrc != VERR_NO_STR_MEMORY
198 && vrc != VERR_NO_MEMORY)
199 {
200 /* ASSUME: input is valid Utf-16. Fake out of memory error. */
201 AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTUtf16Len(a_pbstr) * sizeof(RTUTF16), a_pbstr));
202 }
203
204 m_cch = 0;
205 m_cbAllocated = 0;
206 m_psz = NULL;
207
208 throw std::bad_alloc();
209 }
210 }
211 else
212 {
213 m_cch = 0;
214 m_cbAllocated = 0;
215 m_psz = NULL;
216 }
217}
218
219/**
220 * A variant of Utf8Str::copyFrom that does not throw any exceptions but returns
221 * E_OUTOFMEMORY instead.
222 *
223 * @param a_pbstr The source string.
224 * @returns S_OK or E_OUTOFMEMORY.
225 */
226HRESULT Utf8Str::copyFromEx(CBSTR a_pbstr)
227{
228 if (a_pbstr && *a_pbstr)
229 {
230 int vrc = RTUtf16ToUtf8Ex((PCRTUTF16)a_pbstr,
231 RTSTR_MAX, // size_t cwcString: translate entire string
232 &m_psz, // char **ppsz: output buffer
233 0, // size_t cch: if 0, func allocates buffer in *ppsz
234 &m_cch); // size_t *pcch: receives the size of the output string, excluding the terminator.
235 if (RT_SUCCESS(vrc))
236 m_cbAllocated = m_cch + 1;
237 else
238 {
239 if ( vrc != VERR_NO_STR_MEMORY
240 && vrc != VERR_NO_MEMORY)
241 {
242 /* ASSUME: input is valid Utf-16. Fake out of memory error. */
243 AssertLogRelMsgFailed(("%Rrc %.*Rhxs\n", vrc, RTUtf16Len(a_pbstr) * sizeof(RTUTF16), a_pbstr));
244 }
245
246 m_cch = 0;
247 m_cbAllocated = 0;
248 m_psz = NULL;
249
250 return E_OUTOFMEMORY;
251 }
252 }
253 else
254 {
255 m_cch = 0;
256 m_cbAllocated = 0;
257 m_psz = NULL;
258 }
259 return S_OK;
260}
261
262
263/**
264 * A variant of Utf8Str::copyFromN that does not throw any exceptions but
265 * returns E_OUTOFMEMORY instead.
266 *
267 * @param a_pcszSrc The source string.
268 * @param a_offSrc Start offset to copy from.
269 * @param a_cchSrc The source string.
270 * @returns S_OK or E_OUTOFMEMORY.
271 *
272 * @remarks This calls cleanup() first, so the caller doesn't have to. (Saves
273 * code space.)
274 */
275HRESULT Utf8Str::copyFromExNComRC(const char *a_pcszSrc, size_t a_offSrc, size_t a_cchSrc)
276{
277 cleanup();
278 if (a_cchSrc)
279 {
280 m_psz = RTStrAlloc(a_cchSrc + 1);
281 if (RT_LIKELY(m_psz))
282 {
283 m_cch = a_cchSrc;
284 m_cbAllocated = a_cchSrc + 1;
285 memcpy(m_psz, a_pcszSrc + a_offSrc, a_cchSrc);
286 m_psz[a_cchSrc] = '\0';
287 }
288 else
289 {
290 m_cch = 0;
291 m_cbAllocated = 0;
292 return E_OUTOFMEMORY;
293 }
294 }
295 else
296 {
297 m_cch = 0;
298 m_cbAllocated = 0;
299 m_psz = NULL;
300 }
301 return S_OK;
302}
303
304} /* 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