master
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#ifndef _WRL_COREWRAPPERS_H_
8#define _WRL_COREWRAPPERS_H_
9
10#include <type_traits>
11
12#include <windows.h>
13#include <intsafe.h>
14#include <winstring.h>
15#include <roapi.h>
16
17/* #include <wrl/def.h> */
18#include <wrl/internal.h>
19
20namespace Microsoft {
21 namespace WRL {
22 namespace Details {
23 struct Dummy {};
24 }
25
26 namespace Wrappers {
27 class HStringReference;
28
29 class HString {
30 public:
31 HString() throw() : hstr_(nullptr) {}
32
33 HString(HString&& o) throw() : hstr_(o.hstr_) {
34 o.hstr_ = nullptr;
35 }
36
37 HString(const HString&) = delete;
38 HString& operator=(const HString&) = delete;
39
40 operator HSTRING() const throw() {
41 return hstr_;
42 }
43
44 ~HString() throw() {
45 Release();
46 }
47
48 HString& operator=(HString&& o) throw() {
49 Release();
50 hstr_ = o.hstr_;
51 o.hstr_ = nullptr;
52 return *this;
53 }
54
55 HRESULT Set(const wchar_t *s, unsigned int l) throw() {
56 Release();
57 return ::WindowsCreateString(s, l, &hstr_);
58 }
59
60 template <size_t s>
61 HRESULT Set(const wchar_t (&str)[s]) throw() {
62 static_assert(static_cast<size_t>(static_cast<UINT32>(s - 1)) == s - 1, "mismatch string length");
63 return Set(str, s - 1);
64 }
65
66 template <size_t s>
67 HRESULT Set(wchar_t (&strRef)[s]) throw() {
68 const wchar_t *str = static_cast<const wchar_t *>(strRef);
69 unsigned int l;
70 HRESULT hr = SizeTToUInt32(::wcslen(str), &l);
71 if (SUCCEEDED(hr))
72 hr = Set(str, l);
73 return hr;
74 }
75
76 template <typename T>
77 HRESULT Set(const T& s, typename ::std::enable_if<::std::is_convertible<const T&, const wchar_t *>::value, ::Microsoft::WRL::Details::Dummy>::type = ::Microsoft::WRL::Details::Dummy()) throw() {
78 HRESULT hr = S_OK;
79 const wchar_t *str = static_cast<PCWSTR>(s);
80 if (str != nullptr) {
81 unsigned int l;
82 hr = SizeTToUInt32(::wcslen(str), &l);
83 if (SUCCEEDED(hr))
84 hr = Set(str, l);
85 }
86 else
87 hr = Set(L"", 0);
88 return hr;
89 }
90
91 HRESULT Set(const HSTRING& s) throw() {
92 HRESULT hr = S_OK;
93 if (s == nullptr || s != hstr_) {
94 Release();
95 hr = ::WindowsDuplicateString(s, &hstr_);
96 }
97 return hr;
98 }
99
100 void Attach(HSTRING h) throw() {
101 ::WindowsDeleteString(hstr_);
102 hstr_ = h;
103 }
104
105 HSTRING Detach() throw() {
106 HSTRING t = hstr_;
107 hstr_ = nullptr;
108 return t;
109 }
110
111 HSTRING* GetAddressOf() throw() {
112 Release();
113 return &hstr_;
114 }
115
116 HSTRING* ReleaseAndGetAddressOf() throw() {
117 Release();
118 return &hstr_;
119 }
120
121 HSTRING Get() const throw() {
122 return hstr_;
123 }
124
125 void Release() throw() {
126 ::WindowsDeleteString(hstr_);
127 hstr_ = nullptr;
128 }
129
130 bool IsValid() const throw() {
131 return hstr_ != nullptr;
132 }
133
134 UINT32 Length() const throw() {
135 return ::WindowsGetStringLen(hstr_);
136 }
137
138 const wchar_t* GetRawBuffer(unsigned int *l) const {
139 return ::WindowsGetStringRawBuffer(hstr_, l);
140 }
141
142 HRESULT CopyTo(HSTRING *s) const throw() {
143 return ::WindowsDuplicateString(hstr_, s);
144 }
145
146 HRESULT Duplicate(const HString& o) throw() {
147 HSTRING l;
148 HRESULT hr = ::WindowsDuplicateString(o, &l);
149 return ReleaseAndAssignOnSuccess(hr, l, *this);
150 }
151
152 bool IsEmpty() const throw() {
153 return hstr_ == nullptr;
154 }
155
156 HRESULT Concat(const HString& s, HString& n) const throw() {
157 HSTRING l;
158 HRESULT hr = ::WindowsConcatString(hstr_, s, &l);
159 return ReleaseAndAssignOnSuccess(hr, l, n);
160 }
161
162 HRESULT TrimStart(const HString& t, HString& n) const throw() {
163 HSTRING l;
164 HRESULT hr = ::WindowsTrimStringStart(hstr_, t, &l);
165 return ReleaseAndAssignOnSuccess(hr, l, n);
166 }
167
168 HRESULT TrimEnd(const HString& t, HString& n) const throw() {
169 HSTRING l;
170 HRESULT hr = ::WindowsTrimStringEnd(hstr_, t, &l);
171 return ReleaseAndAssignOnSuccess(hr, l, n);
172 }
173
174 HRESULT Substring(UINT32 s, HString& n) const throw() {
175 HSTRING l;
176 HRESULT hr = ::WindowsSubstring(hstr_, s, &l);
177 return ReleaseAndAssignOnSuccess(hr, l, n);
178 }
179
180 HRESULT Substring(UINT32 s, UINT32 len, HString& n) const throw() {
181 HSTRING l;
182 HRESULT hr = ::WindowsSubstringWithSpecifiedLength(hstr_, s, len, &l);
183 return ReleaseAndAssignOnSuccess(hr, l, n);
184 }
185
186 HRESULT Replace(const HString& s1, const HString& s2, HString& n) const throw() {
187 HSTRING l;
188 HRESULT hr = ::WindowsReplaceString(hstr_, s1, s2, &l);
189 return ReleaseAndAssignOnSuccess(hr, l, n);
190 }
191
192 template<unsigned int s>
193 static HStringReference MakeReference(wchar_t const (&str)[s]) throw();
194
195 template<unsigned int s>
196 static HStringReference MakeReference(wchar_t const (&str)[s], unsigned int l) throw();
197
198 private:
199 static HRESULT ReleaseAndAssignOnSuccess(HRESULT hr, HSTRING n, HString& t) {
200 if (SUCCEEDED(hr)) {
201 *t.ReleaseAndGetAddressOf() = n;
202 }
203 return hr;
204 }
205
206 protected:
207 HSTRING hstr_;
208 };
209
210 class HStringReference {
211 private:
212 void Init(const wchar_t* str, unsigned int len) {
213 HRESULT hres = ::WindowsCreateStringReference(str, len, &header_, &hstr_);
214 if (FAILED(hres))
215 ::Microsoft::WRL::Details::RaiseException(hres);
216 }
217
218 HStringReference() : hstr_(nullptr) {}
219
220 public:
221 HStringReference(const wchar_t* str, unsigned int len) throw() : hstr_(nullptr) {
222 Init(str, len);
223 }
224
225 template<unsigned int sizeDest>
226 explicit HStringReference(wchar_t const (&str)[sizeDest]) throw() : hstr_(nullptr) {
227 Init(str, sizeDest - 1);
228 }
229
230 template <size_t sizeDest>
231 explicit HStringReference(wchar_t (&strRef)[sizeDest]) throw() {
232 const wchar_t *str = static_cast<const wchar_t*>(strRef);
233 Init(str, ::wcslen(str));
234 }
235
236 template<typename T>
237 explicit HStringReference(const T &strRef) throw() : hstr_(nullptr) {
238 const wchar_t* str = static_cast<const wchar_t*>(strRef);
239 size_t len = ::wcslen(str);
240 if(static_cast<size_t>(static_cast<unsigned int>(len)) != len)
241 ::Microsoft::WRL::Details::RaiseException(INTSAFE_E_ARITHMETIC_OVERFLOW);
242 Init(str, len);
243 }
244
245 HStringReference(const HStringReference &other) throw() : hstr_(nullptr) {
246 unsigned int len = 0;
247 const wchar_t* value = other.GetRawBuffer(&len);
248 Init(value, len);
249 }
250
251 ~HStringReference() throw() {
252 hstr_ = nullptr;
253 }
254
255 HStringReference& operator=(const HStringReference &other) throw() {
256 unsigned int len = 0;
257 const wchar_t* value = other.GetRawBuffer(&len);
258 Init(value, len);
259 return *this;
260 }
261
262 HSTRING Get() const throw() {
263 return hstr_;
264 }
265
266 const wchar_t *GetRawBuffer(unsigned int *len) const {
267 return ::WindowsGetStringRawBuffer(hstr_, len);
268 }
269
270 HRESULT CopyTo(HSTRING *str) const throw() {
271 return ::WindowsDuplicateString(hstr_, str);
272 }
273
274 friend class HString;
275
276 protected:
277 HSTRING_HEADER header_;
278 HSTRING hstr_;
279 };
280
281 class RoInitializeWrapper {
282 public:
283 RoInitializeWrapper(RO_INIT_TYPE flags) {
284 hres = ::Windows::Foundation::Initialize(flags);
285 }
286
287 ~RoInitializeWrapper() {
288 if(SUCCEEDED(hres))
289 ::Windows::Foundation::Uninitialize();
290 }
291
292 operator HRESULT() {
293 return hres;
294 }
295 private:
296 HRESULT hres;
297 };
298 }
299 }
300}
301
302#endif