VirtualBox

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

Last change on this file since 35105 was 34846, checked in by vboxsync, 14 years ago

COM glue: Added a substring constructor to the Bstr class (with optimized memory usage compared to the others).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.9 KB
Line 
1/* $Id: string.cpp 34846 2010-12-08 17:50:25Z vboxsync $ */
2
3/** @file
4 *
5 * MS COM / XPCOM Abstraction Layer:
6 * UTF-8 and UTF-16 string classes
7 */
8
9/*
10 * Copyright (C) 2006-2007 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
21#include "VBox/com/string.h"
22
23#include <iprt/err.h>
24#include <iprt/path.h>
25
26namespace com
27{
28
29// BSTR representing a null wide char with 32 bits of length prefix (0);
30// this will work on Windows as well as other platforms where BSTR does
31// not use length prefixes
32const OLECHAR g_achEmptyBstr[3] = { 0, 0, 0 };
33const BSTR g_bstrEmpty = (BSTR)(&g_achEmptyBstr[2]);
34
35/* static */
36const Bstr Bstr::Empty; /* default ctor is OK */
37
38void Bstr::copyFromN(const char *a_pszSrc, size_t a_cchMax)
39{
40 /*
41 * Initialie m_bstr first in case of throws further down in the code, then
42 * check for empty input (m_bstr == NULL means empty, there are no NULL
43 * strings).
44 */
45 m_bstr = NULL;
46 if (!a_cchMax || !a_pszSrc || !*a_pszSrc)
47 return;
48
49 /*
50 * Calculate the length and allocate a BSTR string buffer of the right
51 * size, i.e. optimize heap usage.
52 */
53 size_t cwc;
54 int vrc = ::RTStrCalcUtf16LenEx(a_pszSrc, a_cchMax, &cwc);
55 AssertRCReturnVoid(vrc); /* throw instead? */
56
57 m_bstr = ::SysAllocStringByteLen(NULL, cwc * sizeof(OLECHAR));
58 if (m_bstr)
59 {
60 PRTUTF16 pwsz = (PRTUTF16)m_bstr;
61 vrc = ::RTStrToUtf16Ex(a_pszSrc, a_cchMax, &pwsz, cwc + 1, NULL);
62 if (RT_FAILURE(vrc))
63 {
64 /* This should not happen! */
65 AssertRC(vrc);
66 cleanup();
67 }
68 }
69 else
70 throw std::bad_alloc();
71}
72
73
74/* static */
75const Utf8Str Utf8Str::Empty; /* default ctor is OK */
76
77#if defined(VBOX_WITH_XPCOM)
78void Utf8Str::cloneTo(char **pstr) const
79{
80 size_t cb = length() + 1;
81 *pstr = (char*)nsMemory::Alloc(cb);
82 if (!*pstr)
83 throw std::bad_alloc();
84 memcpy(*pstr, c_str(), cb);
85}
86#endif
87
88Utf8Str& Utf8Str::stripTrailingSlash()
89{
90 if (length())
91 {
92 ::RTPathStripTrailingSlash(m_psz);
93 jolt();
94 }
95 return *this;
96}
97
98Utf8Str& Utf8Str::stripFilename()
99{
100 if (length())
101 {
102 RTPathStripFilename(m_psz);
103 jolt();
104 }
105 return *this;
106}
107
108Utf8Str& Utf8Str::stripPath()
109{
110 if (length())
111 {
112 char *pszName = ::RTPathFilename(m_psz);
113 if (pszName)
114 {
115 size_t cchName = length() - (pszName - m_psz);
116 memmove(m_psz, pszName, cchName + 1);
117 jolt();
118 }
119 else
120 cleanup();
121 }
122 return *this;
123}
124
125Utf8Str& Utf8Str::stripExt()
126{
127 if (length())
128 {
129 RTPathStripExt(m_psz);
130 jolt();
131 }
132 return *this;
133}
134
135Utf8Str& Utf8Str::useForwardSlashes()
136{
137 for (size_t i = 0; i < length(); ++i)
138 {
139 char *p = &m_psz[i];
140 if (*p == '\\')
141 *p = '/';
142 }
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 iprt::ministring::copyFrom() variants, this unconditionally
152 * sets the members to a copy of the given other strings and makes
153 * no assumptions about previous contents. This can therefore be used
154 * both in copy constructors, when member variables have no defined
155 * value, and in assignments after having called cleanup().
156 *
157 * This variant converts from a UTF-16 string, most probably from
158 * a Bstr assignment.
159 *
160 * @param s
161 */
162void Utf8Str::copyFrom(CBSTR s)
163{
164 if (s && *s)
165 {
166 int vrc = RTUtf16ToUtf8Ex((PRTUTF16)s, // PCRTUTF16 pwszString
167 RTSTR_MAX, // size_t cwcString: translate entire string
168 &m_psz, // char **ppsz: output buffer
169 0, // size_t cch: if 0, func allocates buffer in *ppsz
170 &m_cch); // size_t *pcch: receives the size of the output string, excluding the terminator.
171 if (RT_FAILURE(vrc))
172 {
173 if ( vrc == VERR_NO_STR_MEMORY
174 || vrc == VERR_NO_MEMORY
175 )
176 throw std::bad_alloc();
177
178 // @todo what do we do with bad input strings? throw also? for now just keep an empty string
179 m_cch = 0;
180 m_cbAllocated = 0;
181 m_psz = NULL;
182 }
183 else
184 m_cbAllocated = m_cch + 1;
185 }
186 else
187 {
188 m_cch = 0;
189 m_cbAllocated = 0;
190 m_psz = NULL;
191 }
192}
193
194} /* 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