[CRT/INTRIN] Use the gcc intrinsic equivalents when compiling with clang-cl and skip...
[reactos.git] / sdk / include / crt / comutil.h
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 #ifndef _INC_COMUTIL
7 #define _INC_COMUTIL
8
9 #include <ole2.h>
10
11 #ifndef _COM_ASSERT
12 #define _COM_ASSERT(x) ((void)0)
13 #endif
14
15 #define _COM_MEMCPY_S(dest,destsize,src,count) memcpy(dest,src,count)
16
17 /* Use of wsprintf might be impossible, if strsafe.h is included. */
18 #if !defined(__STDC_SECURE_LIB__) || defined(__REACTOS__)
19 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) wsprintf(dest,format,arg1)
20 #elif defined(UNICODE)
21 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) swprintf_s(dest,destsize,format,arg1)
22 #else
23 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) sprintf_s(dest,destsize,format,arg1)
24 #endif
25
26 #ifdef __cplusplus
27
28 #pragma push_macro("new")
29 #undef new
30
31 #ifndef WINAPI
32 #define WINAPI __stdcall
33 #endif
34
35 class _com_error;
36
37 void WINAPI _com_issue_error(HRESULT);
38
39 class _bstr_t;
40 class _variant_t;
41
42 namespace _com_util {
43 inline void CheckError(HRESULT hr) {
44 if(FAILED(hr)) { _com_issue_error(hr); }
45 }
46 }
47
48 namespace _com_util {
49 BSTR WINAPI ConvertStringToBSTR(const char *pSrc);
50 char *WINAPI ConvertBSTRToString(BSTR pSrc);
51 }
52
53 class _bstr_t {
54 public:
55 _bstr_t() throw();
56 _bstr_t(const _bstr_t &s) throw();
57 _bstr_t(const char *s);
58 _bstr_t(const wchar_t *s);
59 _bstr_t(const _variant_t &var);
60 _bstr_t(BSTR bstr,bool fCopy);
61 ~_bstr_t() throw();
62 _bstr_t &operator=(const _bstr_t &s) throw();
63 _bstr_t &operator=(const char *s);
64 _bstr_t &operator=(const wchar_t *s);
65 _bstr_t &operator=(const _variant_t &var);
66 _bstr_t &operator+=(const _bstr_t &s);
67 _bstr_t operator+(const _bstr_t &s) const;
68 friend _bstr_t operator+(const char *s1,const _bstr_t &s2);
69 friend _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2);
70 operator const wchar_t *() const throw();
71 operator wchar_t *() const throw();
72 operator const char *() const;
73 operator char *() const;
74 bool operator!() const throw();
75 bool operator==(const _bstr_t &str) const throw();
76 bool operator!=(const _bstr_t &str) const throw();
77 bool operator<(const _bstr_t &str) const throw();
78 bool operator>(const _bstr_t &str) const throw();
79 bool operator<=(const _bstr_t &str) const throw();
80 bool operator>=(const _bstr_t &str) const throw();
81 BSTR copy(bool fCopy = true) const;
82 unsigned int length() const throw();
83 void Assign(BSTR s);
84 BSTR &GetBSTR();
85 BSTR *GetAddress();
86 void Attach(BSTR s);
87 BSTR Detach();
88 private:
89 class Data_t {
90 public:
91 Data_t(const char *s);
92 Data_t(const wchar_t *s);
93 Data_t(BSTR bstr,bool fCopy);
94 Data_t(const _bstr_t &s1,const _bstr_t &s2);
95 unsigned long AddRef() throw();
96 unsigned long Release() throw();
97 unsigned long RefCount() const throw();
98 operator const wchar_t *() const throw();
99 operator const char *() const;
100 const wchar_t *GetWString() const throw();
101 wchar_t *&GetWString() throw();
102 const char *GetString() const;
103 BSTR Copy() const;
104 void Assign(BSTR s);
105 void Attach(BSTR s) throw();
106 unsigned int Length() const throw();
107 int Compare(const Data_t &str) const throw();
108 void *operator new(size_t sz);
109 private:
110 BSTR m_wstr;
111 mutable char *m_str;
112 unsigned long m_RefCount;
113 Data_t() throw();
114 Data_t(const Data_t &s) throw();
115 ~Data_t() throw();
116 void _Free() throw();
117 };
118 private:
119 Data_t *m_Data;
120 private:
121 void _AddRef() throw();
122 void _Free() throw();
123 int _Compare(const _bstr_t &str) const throw();
124 };
125
126 inline _bstr_t::_bstr_t() throw() : m_Data(NULL) { }
127
128 inline _bstr_t::_bstr_t(const _bstr_t &s) throw() : m_Data(s.m_Data) { _AddRef(); }
129
130 inline _bstr_t::_bstr_t(const char *s) : m_Data(new Data_t(s)) {
131 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
132 }
133
134 inline _bstr_t::_bstr_t(const wchar_t *s) : m_Data(new Data_t(s)) {
135 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
136 }
137
138 inline _bstr_t::_bstr_t(BSTR bstr,bool fCopy) : m_Data(new Data_t(bstr,fCopy)) {
139 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
140 }
141
142 inline _bstr_t::~_bstr_t() throw() { _Free(); }
143
144 inline _bstr_t &_bstr_t::operator=(const _bstr_t &s) throw() {
145 if(this!=&s) {
146 _Free();
147 m_Data = s.m_Data;
148 _AddRef();
149 }
150 return *this;
151 }
152
153 inline _bstr_t &_bstr_t::operator=(const char *s) {
154 _COM_ASSERT(!s || static_cast<const char *>(*this)!=s);
155 if(!s || static_cast<const char *>(*this)!=s) {
156 _Free();
157 m_Data = new Data_t(s);
158 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
159 }
160 return *this;
161 }
162
163 inline _bstr_t &_bstr_t::operator=(const wchar_t *s) {
164 _COM_ASSERT(!s || static_cast<const wchar_t *>(*this)!=s);
165 if(!s || static_cast<const wchar_t *>(*this)!=s) {
166 _Free();
167 m_Data = new Data_t(s);
168 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
169 }
170 return *this;
171 }
172
173 inline _bstr_t &_bstr_t::operator+=(const _bstr_t &s) {
174 Data_t *newData = new Data_t(*this,s);
175 if(!newData) { _com_issue_error(E_OUTOFMEMORY); }
176 else {
177 _Free();
178 m_Data = newData;
179 }
180 return *this;
181 }
182
183 inline _bstr_t _bstr_t::operator+(const _bstr_t &s) const {
184 _bstr_t b = *this;
185 b += s;
186 return b;
187 }
188
189 inline _bstr_t operator+(const char *s1,const _bstr_t &s2) {
190 _bstr_t b = s1;
191 b += s2;
192 return b;
193 }
194
195 inline _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2) {
196 _bstr_t b = s1;
197 b += s2;
198 return b;
199 }
200
201 inline _bstr_t::operator const wchar_t *() const throw() { return (m_Data!=NULL) ? m_Data->GetWString() : NULL; }
202 inline _bstr_t::operator wchar_t *() const throw() { return const_cast<wchar_t *>((m_Data!=NULL) ? m_Data->GetWString() : NULL); }
203 inline _bstr_t::operator const char *() const { return (m_Data!=NULL) ? m_Data->GetString() : NULL; }
204 inline _bstr_t::operator char *() const { return const_cast<char *>((m_Data!=NULL) ? m_Data->GetString() : NULL); }
205 inline bool _bstr_t::operator!() const throw() { return (m_Data!=NULL) ? !m_Data->GetWString() : true; }
206 inline bool _bstr_t::operator==(const _bstr_t &str) const throw() { return _Compare(str)==0; }
207 inline bool _bstr_t::operator!=(const _bstr_t &str) const throw() { return _Compare(str)!=0; }
208 inline bool _bstr_t::operator<(const _bstr_t &str) const throw() { return _Compare(str)<0; }
209 inline bool _bstr_t::operator>(const _bstr_t &str) const throw() { return _Compare(str)>0; }
210 inline bool _bstr_t::operator<=(const _bstr_t &str) const throw() { return _Compare(str)<=0; }
211 inline bool _bstr_t::operator>=(const _bstr_t &str) const throw() { return _Compare(str)>=0; }
212 inline BSTR _bstr_t::copy(bool fCopy) const { return (m_Data!=NULL) ? (fCopy ? m_Data->Copy() : m_Data->GetWString()) : NULL; }
213 inline unsigned int _bstr_t::length() const throw() { return (m_Data!=NULL) ? m_Data->Length() : 0; }
214 inline void _bstr_t::Assign(BSTR s) {
215 _COM_ASSERT(!s || !m_Data || m_Data->GetWString()!=s);
216 if(!s || !m_Data || m_Data->GetWString()!=s) {
217 _Free();
218 m_Data = new Data_t(s,TRUE);
219 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
220 }
221 }
222
223 inline BSTR &_bstr_t::GetBSTR() {
224 if(!m_Data) {
225 m_Data = new Data_t(0,FALSE);
226 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
227 }
228 return m_Data->GetWString();
229 }
230
231 inline BSTR *_bstr_t::GetAddress() {
232 Attach(0);
233 return &m_Data->GetWString();
234 }
235
236 inline void _bstr_t::Attach(BSTR s) {
237 _Free();
238 m_Data = new Data_t(s,FALSE);
239 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
240 }
241
242 inline BSTR _bstr_t::Detach() {
243 _COM_ASSERT(m_Data!=NULL && m_Data->RefCount()==1);
244 if(m_Data!=NULL && m_Data->RefCount()==1) {
245 BSTR b = m_Data->GetWString();
246 m_Data->GetWString() = NULL;
247 _Free();
248 return b;
249 } else {
250 _com_issue_error(E_POINTER);
251 return NULL;
252 }
253 }
254
255 inline void _bstr_t::_AddRef() throw() {
256 if(m_Data!=NULL) m_Data->AddRef();
257 }
258
259 inline void _bstr_t::_Free() throw() {
260 if(m_Data!=NULL) {
261 m_Data->Release();
262 m_Data = NULL;
263 }
264 }
265
266 inline int _bstr_t::_Compare(const _bstr_t &str) const throw() {
267 if(m_Data==str.m_Data) return 0;
268 if(!m_Data) return -1;
269 if(!str.m_Data) return 1;
270 return m_Data->Compare(*str.m_Data);
271 }
272
273 inline _bstr_t::Data_t::Data_t(const char *s) : m_str(NULL),m_RefCount(1) {
274 m_wstr = _com_util::ConvertStringToBSTR(s);
275 }
276
277 inline _bstr_t::Data_t::Data_t(const wchar_t *s) : m_str(NULL),m_RefCount(1) {
278 m_wstr = ::SysAllocString(s);
279 if(!m_wstr && s!=NULL) { _com_issue_error(E_OUTOFMEMORY); }
280 }
281
282 inline _bstr_t::Data_t::Data_t(BSTR bstr,bool fCopy) : m_str(NULL),m_RefCount(1) {
283 if(fCopy && bstr!=NULL) {
284 m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
285 if(!m_wstr) { _com_issue_error(E_OUTOFMEMORY); }
286 } else m_wstr = bstr;
287 }
288
289 inline _bstr_t::Data_t::Data_t(const _bstr_t &s1,const _bstr_t &s2) : m_str(NULL),m_RefCount(1) {
290 const unsigned int l1 = s1.length();
291 const unsigned int l2 = s2.length();
292 m_wstr = ::SysAllocStringByteLen(NULL,(l1 + l2) *sizeof(wchar_t));
293 if(!m_wstr) {
294 _com_issue_error(E_OUTOFMEMORY);
295 return;
296 }
297 const wchar_t *wstr1 = static_cast<const wchar_t *>(s1);
298 if(wstr1!=NULL) {
299 _COM_MEMCPY_S(m_wstr,(l1 + l2 + 1) *sizeof(wchar_t),wstr1,(l1 + 1) *sizeof(wchar_t));
300 }
301 const wchar_t *wstr2 = static_cast<const wchar_t *>(s2);
302 if(wstr2!=NULL) {
303 _COM_MEMCPY_S(m_wstr + l1,(l2 + 1) *sizeof(wchar_t),wstr2,(l2 + 1) *sizeof(wchar_t));
304 }
305 }
306
307 inline unsigned long _bstr_t::Data_t::AddRef() throw() {
308 InterlockedIncrement(reinterpret_cast<LONG*>(&m_RefCount));
309 return m_RefCount;
310 }
311
312 inline unsigned long _bstr_t::Data_t::Release() throw() {
313 unsigned long cRef = InterlockedDecrement(reinterpret_cast<LONG*>(&m_RefCount));
314 if(cRef==0) delete this;
315 return cRef;
316 }
317
318 inline unsigned long _bstr_t::Data_t::RefCount() const throw() { return m_RefCount; }
319 inline _bstr_t::Data_t::operator const wchar_t *() const throw() { return m_wstr; }
320 inline _bstr_t::Data_t::operator const char *() const { return GetString(); }
321 inline const wchar_t *_bstr_t::Data_t::GetWString() const throw() { return m_wstr; }
322 inline wchar_t *&_bstr_t::Data_t::GetWString() throw() { return m_wstr; }
323 inline const char *_bstr_t::Data_t::GetString() const {
324 if(!m_str) m_str = _com_util::ConvertBSTRToString(m_wstr);
325 return m_str;
326 }
327 inline BSTR _bstr_t::Data_t::Copy() const {
328 if(m_wstr!=NULL) {
329 BSTR bstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(m_wstr),::SysStringByteLen(m_wstr));
330 if(!bstr) { _com_issue_error(E_OUTOFMEMORY); }
331 return bstr;
332 }
333 return NULL;
334 }
335 inline void _bstr_t::Data_t::Assign(BSTR s) {
336 _Free();
337 if(s!=NULL) {
338 m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(s),::SysStringByteLen(s));
339 m_str = 0;
340 }
341 }
342 inline void _bstr_t::Data_t::Attach(BSTR s) throw() {
343 _Free();
344 m_wstr = s;
345 m_str = 0;
346 m_RefCount = 1;
347 }
348 inline unsigned int _bstr_t::Data_t::Length() const throw() { return m_wstr ? ::SysStringLen(m_wstr) : 0; }
349 inline int _bstr_t::Data_t::Compare(const _bstr_t::Data_t &str) const throw() {
350 if(!m_wstr) return str.m_wstr ? -1 : 0;
351 if(!str.m_wstr) return 1;
352 const unsigned int l1 = ::SysStringLen(m_wstr);
353 const unsigned int l2 = ::SysStringLen(str.m_wstr);
354 unsigned int len = l1;
355 if(len>l2) len = l2;
356 BSTR bstr1 = m_wstr;
357 BSTR bstr2 = str.m_wstr;
358 while (len-->0) {
359 if(*bstr1++!=*bstr2++) return bstr1[-1] - bstr2[-1];
360 }
361 return (l1<l2) ? -1 : (l1==l2) ? 0 : 1;
362 }
363
364 #ifdef _COM_OPERATOR_NEW_THROWS
365 inline void *_bstr_t::Data_t::operator new(size_t sz) {
366 try {
367 return ::operator new(sz);
368 } catch (...) {
369 return NULL;
370 }
371 }
372 #else
373 inline void *_bstr_t::Data_t::operator new(size_t sz) {
374 return ::operator new(sz);
375 }
376 #endif
377
378 inline _bstr_t::Data_t::~Data_t() throw() { _Free(); }
379 inline void _bstr_t::Data_t::_Free() throw() {
380 if(m_wstr!=NULL) ::SysFreeString(m_wstr);
381 if(m_str!=NULL) delete [] m_str;
382 }
383
384 class _variant_t : public ::tagVARIANT {
385 public:
386 _variant_t() throw();
387 _variant_t(const VARIANT &varSrc);
388 _variant_t(const VARIANT *pSrc);
389 _variant_t(const _variant_t &varSrc);
390 _variant_t(VARIANT &varSrc,bool fCopy);
391 _variant_t(short sSrc,VARTYPE vtSrc = VT_I2);
392 _variant_t(long lSrc,VARTYPE vtSrc = VT_I4);
393 _variant_t(float fltSrc) throw();
394 _variant_t(double dblSrc,VARTYPE vtSrc = VT_R8);
395 _variant_t(const CY &cySrc) throw();
396 _variant_t(const _bstr_t &bstrSrc);
397 _variant_t(const wchar_t *pSrc);
398 _variant_t(const char *pSrc);
399 _variant_t(IDispatch *pSrc,bool fAddRef = true) throw();
400 _variant_t(bool boolSrc) throw();
401 _variant_t(IUnknown *pSrc,bool fAddRef = true) throw();
402 _variant_t(const DECIMAL &decSrc) throw();
403 _variant_t(BYTE bSrc) throw();
404 _variant_t(char cSrc) throw();
405 _variant_t(unsigned short usSrc) throw();
406 _variant_t(unsigned long ulSrc) throw();
407 _variant_t(int iSrc) throw();
408 _variant_t(unsigned int uiSrc) throw();
409 __MINGW_EXTENSION _variant_t(__int64 i8Src) throw();
410 __MINGW_EXTENSION _variant_t(unsigned __int64 ui8Src) throw();
411 ~_variant_t() throw();
412 operator short() const;
413 operator long() const;
414 operator float() const;
415 operator double() const;
416 operator CY() const;
417 operator _bstr_t() const;
418 operator IDispatch*() const;
419 operator bool() const;
420 operator IUnknown*() const;
421 operator DECIMAL() const;
422 operator BYTE() const;
423 operator VARIANT() const throw();
424 operator char() const;
425 operator unsigned short() const;
426 operator unsigned long() const;
427 operator int() const;
428 operator unsigned int() const;
429 __MINGW_EXTENSION operator __int64() const;
430 __MINGW_EXTENSION operator unsigned __int64() const;
431 _variant_t &operator=(const VARIANT &varSrc);
432 _variant_t &operator=(const VARIANT *pSrc);
433 _variant_t &operator=(const _variant_t &varSrc);
434 _variant_t &operator=(short sSrc);
435 _variant_t &operator=(long lSrc);
436 _variant_t &operator=(float fltSrc);
437 _variant_t &operator=(double dblSrc);
438 _variant_t &operator=(const CY &cySrc);
439 _variant_t &operator=(const _bstr_t &bstrSrc);
440 _variant_t &operator=(const wchar_t *pSrc);
441 _variant_t &operator=(const char *pSrc);
442 _variant_t &operator=(IDispatch *pSrc);
443 _variant_t &operator=(bool boolSrc);
444 _variant_t &operator=(IUnknown *pSrc);
445 _variant_t &operator=(const DECIMAL &decSrc);
446 _variant_t &operator=(BYTE bSrc);
447 _variant_t &operator=(char cSrc);
448 _variant_t &operator=(unsigned short usSrc);
449 _variant_t &operator=(unsigned long ulSrc);
450 _variant_t &operator=(int iSrc);
451 _variant_t &operator=(unsigned int uiSrc);
452 __MINGW_EXTENSION _variant_t &operator=(__int64 i8Src);
453 __MINGW_EXTENSION _variant_t &operator=(unsigned __int64 ui8Src);
454 bool operator==(const VARIANT &varSrc) const throw();
455 bool operator==(const VARIANT *pSrc) const throw();
456 bool operator!=(const VARIANT &varSrc) const throw();
457 bool operator!=(const VARIANT *pSrc) const throw();
458 void Clear();
459 void Attach(VARIANT &varSrc);
460 VARIANT Detach();
461 VARIANT &GetVARIANT() throw();
462 VARIANT *GetAddress();
463 void ChangeType(VARTYPE vartype,const _variant_t *pSrc = NULL);
464 void SetString(const char *pSrc);
465 };
466
467 inline _variant_t::_variant_t() throw() { ::VariantInit(this); }
468 inline _variant_t::_variant_t(const VARIANT &varSrc) {
469 ::VariantInit(this);
470 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc)));
471 }
472 inline _variant_t::_variant_t(const VARIANT *pSrc) {
473 if(!pSrc) { _com_issue_error(E_POINTER); }
474 else {
475 ::VariantInit(this);
476 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(pSrc)));
477 }
478 }
479 inline _variant_t::_variant_t(const _variant_t &varSrc) {
480 ::VariantInit(this);
481 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
482 }
483 inline _variant_t::_variant_t(VARIANT &varSrc,bool fCopy) {
484 if(fCopy) {
485 ::VariantInit(this);
486 _com_util::CheckError(::VariantCopy(this,&varSrc));
487 } else {
488 _COM_MEMCPY_S(this,sizeof(varSrc),&varSrc,sizeof(varSrc));
489 V_VT(&varSrc) = VT_EMPTY;
490 }
491 }
492 inline _variant_t::_variant_t(short sSrc,VARTYPE vtSrc) {
493 if((vtSrc!=VT_I2) && (vtSrc!=VT_BOOL)) {
494 _com_issue_error(E_INVALIDARG);
495 return;
496 }
497 if(vtSrc==VT_BOOL) {
498 V_VT(this) = VT_BOOL;
499 V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
500 } else {
501 V_VT(this) = VT_I2;
502 V_I2(this) = sSrc;
503 }
504 }
505 inline _variant_t::_variant_t(long lSrc,VARTYPE vtSrc) {
506 if((vtSrc!=VT_I4) && (vtSrc!=VT_ERROR) && (vtSrc!=VT_BOOL)) {
507 _com_issue_error(E_INVALIDARG);
508 return;
509 }
510 if(vtSrc==VT_ERROR) {
511 V_VT(this) = VT_ERROR;
512 V_ERROR(this) = lSrc;
513 } else if(vtSrc==VT_BOOL) {
514 V_VT(this) = VT_BOOL;
515 V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
516 } else {
517 V_VT(this) = VT_I4;
518 V_I4(this) = lSrc;
519 }
520 }
521 inline _variant_t::_variant_t(float fltSrc) throw() {
522 V_VT(this) = VT_R4;
523 V_R4(this) = fltSrc;
524 }
525
526 inline _variant_t::_variant_t(double dblSrc,VARTYPE vtSrc) {
527 if((vtSrc!=VT_R8) && (vtSrc!=VT_DATE)) {
528 _com_issue_error(E_INVALIDARG);
529 return;
530 }
531 if(vtSrc==VT_DATE) {
532 V_VT(this) = VT_DATE;
533 V_DATE(this) = dblSrc;
534 } else {
535 V_VT(this) = VT_R8;
536 V_R8(this) = dblSrc;
537 }
538 }
539 inline _variant_t::_variant_t(const CY &cySrc) throw() {
540 V_VT(this) = VT_CY;
541 V_CY(this) = cySrc;
542 }
543 inline _variant_t::_variant_t(const _bstr_t &bstrSrc) {
544 V_VT(this) = VT_BSTR;
545 BSTR bstr = static_cast<wchar_t *>(bstrSrc);
546 if(!bstr) V_BSTR(this) = NULL;
547 else {
548 V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
549 if(!(V_BSTR(this))) { _com_issue_error(E_OUTOFMEMORY); }
550 }
551 }
552 inline _variant_t::_variant_t(const wchar_t *pSrc) {
553 V_VT(this) = VT_BSTR;
554 V_BSTR(this) = ::SysAllocString(pSrc);
555 if(!(V_BSTR(this)) && pSrc!=NULL) { _com_issue_error(E_OUTOFMEMORY); }
556 }
557 inline _variant_t::_variant_t(const char *pSrc) {
558 V_VT(this) = VT_BSTR;
559 V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
560 }
561 inline _variant_t::_variant_t(IDispatch *pSrc,bool fAddRef) throw() {
562 V_VT(this) = VT_DISPATCH;
563 V_DISPATCH(this) = pSrc;
564 if(fAddRef && V_DISPATCH(this)!=NULL) V_DISPATCH(this)->AddRef();
565 }
566 inline _variant_t::_variant_t(bool boolSrc) throw() {
567 V_VT(this) = VT_BOOL;
568 V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE);
569 }
570 inline _variant_t::_variant_t(IUnknown *pSrc,bool fAddRef) throw() {
571 V_VT(this) = VT_UNKNOWN;
572 V_UNKNOWN(this) = pSrc;
573 if(fAddRef && V_UNKNOWN(this)!=NULL) V_UNKNOWN(this)->AddRef();
574 }
575 inline _variant_t::_variant_t(const DECIMAL &decSrc) throw() {
576 V_DECIMAL(this) = decSrc;
577 V_VT(this) = VT_DECIMAL;
578 }
579 inline _variant_t::_variant_t(BYTE bSrc) throw() {
580 V_VT(this) = VT_UI1;
581 V_UI1(this) = bSrc;
582 }
583 inline _variant_t::_variant_t(char cSrc) throw() {
584 V_VT(this) = VT_I1;
585 V_I1(this) = cSrc;
586 }
587 inline _variant_t::_variant_t(unsigned short usSrc) throw() {
588 V_VT(this) = VT_UI2;
589 V_UI2(this) = usSrc;
590 }
591 inline _variant_t::_variant_t(unsigned long ulSrc) throw() {
592 V_VT(this) = VT_UI4;
593 V_UI4(this) = ulSrc;
594 }
595 inline _variant_t::_variant_t(int iSrc) throw() {
596 V_VT(this) = VT_INT;
597 V_INT(this) = iSrc;
598 }
599 inline _variant_t::_variant_t(unsigned int uiSrc) throw() {
600 V_VT(this) = VT_UINT;
601 V_UINT(this) = uiSrc;
602 }
603 __MINGW_EXTENSION inline _variant_t::_variant_t(__int64 i8Src) throw() {
604 V_VT(this) = VT_I8;
605 V_I8(this) = i8Src;
606 }
607 __MINGW_EXTENSION inline _variant_t::_variant_t(unsigned __int64 ui8Src) throw() {
608 V_VT(this) = VT_UI8;
609 V_UI8(this) = ui8Src;
610 }
611 inline _variant_t::operator short() const {
612 if(V_VT(this)==VT_I2) return V_I2(this);
613 _variant_t varDest;
614 varDest.ChangeType(VT_I2,this);
615 return V_I2(&varDest);
616 }
617 inline _variant_t::operator long() const {
618 if(V_VT(this)==VT_I4) return V_I4(this);
619 _variant_t varDest;
620 varDest.ChangeType(VT_I4,this);
621 return V_I4(&varDest);
622 }
623
624 inline _variant_t::operator float() const {
625 if(V_VT(this)==VT_R4) return V_R4(this);
626 _variant_t varDest;
627 varDest.ChangeType(VT_R4,this);
628 return V_R4(&varDest);
629 }
630
631 inline _variant_t::operator double() const {
632 if(V_VT(this)==VT_R8) return V_R8(this);
633 _variant_t varDest;
634 varDest.ChangeType(VT_R8,this);
635 return V_R8(&varDest);
636 }
637
638 inline _variant_t::operator CY() const {
639 if(V_VT(this)==VT_CY) return V_CY(this);
640 _variant_t varDest;
641 varDest.ChangeType(VT_CY,this);
642 return V_CY(&varDest);
643 }
644
645 inline _variant_t::operator _bstr_t() const {
646 if(V_VT(this)==VT_BSTR) return V_BSTR(this);
647 _variant_t varDest;
648 varDest.ChangeType(VT_BSTR,this);
649 return V_BSTR(&varDest);
650 }
651
652 inline _variant_t::operator IDispatch*() const {
653 if(V_VT(this)==VT_DISPATCH) {
654 if(V_DISPATCH(this)!=NULL) V_DISPATCH(this)->AddRef();
655 return V_DISPATCH(this);
656 }
657 _variant_t varDest;
658 varDest.ChangeType(VT_DISPATCH,this);
659 if(V_DISPATCH(&varDest)!=NULL) V_DISPATCH(&varDest)->AddRef();
660 return V_DISPATCH(&varDest);
661 }
662 inline _variant_t::operator bool() const {
663 if(V_VT(this)==VT_BOOL) return V_BOOL(this) ? true : false;
664 _variant_t varDest;
665 varDest.ChangeType(VT_BOOL,this);
666 return (V_BOOL(&varDest)==VARIANT_TRUE) ? true : false;
667 }
668
669 inline _variant_t::operator IUnknown*() const {
670 if(V_VT(this)==VT_UNKNOWN) {
671 if(V_UNKNOWN(this)!=NULL) V_UNKNOWN(this)->AddRef();
672 return V_UNKNOWN(this);
673 }
674 _variant_t varDest;
675 varDest.ChangeType(VT_UNKNOWN,this);
676 if(V_UNKNOWN(&varDest)!=NULL) V_UNKNOWN(&varDest)->AddRef();
677 return V_UNKNOWN(&varDest);
678 }
679 inline _variant_t::operator DECIMAL() const {
680 if(V_VT(this)==VT_DECIMAL) return V_DECIMAL(this);
681 _variant_t varDest;
682 varDest.ChangeType(VT_DECIMAL,this);
683 return V_DECIMAL(&varDest);
684 }
685 inline _variant_t::operator BYTE() const {
686 if(V_VT(this)==VT_UI1) return V_UI1(this);
687 _variant_t varDest;
688 varDest.ChangeType(VT_UI1,this);
689 return V_UI1(&varDest);
690 }
691 inline _variant_t::operator VARIANT() const throw() { return *(VARIANT*) this; }
692 inline _variant_t::operator char() const {
693 if(V_VT(this)==VT_I1) return V_I1(this);
694 _variant_t varDest;
695 varDest.ChangeType(VT_I1,this);
696 return V_I1(&varDest);
697 }
698
699 inline _variant_t::operator unsigned short() const {
700 if(V_VT(this)==VT_UI2) return V_UI2(this);
701 _variant_t varDest;
702 varDest.ChangeType(VT_UI2,this);
703 return V_UI2(&varDest);
704 }
705
706 inline _variant_t::operator unsigned long() const {
707 if(V_VT(this)==VT_UI4) return V_UI4(this);
708 _variant_t varDest;
709 varDest.ChangeType(VT_UI4,this);
710 return V_UI4(&varDest);
711 }
712 inline _variant_t::operator int() const {
713 if(V_VT(this)==VT_INT) return V_INT(this);
714 _variant_t varDest;
715 varDest.ChangeType(VT_INT,this);
716 return V_INT(&varDest);
717 }
718 inline _variant_t::operator unsigned int() const {
719 if(V_VT(this)==VT_UINT) return V_UINT(this);
720 _variant_t varDest;
721 varDest.ChangeType(VT_UINT,this);
722 return V_UINT(&varDest);
723 }
724 __MINGW_EXTENSION inline _variant_t::operator __int64() const {
725 if(V_VT(this)==VT_I8) return V_I8(this);
726 _variant_t varDest;
727 varDest.ChangeType(VT_I8,this);
728 return V_I8(&varDest);
729 }
730 __MINGW_EXTENSION inline _variant_t::operator unsigned __int64() const {
731 if(V_VT(this)==VT_UI8) return V_UI8(this);
732 _variant_t varDest;
733 varDest.ChangeType(VT_UI8,this);
734 return V_UI8(&varDest);
735 }
736 inline _variant_t &_variant_t::operator=(const VARIANT &varSrc) {
737 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc)));
738 return *this;
739 }
740 inline _variant_t &_variant_t::operator=(const VARIANT *pSrc) {
741 if(!pSrc) { _com_issue_error(E_POINTER); }
742 else { _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(pSrc))); }
743 return *this;
744 }
745 inline _variant_t &_variant_t::operator=(const _variant_t &varSrc) {
746 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
747 return *this;
748 }
749 inline _variant_t &_variant_t::operator=(short sSrc) {
750 if(V_VT(this)==VT_I2) V_I2(this) = sSrc;
751 else if(V_VT(this)==VT_BOOL) V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
752 else {
753 Clear();
754 V_VT(this) = VT_I2;
755 V_I2(this) = sSrc;
756 }
757 return *this;
758 }
759 inline _variant_t &_variant_t::operator=(long lSrc) {
760 if(V_VT(this)==VT_I4) V_I4(this) = lSrc;
761 else if(V_VT(this)==VT_ERROR) V_ERROR(this) = lSrc;
762 else if(V_VT(this)==VT_BOOL) V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
763 else {
764 Clear();
765 V_VT(this) = VT_I4;
766 V_I4(this) = lSrc;
767 }
768 return *this;
769 }
770 inline _variant_t &_variant_t::operator=(float fltSrc) {
771 if(V_VT(this)!=VT_R4) {
772 Clear();
773 V_VT(this) = VT_R4;
774 }
775 V_R4(this) = fltSrc;
776 return *this;
777 }
778
779 inline _variant_t &_variant_t::operator=(double dblSrc)
780 {
781 if(V_VT(this)==VT_R8) {
782 V_R8(this) = dblSrc;
783 }
784 else if(V_VT(this)==VT_DATE) {
785 V_DATE(this) = dblSrc;
786 }
787 else {
788
789 Clear();
790
791 V_VT(this) = VT_R8;
792 V_R8(this) = dblSrc;
793 }
794
795 return *this;
796 }
797
798 inline _variant_t &_variant_t::operator=(const CY &cySrc)
799 {
800 if(V_VT(this)!=VT_CY) {
801
802 Clear();
803
804 V_VT(this) = VT_CY;
805 }
806
807 V_CY(this) = cySrc;
808
809 return *this;
810 }
811
812 inline _variant_t &_variant_t::operator=(const _bstr_t &bstrSrc)
813 {
814 _COM_ASSERT(V_VT(this)!=VT_BSTR || !((BSTR) bstrSrc) || V_BSTR(this)!=(BSTR) bstrSrc);
815
816 Clear();
817
818 V_VT(this) = VT_BSTR;
819
820 if(!bstrSrc) {
821 V_BSTR(this) = NULL;
822 }
823 else {
824 BSTR bstr = static_cast<wchar_t *>(bstrSrc);
825 V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
826
827 if(!(V_BSTR(this))) {
828 _com_issue_error(E_OUTOFMEMORY);
829 }
830 }
831
832 return *this;
833 }
834
835 inline _variant_t &_variant_t::operator=(const wchar_t *pSrc)
836 {
837 _COM_ASSERT(V_VT(this)!=VT_BSTR || !pSrc || V_BSTR(this)!=pSrc);
838
839 Clear();
840
841 V_VT(this) = VT_BSTR;
842
843 if(!pSrc) {
844 V_BSTR(this) = NULL;
845 }
846 else {
847 V_BSTR(this) = ::SysAllocString(pSrc);
848
849 if(!(V_BSTR(this))) {
850 _com_issue_error(E_OUTOFMEMORY);
851 }
852 }
853
854 return *this;
855 }
856
857 inline _variant_t &_variant_t::operator=(const char *pSrc)
858 {
859 _COM_ASSERT(V_VT(this)!=(VT_I1 | VT_BYREF) || !pSrc || V_I1REF(this)!=pSrc);
860
861 Clear();
862
863 V_VT(this) = VT_BSTR;
864 V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
865
866 return *this;
867 }
868
869 inline _variant_t &_variant_t::operator=(IDispatch *pSrc)
870 {
871 _COM_ASSERT(V_VT(this)!=VT_DISPATCH || pSrc==0 || V_DISPATCH(this)!=pSrc);
872
873 Clear();
874
875 V_VT(this) = VT_DISPATCH;
876 V_DISPATCH(this) = pSrc;
877
878 if(V_DISPATCH(this)!=NULL) {
879
880 V_DISPATCH(this)->AddRef();
881 }
882
883 return *this;
884 }
885
886 inline _variant_t &_variant_t::operator=(bool boolSrc)
887 {
888 if(V_VT(this)!=VT_BOOL) {
889
890 Clear();
891
892 V_VT(this) = VT_BOOL;
893 }
894
895 V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE);
896
897 return *this;
898 }
899
900 inline _variant_t &_variant_t::operator=(IUnknown *pSrc)
901 {
902 _COM_ASSERT(V_VT(this)!=VT_UNKNOWN || !pSrc || V_UNKNOWN(this)!=pSrc);
903
904 Clear();
905
906 V_VT(this) = VT_UNKNOWN;
907 V_UNKNOWN(this) = pSrc;
908
909 if(V_UNKNOWN(this)!=NULL) {
910
911 V_UNKNOWN(this)->AddRef();
912 }
913
914 return *this;
915 }
916
917 inline _variant_t &_variant_t::operator=(const DECIMAL &decSrc)
918 {
919 if(V_VT(this)!=VT_DECIMAL) {
920
921 Clear();
922 }
923
924 V_DECIMAL(this) = decSrc;
925 V_VT(this) = VT_DECIMAL;
926
927 return *this;
928 }
929
930 inline _variant_t &_variant_t::operator=(BYTE bSrc)
931 {
932 if(V_VT(this)!=VT_UI1) {
933
934 Clear();
935
936 V_VT(this) = VT_UI1;
937 }
938
939 V_UI1(this) = bSrc;
940
941 return *this;
942 }
943
944 inline _variant_t &_variant_t::operator=(char cSrc)
945 {
946 if(V_VT(this)!=VT_I1) {
947
948 Clear();
949
950 V_VT(this) = VT_I1;
951 }
952
953 V_I1(this) = cSrc;
954
955 return *this;
956 }
957
958 inline _variant_t &_variant_t::operator=(unsigned short usSrc)
959 {
960 if(V_VT(this)!=VT_UI2) {
961
962 Clear();
963
964 V_VT(this) = VT_UI2;
965 }
966
967 V_UI2(this) = usSrc;
968
969 return *this;
970 }
971
972 inline _variant_t &_variant_t::operator=(unsigned long ulSrc)
973 {
974 if(V_VT(this)!=VT_UI4) {
975
976 Clear();
977
978 V_VT(this) = VT_UI4;
979 }
980
981 V_UI4(this) = ulSrc;
982
983 return *this;
984 }
985
986 inline _variant_t &_variant_t::operator=(int iSrc)
987 {
988 if(V_VT(this)!=VT_INT) {
989
990 Clear();
991
992 V_VT(this) = VT_INT;
993 }
994
995 V_INT(this) = iSrc;
996
997 return *this;
998 }
999
1000 inline _variant_t &_variant_t::operator=(unsigned int uiSrc)
1001 {
1002 if(V_VT(this)!=VT_UINT) {
1003
1004 Clear();
1005
1006 V_VT(this) = VT_UINT;
1007 }
1008
1009 V_UINT(this) = uiSrc;
1010
1011 return *this;
1012 }
1013
1014 __MINGW_EXTENSION inline _variant_t &_variant_t::operator=(__int64 i8Src) {
1015 if(V_VT(this)!=VT_I8) {
1016
1017 Clear();
1018
1019 V_VT(this) = VT_I8;
1020 }
1021
1022 V_I8(this) = i8Src;
1023
1024 return *this;
1025 }
1026
1027 __MINGW_EXTENSION inline _variant_t &_variant_t::operator=(unsigned __int64 ui8Src) {
1028 if(V_VT(this)!=VT_UI8) {
1029
1030 Clear();
1031
1032 V_VT(this) = VT_UI8;
1033 }
1034
1035 V_UI8(this) = ui8Src;
1036
1037 return *this;
1038 }
1039
1040 inline bool _variant_t::operator==(const VARIANT &varSrc) const throw() {
1041 return *this==&varSrc;
1042 }
1043
1044 inline bool _variant_t::operator==(const VARIANT *pSrc) const throw()
1045 {
1046 if(!pSrc) {
1047 return false;
1048 }
1049
1050 if(this==pSrc) {
1051 return true;
1052 }
1053
1054 if(V_VT(this)!=V_VT(pSrc)) {
1055 return false;
1056 }
1057
1058 switch (V_VT(this)) {
1059 case VT_EMPTY:
1060 case VT_NULL:
1061 return true;
1062
1063 case VT_I2:
1064 return V_I2(this)==V_I2(pSrc);
1065
1066 case VT_I4:
1067 return V_I4(this)==V_I4(pSrc);
1068
1069 case VT_R4:
1070 return V_R4(this)==V_R4(pSrc);
1071
1072 case VT_R8:
1073 return V_R8(this)==V_R8(pSrc);
1074
1075 case VT_CY:
1076 return memcmp(&(V_CY(this)),&(V_CY(pSrc)),sizeof(CY))==0;
1077
1078 case VT_DATE:
1079 return V_DATE(this)==V_DATE(pSrc);
1080
1081 case VT_BSTR:
1082 return (::SysStringByteLen(V_BSTR(this))==::SysStringByteLen(V_BSTR(pSrc))) &&
1083 (memcmp(V_BSTR(this),V_BSTR(pSrc),::SysStringByteLen(V_BSTR(this)))==0);
1084
1085 case VT_DISPATCH:
1086 return V_DISPATCH(this)==V_DISPATCH(pSrc);
1087
1088 case VT_ERROR:
1089 return V_ERROR(this)==V_ERROR(pSrc);
1090
1091 case VT_BOOL:
1092 return V_BOOL(this)==V_BOOL(pSrc);
1093
1094 case VT_UNKNOWN:
1095 return V_UNKNOWN(this)==V_UNKNOWN(pSrc);
1096
1097 case VT_DECIMAL:
1098 return memcmp(&(V_DECIMAL(this)),&(V_DECIMAL(pSrc)),sizeof(DECIMAL))==0;
1099
1100 case VT_UI1:
1101 return V_UI1(this)==V_UI1(pSrc);
1102
1103 case VT_I1:
1104 return V_I1(this)==V_I1(pSrc);
1105
1106 case VT_UI2:
1107 return V_UI2(this)==V_UI2(pSrc);
1108
1109 case VT_UI4:
1110 return V_UI4(this)==V_UI4(pSrc);
1111
1112 case VT_INT:
1113 return V_INT(this)==V_INT(pSrc);
1114
1115 case VT_UINT:
1116 return V_UINT(this)==V_UINT(pSrc);
1117
1118 case VT_I8:
1119 return V_I8(this)==V_I8(pSrc);
1120
1121 case VT_UI8:
1122 return V_UI8(this)==V_UI8(pSrc);
1123
1124 default:
1125 _com_issue_error(E_INVALIDARG);
1126
1127 }
1128
1129 return false;
1130 }
1131
1132 inline bool _variant_t::operator!=(const VARIANT &varSrc) const throw()
1133 {
1134 return !(*this==&varSrc);
1135 }
1136
1137 inline bool _variant_t::operator!=(const VARIANT *pSrc) const throw()
1138 {
1139 return !(*this==pSrc);
1140 }
1141
1142 inline void _variant_t::Clear()
1143 {
1144 _com_util::CheckError(::VariantClear(this));
1145 }
1146
1147 inline void _variant_t::Attach(VARIANT &varSrc)
1148 {
1149
1150 Clear();
1151
1152 _COM_MEMCPY_S(this,sizeof(varSrc),&varSrc,sizeof(varSrc));
1153 V_VT(&varSrc) = VT_EMPTY;
1154 }
1155
1156 inline VARIANT _variant_t::Detach()
1157 {
1158 VARIANT varResult = *this;
1159 V_VT(this) = VT_EMPTY;
1160
1161 return varResult;
1162 }
1163
1164 inline VARIANT &_variant_t::GetVARIANT() throw()
1165 {
1166 return *(VARIANT*) this;
1167 }
1168
1169 inline VARIANT *_variant_t::GetAddress() {
1170 Clear();
1171 return (VARIANT*) this;
1172 }
1173 inline void _variant_t::ChangeType(VARTYPE vartype,const _variant_t *pSrc) {
1174 if(!pSrc) pSrc = this;
1175 if((this!=pSrc) || (vartype!=V_VT(this))) {
1176 _com_util::CheckError(::VariantChangeType(static_cast<VARIANT*>(this),const_cast<VARIANT*>(static_cast<const VARIANT*>(pSrc)),0,vartype));
1177 }
1178 }
1179 inline void _variant_t::SetString(const char *pSrc) { operator=(pSrc); }
1180 inline _variant_t::~_variant_t() throw() { ::VariantClear(this); }
1181 inline _bstr_t::_bstr_t(const _variant_t &var) : m_Data(NULL) {
1182 if(V_VT(&var)==VT_BSTR) {
1183 *this = V_BSTR(&var);
1184 return;
1185 }
1186 _variant_t varDest;
1187 varDest.ChangeType(VT_BSTR,&var);
1188 *this = V_BSTR(&varDest);
1189 }
1190 inline _bstr_t &_bstr_t::operator=(const _variant_t &var) {
1191 if(V_VT(&var)==VT_BSTR) {
1192 *this = V_BSTR(&var);
1193 return *this;
1194 }
1195 _variant_t varDest;
1196 varDest.ChangeType(VT_BSTR,&var);
1197 *this = V_BSTR(&varDest);
1198 return *this;
1199 }
1200
1201 extern _variant_t vtMissing;
1202
1203 #ifndef _USE_RAW
1204 #define bstr_t _bstr_t
1205 #define variant_t _variant_t
1206 #endif
1207
1208 #pragma pop_macro("new")
1209
1210 #endif /* __cplusplus */
1211
1212 #endif