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.
12 #define _COM_ASSERT(x) ((void)0)
15 #define _COM_MEMCPY_S(dest,destsize,src,count) memcpy(dest,src,count)
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)
23 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) sprintf_s(dest,destsize,format,arg1)
28 #pragma push_macro("new")
32 #define WINAPI __stdcall
37 void WINAPI
_com_issue_error(HRESULT
);
43 inline void CheckError(HRESULT hr
) {
44 if(FAILED(hr
)) { _com_issue_error(hr
); }
49 BSTR WINAPI
ConvertStringToBSTR(const char *pSrc
);
50 char *WINAPI
ConvertBSTRToString(BSTR pSrc
);
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
);
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();
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;
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
);
112 unsigned long m_RefCount
;
114 Data_t(const Data_t
&s
) throw();
116 void _Free() throw();
121 void _AddRef() throw();
122 void _Free() throw();
123 int _Compare(const _bstr_t
&str
) const throw();
126 inline _bstr_t::_bstr_t() throw() : m_Data(NULL
) { }
128 inline _bstr_t::_bstr_t(const _bstr_t
&s
) throw() : m_Data(s
.m_Data
) { _AddRef(); }
130 inline _bstr_t::_bstr_t(const char *s
) : m_Data(new Data_t(s
)) {
131 if(!m_Data
) { _com_issue_error(E_OUTOFMEMORY
); }
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
); }
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
); }
142 inline _bstr_t::~_bstr_t() throw() { _Free(); }
144 inline _bstr_t
&_bstr_t::operator=(const _bstr_t
&s
) throw() {
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
) {
157 m_Data
= new Data_t(s
);
158 if(!m_Data
) { _com_issue_error(E_OUTOFMEMORY
); }
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
) {
167 m_Data
= new Data_t(s
);
168 if(!m_Data
) { _com_issue_error(E_OUTOFMEMORY
); }
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
); }
183 inline _bstr_t
_bstr_t::operator+(const _bstr_t
&s
) const {
189 inline _bstr_t
operator+(const char *s1
,const _bstr_t
&s2
) {
195 inline _bstr_t
operator+(const wchar_t *s1
,const _bstr_t
&s2
) {
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
) {
218 m_Data
= new Data_t(s
,TRUE
);
219 if(!m_Data
) { _com_issue_error(E_OUTOFMEMORY
); }
223 inline BSTR
&_bstr_t::GetBSTR() {
225 m_Data
= new Data_t(0,FALSE
);
226 if(!m_Data
) { _com_issue_error(E_OUTOFMEMORY
); }
228 return m_Data
->GetWString();
231 inline BSTR
*_bstr_t::GetAddress() {
233 return &m_Data
->GetWString();
236 inline void _bstr_t::Attach(BSTR s
) {
238 m_Data
= new Data_t(s
,FALSE
);
239 if(!m_Data
) { _com_issue_error(E_OUTOFMEMORY
); }
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
;
250 _com_issue_error(E_POINTER
);
255 inline void _bstr_t::_AddRef() throw() {
256 if(m_Data
!=NULL
) m_Data
->AddRef();
259 inline void _bstr_t::_Free() throw() {
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
);
273 inline _bstr_t::Data_t::Data_t(const char *s
) : m_str(NULL
),m_RefCount(1) {
274 m_wstr
= _com_util::ConvertStringToBSTR(s
);
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
); }
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
;
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));
294 _com_issue_error(E_OUTOFMEMORY
);
297 const wchar_t *wstr1
= static_cast<const wchar_t *>(s1
);
299 _COM_MEMCPY_S(m_wstr
,(l1
+ l2
+ 1) *sizeof(wchar_t),wstr1
,(l1
+ 1) *sizeof(wchar_t));
301 const wchar_t *wstr2
= static_cast<const wchar_t *>(s2
);
303 _COM_MEMCPY_S(m_wstr
+ l1
,(l2
+ 1) *sizeof(wchar_t),wstr2
,(l2
+ 1) *sizeof(wchar_t));
307 inline unsigned long _bstr_t::Data_t::AddRef() throw() {
308 InterlockedIncrement(reinterpret_cast<LONG
*>(&m_RefCount
));
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;
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
);
327 inline BSTR
_bstr_t::Data_t::Copy() const {
329 BSTR bstr
= ::SysAllocStringByteLen(reinterpret_cast<char *>(m_wstr
),::SysStringByteLen(m_wstr
));
330 if(!bstr
) { _com_issue_error(E_OUTOFMEMORY
); }
335 inline void _bstr_t::Data_t::Assign(BSTR s
) {
338 m_wstr
= ::SysAllocStringByteLen(reinterpret_cast<char *>(s
),::SysStringByteLen(s
));
342 inline void _bstr_t::Data_t::Attach(BSTR s
) throw() {
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
;
357 BSTR bstr2
= str
.m_wstr
;
359 if(*bstr1
++!=*bstr2
++) return bstr1
[-1] - bstr2
[-1];
361 return (l1
<l2
) ? -1 : (l1
==l2
) ? 0 : 1;
364 #ifdef _COM_OPERATOR_NEW_THROWS
365 inline void *_bstr_t::Data_t::operator new(size_t sz
) {
367 return ::operator new(sz
);
373 inline void *_bstr_t::Data_t::operator new(size_t sz
) {
374 return ::operator new(sz
);
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
;
384 class _variant_t
: public ::tagVARIANT
{
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;
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();
459 void Attach(VARIANT
&varSrc
);
461 VARIANT
&GetVARIANT() throw();
462 VARIANT
*GetAddress();
463 void ChangeType(VARTYPE vartype
,const _variant_t
*pSrc
= NULL
);
464 void SetString(const char *pSrc
);
467 inline _variant_t::_variant_t() throw() { ::VariantInit(this); }
468 inline _variant_t::_variant_t(const VARIANT
&varSrc
) {
470 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT
*>(&varSrc
)));
472 inline _variant_t::_variant_t(const VARIANT
*pSrc
) {
473 if(!pSrc
) { _com_issue_error(E_POINTER
); }
476 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT
*>(pSrc
)));
479 inline _variant_t::_variant_t(const _variant_t
&varSrc
) {
481 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT
*>(static_cast<const VARIANT
*>(&varSrc
))));
483 inline _variant_t::_variant_t(VARIANT
&varSrc
,bool fCopy
) {
486 _com_util::CheckError(::VariantCopy(this,&varSrc
));
488 _COM_MEMCPY_S(this,sizeof(varSrc
),&varSrc
,sizeof(varSrc
));
489 V_VT(&varSrc
) = VT_EMPTY
;
492 inline _variant_t::_variant_t(short sSrc
,VARTYPE vtSrc
) {
493 if((vtSrc
!=VT_I2
) && (vtSrc
!=VT_BOOL
)) {
494 _com_issue_error(E_INVALIDARG
);
498 V_VT(this) = VT_BOOL
;
499 V_BOOL(this) = (sSrc
? VARIANT_TRUE
: VARIANT_FALSE
);
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
);
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
);
521 inline _variant_t::_variant_t(float fltSrc
) throw() {
526 inline _variant_t::_variant_t(double dblSrc
,VARTYPE vtSrc
) {
527 if((vtSrc
!=VT_R8
) && (vtSrc
!=VT_DATE
)) {
528 _com_issue_error(E_INVALIDARG
);
532 V_VT(this) = VT_DATE
;
533 V_DATE(this) = dblSrc
;
539 inline _variant_t::_variant_t(const CY
&cySrc
) throw() {
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
;
548 V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr
),::SysStringByteLen(bstr
));
549 if(!(V_BSTR(this))) { _com_issue_error(E_OUTOFMEMORY
); }
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
); }
557 inline _variant_t::_variant_t(const char *pSrc
) {
558 V_VT(this) = VT_BSTR
;
559 V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc
);
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();
566 inline _variant_t::_variant_t(bool boolSrc
) throw() {
567 V_VT(this) = VT_BOOL
;
568 V_BOOL(this) = (boolSrc
? VARIANT_TRUE
: VARIANT_FALSE
);
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();
575 inline _variant_t::_variant_t(const DECIMAL
&decSrc
) throw() {
576 V_DECIMAL(this) = decSrc
;
577 V_VT(this) = VT_DECIMAL
;
579 inline _variant_t::_variant_t(BYTE bSrc
) throw() {
583 inline _variant_t::_variant_t(char cSrc
) throw() {
587 inline _variant_t::_variant_t(unsigned short usSrc
) throw() {
591 inline _variant_t::_variant_t(unsigned long ulSrc
) throw() {
595 inline _variant_t::_variant_t(int iSrc
) throw() {
599 inline _variant_t::_variant_t(unsigned int uiSrc
) throw() {
600 V_VT(this) = VT_UINT
;
601 V_UINT(this) = uiSrc
;
603 __MINGW_EXTENSION
inline _variant_t::_variant_t(__int64 i8Src
) throw() {
607 __MINGW_EXTENSION
inline _variant_t::_variant_t(unsigned __int64 ui8Src
) throw() {
609 V_UI8(this) = ui8Src
;
611 inline _variant_t::operator short() const {
612 if(V_VT(this)==VT_I2
) return V_I2(this);
614 varDest
.ChangeType(VT_I2
,this);
615 return V_I2(&varDest
);
617 inline _variant_t::operator long() const {
618 if(V_VT(this)==VT_I4
) return V_I4(this);
620 varDest
.ChangeType(VT_I4
,this);
621 return V_I4(&varDest
);
624 inline _variant_t::operator float() const {
625 if(V_VT(this)==VT_R4
) return V_R4(this);
627 varDest
.ChangeType(VT_R4
,this);
628 return V_R4(&varDest
);
631 inline _variant_t::operator double() const {
632 if(V_VT(this)==VT_R8
) return V_R8(this);
634 varDest
.ChangeType(VT_R8
,this);
635 return V_R8(&varDest
);
638 inline _variant_t::operator CY() const {
639 if(V_VT(this)==VT_CY
) return V_CY(this);
641 varDest
.ChangeType(VT_CY
,this);
642 return V_CY(&varDest
);
645 inline _variant_t::operator _bstr_t() const {
646 if(V_VT(this)==VT_BSTR
) return V_BSTR(this);
648 varDest
.ChangeType(VT_BSTR
,this);
649 return V_BSTR(&varDest
);
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);
658 varDest
.ChangeType(VT_DISPATCH
,this);
659 if(V_DISPATCH(&varDest
)!=NULL
) V_DISPATCH(&varDest
)->AddRef();
660 return V_DISPATCH(&varDest
);
662 inline _variant_t::operator bool() const {
663 if(V_VT(this)==VT_BOOL
) return V_BOOL(this) ? true : false;
665 varDest
.ChangeType(VT_BOOL
,this);
666 return (V_BOOL(&varDest
)==VARIANT_TRUE
) ? true : false;
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);
675 varDest
.ChangeType(VT_UNKNOWN
,this);
676 if(V_UNKNOWN(&varDest
)!=NULL
) V_UNKNOWN(&varDest
)->AddRef();
677 return V_UNKNOWN(&varDest
);
679 inline _variant_t::operator DECIMAL() const {
680 if(V_VT(this)==VT_DECIMAL
) return V_DECIMAL(this);
682 varDest
.ChangeType(VT_DECIMAL
,this);
683 return V_DECIMAL(&varDest
);
685 inline _variant_t::operator BYTE() const {
686 if(V_VT(this)==VT_UI1
) return V_UI1(this);
688 varDest
.ChangeType(VT_UI1
,this);
689 return V_UI1(&varDest
);
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);
695 varDest
.ChangeType(VT_I1
,this);
696 return V_I1(&varDest
);
699 inline _variant_t::operator unsigned short() const {
700 if(V_VT(this)==VT_UI2
) return V_UI2(this);
702 varDest
.ChangeType(VT_UI2
,this);
703 return V_UI2(&varDest
);
706 inline _variant_t::operator unsigned long() const {
707 if(V_VT(this)==VT_UI4
) return V_UI4(this);
709 varDest
.ChangeType(VT_UI4
,this);
710 return V_UI4(&varDest
);
712 inline _variant_t::operator int() const {
713 if(V_VT(this)==VT_INT
) return V_INT(this);
715 varDest
.ChangeType(VT_INT
,this);
716 return V_INT(&varDest
);
718 inline _variant_t::operator unsigned int() const {
719 if(V_VT(this)==VT_UINT
) return V_UINT(this);
721 varDest
.ChangeType(VT_UINT
,this);
722 return V_UINT(&varDest
);
724 __MINGW_EXTENSION
inline _variant_t::operator __int64() const {
725 if(V_VT(this)==VT_I8
) return V_I8(this);
727 varDest
.ChangeType(VT_I8
,this);
728 return V_I8(&varDest
);
730 __MINGW_EXTENSION
inline _variant_t::operator unsigned __int64() const {
731 if(V_VT(this)==VT_UI8
) return V_UI8(this);
733 varDest
.ChangeType(VT_UI8
,this);
734 return V_UI8(&varDest
);
736 inline _variant_t
&_variant_t::operator=(const VARIANT
&varSrc
) {
737 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT
*>(&varSrc
)));
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
))); }
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
))));
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
);
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
);
770 inline _variant_t
&_variant_t::operator=(float fltSrc
) {
771 if(V_VT(this)!=VT_R4
) {
779 inline _variant_t
&_variant_t::operator=(double dblSrc
)
781 if(V_VT(this)==VT_R8
) {
784 else if(V_VT(this)==VT_DATE
) {
785 V_DATE(this) = dblSrc
;
798 inline _variant_t
&_variant_t::operator=(const CY
&cySrc
)
800 if(V_VT(this)!=VT_CY
) {
812 inline _variant_t
&_variant_t::operator=(const _bstr_t
&bstrSrc
)
814 _COM_ASSERT(V_VT(this)!=VT_BSTR
|| !((BSTR
) bstrSrc
) || V_BSTR(this)!=(BSTR
) bstrSrc
);
818 V_VT(this) = VT_BSTR
;
824 BSTR bstr
= static_cast<wchar_t *>(bstrSrc
);
825 V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr
),::SysStringByteLen(bstr
));
827 if(!(V_BSTR(this))) {
828 _com_issue_error(E_OUTOFMEMORY
);
835 inline _variant_t
&_variant_t::operator=(const wchar_t *pSrc
)
837 _COM_ASSERT(V_VT(this)!=VT_BSTR
|| !pSrc
|| V_BSTR(this)!=pSrc
);
841 V_VT(this) = VT_BSTR
;
847 V_BSTR(this) = ::SysAllocString(pSrc
);
849 if(!(V_BSTR(this))) {
850 _com_issue_error(E_OUTOFMEMORY
);
857 inline _variant_t
&_variant_t::operator=(const char *pSrc
)
859 _COM_ASSERT(V_VT(this)!=(VT_I1
| VT_BYREF
) || !pSrc
|| V_I1REF(this)!=pSrc
);
863 V_VT(this) = VT_BSTR
;
864 V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc
);
869 inline _variant_t
&_variant_t::operator=(IDispatch
*pSrc
)
871 _COM_ASSERT(V_VT(this)!=VT_DISPATCH
|| pSrc
==0 || V_DISPATCH(this)!=pSrc
);
875 V_VT(this) = VT_DISPATCH
;
876 V_DISPATCH(this) = pSrc
;
878 if(V_DISPATCH(this)!=NULL
) {
880 V_DISPATCH(this)->AddRef();
886 inline _variant_t
&_variant_t::operator=(bool boolSrc
)
888 if(V_VT(this)!=VT_BOOL
) {
892 V_VT(this) = VT_BOOL
;
895 V_BOOL(this) = (boolSrc
? VARIANT_TRUE
: VARIANT_FALSE
);
900 inline _variant_t
&_variant_t::operator=(IUnknown
*pSrc
)
902 _COM_ASSERT(V_VT(this)!=VT_UNKNOWN
|| !pSrc
|| V_UNKNOWN(this)!=pSrc
);
906 V_VT(this) = VT_UNKNOWN
;
907 V_UNKNOWN(this) = pSrc
;
909 if(V_UNKNOWN(this)!=NULL
) {
911 V_UNKNOWN(this)->AddRef();
917 inline _variant_t
&_variant_t::operator=(const DECIMAL
&decSrc
)
919 if(V_VT(this)!=VT_DECIMAL
) {
924 V_DECIMAL(this) = decSrc
;
925 V_VT(this) = VT_DECIMAL
;
930 inline _variant_t
&_variant_t::operator=(BYTE bSrc
)
932 if(V_VT(this)!=VT_UI1
) {
944 inline _variant_t
&_variant_t::operator=(char cSrc
)
946 if(V_VT(this)!=VT_I1
) {
958 inline _variant_t
&_variant_t::operator=(unsigned short usSrc
)
960 if(V_VT(this)!=VT_UI2
) {
972 inline _variant_t
&_variant_t::operator=(unsigned long ulSrc
)
974 if(V_VT(this)!=VT_UI4
) {
986 inline _variant_t
&_variant_t::operator=(int iSrc
)
988 if(V_VT(this)!=VT_INT
) {
1000 inline _variant_t
&_variant_t::operator=(unsigned int uiSrc
)
1002 if(V_VT(this)!=VT_UINT
) {
1006 V_VT(this) = VT_UINT
;
1009 V_UINT(this) = uiSrc
;
1014 __MINGW_EXTENSION
inline _variant_t
&_variant_t::operator=(__int64 i8Src
) {
1015 if(V_VT(this)!=VT_I8
) {
1027 __MINGW_EXTENSION
inline _variant_t
&_variant_t::operator=(unsigned __int64 ui8Src
) {
1028 if(V_VT(this)!=VT_UI8
) {
1032 V_VT(this) = VT_UI8
;
1035 V_UI8(this) = ui8Src
;
1040 inline bool _variant_t::operator==(const VARIANT
&varSrc
) const throw() {
1041 return *this==&varSrc
;
1044 inline bool _variant_t::operator==(const VARIANT
*pSrc
) const throw()
1054 if(V_VT(this)!=V_VT(pSrc
)) {
1058 switch (V_VT(this)) {
1064 return V_I2(this)==V_I2(pSrc
);
1067 return V_I4(this)==V_I4(pSrc
);
1070 return V_R4(this)==V_R4(pSrc
);
1073 return V_R8(this)==V_R8(pSrc
);
1076 return memcmp(&(V_CY(this)),&(V_CY(pSrc
)),sizeof(CY
))==0;
1079 return V_DATE(this)==V_DATE(pSrc
);
1082 return (::SysStringByteLen(V_BSTR(this))==::SysStringByteLen(V_BSTR(pSrc
))) &&
1083 (memcmp(V_BSTR(this),V_BSTR(pSrc
),::SysStringByteLen(V_BSTR(this)))==0);
1086 return V_DISPATCH(this)==V_DISPATCH(pSrc
);
1089 return V_ERROR(this)==V_ERROR(pSrc
);
1092 return V_BOOL(this)==V_BOOL(pSrc
);
1095 return V_UNKNOWN(this)==V_UNKNOWN(pSrc
);
1098 return memcmp(&(V_DECIMAL(this)),&(V_DECIMAL(pSrc
)),sizeof(DECIMAL
))==0;
1101 return V_UI1(this)==V_UI1(pSrc
);
1104 return V_I1(this)==V_I1(pSrc
);
1107 return V_UI2(this)==V_UI2(pSrc
);
1110 return V_UI4(this)==V_UI4(pSrc
);
1113 return V_INT(this)==V_INT(pSrc
);
1116 return V_UINT(this)==V_UINT(pSrc
);
1119 return V_I8(this)==V_I8(pSrc
);
1122 return V_UI8(this)==V_UI8(pSrc
);
1125 _com_issue_error(E_INVALIDARG
);
1132 inline bool _variant_t::operator!=(const VARIANT
&varSrc
) const throw()
1134 return !(*this==&varSrc
);
1137 inline bool _variant_t::operator!=(const VARIANT
*pSrc
) const throw()
1139 return !(*this==pSrc
);
1142 inline void _variant_t::Clear()
1144 _com_util::CheckError(::VariantClear(this));
1147 inline void _variant_t::Attach(VARIANT
&varSrc
)
1152 _COM_MEMCPY_S(this,sizeof(varSrc
),&varSrc
,sizeof(varSrc
));
1153 V_VT(&varSrc
) = VT_EMPTY
;
1156 inline VARIANT
_variant_t::Detach()
1158 VARIANT varResult
= *this;
1159 V_VT(this) = VT_EMPTY
;
1164 inline VARIANT
&_variant_t::GetVARIANT() throw()
1166 return *(VARIANT
*) this;
1169 inline VARIANT
*_variant_t::GetAddress() {
1171 return (VARIANT
*) this;
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
));
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
);
1187 varDest
.ChangeType(VT_BSTR
,&var
);
1188 *this = V_BSTR(&varDest
);
1190 inline _bstr_t
&_bstr_t::operator=(const _variant_t
&var
) {
1191 if(V_VT(&var
)==VT_BSTR
) {
1192 *this = V_BSTR(&var
);
1196 varDest
.ChangeType(VT_BSTR
,&var
);
1197 *this = V_BSTR(&varDest
);
1201 extern _variant_t vtMissing
;
1204 #define bstr_t _bstr_t
1205 #define variant_t _variant_t
1208 #pragma pop_macro("new")
1210 #endif /* __cplusplus */