Reactos
at master 1212 lines 32 kB view raw
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 35class _com_error; 36 37void WINAPI _com_issue_error(HRESULT); 38 39class _bstr_t; 40class _variant_t; 41 42namespace _com_util { 43 inline void CheckError(HRESULT hr) { 44 if(FAILED(hr)) { _com_issue_error(hr); } 45 } 46} 47 48namespace _com_util { 49 BSTR WINAPI ConvertStringToBSTR(const char *pSrc); 50 char *WINAPI ConvertBSTRToString(BSTR pSrc); 51} 52 53class _bstr_t { 54public: 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(); 88private: 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 }; 118private: 119 Data_t *m_Data; 120private: 121 void _AddRef() throw(); 122 void _Free() throw(); 123 int _Compare(const _bstr_t &str) const throw(); 124}; 125 126inline _bstr_t::_bstr_t() throw() : m_Data(NULL) { } 127 128inline _bstr_t::_bstr_t(const _bstr_t &s) throw() : m_Data(s.m_Data) { _AddRef(); } 129 130inline _bstr_t::_bstr_t(const char *s) : m_Data(new Data_t(s)) { 131 if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); } 132} 133 134inline _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 138inline _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 142inline _bstr_t::~_bstr_t() throw() { _Free(); } 143 144inline _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 153inline _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 163inline _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 173inline _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 183inline _bstr_t _bstr_t::operator+(const _bstr_t &s) const { 184 _bstr_t b = *this; 185 b += s; 186 return b; 187} 188 189inline _bstr_t operator+(const char *s1,const _bstr_t &s2) { 190 _bstr_t b = s1; 191 b += s2; 192 return b; 193} 194 195inline _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2) { 196 _bstr_t b = s1; 197 b += s2; 198 return b; 199} 200 201inline _bstr_t::operator const wchar_t *() const throw() { return (m_Data!=NULL) ? m_Data->GetWString() : NULL; } 202inline _bstr_t::operator wchar_t *() const throw() { return const_cast<wchar_t *>((m_Data!=NULL) ? m_Data->GetWString() : NULL); } 203inline _bstr_t::operator const char *() const { return (m_Data!=NULL) ? m_Data->GetString() : NULL; } 204inline _bstr_t::operator char *() const { return const_cast<char *>((m_Data!=NULL) ? m_Data->GetString() : NULL); } 205inline bool _bstr_t::operator!() const throw() { return (m_Data!=NULL) ? !m_Data->GetWString() : true; } 206inline bool _bstr_t::operator==(const _bstr_t &str) const throw() { return _Compare(str)==0; } 207inline bool _bstr_t::operator!=(const _bstr_t &str) const throw() { return _Compare(str)!=0; } 208inline bool _bstr_t::operator<(const _bstr_t &str) const throw() { return _Compare(str)<0; } 209inline bool _bstr_t::operator>(const _bstr_t &str) const throw() { return _Compare(str)>0; } 210inline bool _bstr_t::operator<=(const _bstr_t &str) const throw() { return _Compare(str)<=0; } 211inline bool _bstr_t::operator>=(const _bstr_t &str) const throw() { return _Compare(str)>=0; } 212inline BSTR _bstr_t::copy(bool fCopy) const { return (m_Data!=NULL) ? (fCopy ? m_Data->Copy() : m_Data->GetWString()) : NULL; } 213inline unsigned int _bstr_t::length() const throw() { return (m_Data!=NULL) ? m_Data->Length() : 0; } 214inline 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 223inline 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 231inline BSTR *_bstr_t::GetAddress() { 232 Attach(0); 233 return &m_Data->GetWString(); 234} 235 236inline 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 242inline 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 255inline void _bstr_t::_AddRef() throw() { 256 if(m_Data!=NULL) m_Data->AddRef(); 257} 258 259inline void _bstr_t::_Free() throw() { 260 if(m_Data!=NULL) { 261 m_Data->Release(); 262 m_Data = NULL; 263 } 264} 265 266inline 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 273inline _bstr_t::Data_t::Data_t(const char *s) : m_str(NULL),m_RefCount(1) { 274 m_wstr = _com_util::ConvertStringToBSTR(s); 275} 276 277inline _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 282inline _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 289inline _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 307inline unsigned long _bstr_t::Data_t::AddRef() throw() { 308 InterlockedIncrement(reinterpret_cast<LONG*>(&m_RefCount)); 309 return m_RefCount; 310} 311 312inline 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 318inline unsigned long _bstr_t::Data_t::RefCount() const throw() { return m_RefCount; } 319inline _bstr_t::Data_t::operator const wchar_t *() const throw() { return m_wstr; } 320inline _bstr_t::Data_t::operator const char *() const { return GetString(); } 321inline const wchar_t *_bstr_t::Data_t::GetWString() const throw() { return m_wstr; } 322inline wchar_t *&_bstr_t::Data_t::GetWString() throw() { return m_wstr; } 323inline const char *_bstr_t::Data_t::GetString() const { 324 if(!m_str) m_str = _com_util::ConvertBSTRToString(m_wstr); 325 return m_str; 326} 327inline 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} 335inline 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} 342inline void _bstr_t::Data_t::Attach(BSTR s) throw() { 343 _Free(); 344 m_wstr = s; 345 m_str = 0; 346 m_RefCount = 1; 347} 348inline unsigned int _bstr_t::Data_t::Length() const throw() { return m_wstr ? ::SysStringLen(m_wstr) : 0; } 349inline 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 365inline 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 373inline void *_bstr_t::Data_t::operator new(size_t sz) { 374 return ::operator new(sz); 375} 376#endif 377 378inline _bstr_t::Data_t::~Data_t() throw() { _Free(); } 379inline 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 384class _variant_t : public ::tagVARIANT { 385public: 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 467inline _variant_t::_variant_t() throw() { ::VariantInit(this); } 468inline _variant_t::_variant_t(const VARIANT &varSrc) { 469 ::VariantInit(this); 470 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc))); 471} 472inline _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} 479inline _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} 483inline _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(static_cast<void*>(this),sizeof(varSrc),&varSrc,sizeof(varSrc)); 489 V_VT(&varSrc) = VT_EMPTY; 490 } 491} 492inline _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} 505inline _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} 521inline _variant_t::_variant_t(float fltSrc) throw() { 522 V_VT(this) = VT_R4; 523 V_R4(this) = fltSrc; 524} 525 526inline _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} 539inline _variant_t::_variant_t(const CY &cySrc) throw() { 540 V_VT(this) = VT_CY; 541 V_CY(this) = cySrc; 542} 543inline _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} 552inline _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} 557inline _variant_t::_variant_t(const char *pSrc) { 558 V_VT(this) = VT_BSTR; 559 V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc); 560} 561inline _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} 566inline _variant_t::_variant_t(bool boolSrc) throw() { 567 V_VT(this) = VT_BOOL; 568 V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE); 569} 570inline _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} 575inline _variant_t::_variant_t(const DECIMAL &decSrc) throw() { 576 V_DECIMAL(this) = decSrc; 577 V_VT(this) = VT_DECIMAL; 578} 579inline _variant_t::_variant_t(BYTE bSrc) throw() { 580 V_VT(this) = VT_UI1; 581 V_UI1(this) = bSrc; 582} 583inline _variant_t::_variant_t(char cSrc) throw() { 584 V_VT(this) = VT_I1; 585 V_I1(this) = cSrc; 586} 587inline _variant_t::_variant_t(unsigned short usSrc) throw() { 588 V_VT(this) = VT_UI2; 589 V_UI2(this) = usSrc; 590} 591inline _variant_t::_variant_t(unsigned long ulSrc) throw() { 592 V_VT(this) = VT_UI4; 593 V_UI4(this) = ulSrc; 594} 595inline _variant_t::_variant_t(int iSrc) throw() { 596 V_VT(this) = VT_INT; 597 V_INT(this) = iSrc; 598} 599inline _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} 611inline _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} 617inline _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 624inline _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 631inline _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 638inline _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 645inline _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 652inline _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} 662inline _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 669inline _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} 679inline _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} 685inline _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} 691inline _variant_t::operator VARIANT() const throw() { return *(VARIANT*) this; } 692inline _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 699inline _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 706inline _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} 712inline _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} 718inline _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} 736inline _variant_t &_variant_t::operator=(const VARIANT &varSrc) { 737 _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc))); 738 return *this; 739} 740inline _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} 745inline _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} 749inline _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} 759inline _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} 770inline _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 779inline _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 798inline _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 812inline _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 835inline _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 857inline _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 869inline _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 886inline _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 900inline _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 917inline _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 930inline _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 944inline _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 958inline _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 972inline _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 986inline _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 1000inline _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 1040inline bool _variant_t::operator==(const VARIANT &varSrc) const throw() { 1041 return *this==&varSrc; 1042} 1043 1044inline 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)) { 1059case VT_EMPTY: 1060case VT_NULL: 1061 return true; 1062 1063case VT_I2: 1064 return V_I2(this)==V_I2(pSrc); 1065 1066case VT_I4: 1067 return V_I4(this)==V_I4(pSrc); 1068 1069case VT_R4: 1070 return V_R4(this)==V_R4(pSrc); 1071 1072case VT_R8: 1073 return V_R8(this)==V_R8(pSrc); 1074 1075case VT_CY: 1076 return memcmp(&(V_CY(this)),&(V_CY(pSrc)),sizeof(CY))==0; 1077 1078case VT_DATE: 1079 return V_DATE(this)==V_DATE(pSrc); 1080 1081case 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 1085case VT_DISPATCH: 1086 return V_DISPATCH(this)==V_DISPATCH(pSrc); 1087 1088case VT_ERROR: 1089 return V_ERROR(this)==V_ERROR(pSrc); 1090 1091case VT_BOOL: 1092 return V_BOOL(this)==V_BOOL(pSrc); 1093 1094case VT_UNKNOWN: 1095 return V_UNKNOWN(this)==V_UNKNOWN(pSrc); 1096 1097case VT_DECIMAL: 1098 return memcmp(&(V_DECIMAL(this)),&(V_DECIMAL(pSrc)),sizeof(DECIMAL))==0; 1099 1100case VT_UI1: 1101 return V_UI1(this)==V_UI1(pSrc); 1102 1103case VT_I1: 1104 return V_I1(this)==V_I1(pSrc); 1105 1106case VT_UI2: 1107 return V_UI2(this)==V_UI2(pSrc); 1108 1109case VT_UI4: 1110 return V_UI4(this)==V_UI4(pSrc); 1111 1112case VT_INT: 1113 return V_INT(this)==V_INT(pSrc); 1114 1115case VT_UINT: 1116 return V_UINT(this)==V_UINT(pSrc); 1117 1118case VT_I8: 1119 return V_I8(this)==V_I8(pSrc); 1120 1121case VT_UI8: 1122 return V_UI8(this)==V_UI8(pSrc); 1123 1124default: 1125 _com_issue_error(E_INVALIDARG); 1126 1127 } 1128 1129 return false; 1130} 1131 1132inline bool _variant_t::operator!=(const VARIANT &varSrc) const throw() 1133{ 1134 return !(*this==&varSrc); 1135} 1136 1137inline bool _variant_t::operator!=(const VARIANT *pSrc) const throw() 1138{ 1139 return !(*this==pSrc); 1140} 1141 1142inline void _variant_t::Clear() 1143{ 1144 _com_util::CheckError(::VariantClear(this)); 1145} 1146 1147inline void _variant_t::Attach(VARIANT &varSrc) 1148{ 1149 1150 Clear(); 1151 1152 _COM_MEMCPY_S(static_cast<void*>(this),sizeof(varSrc),&varSrc,sizeof(varSrc)); 1153 V_VT(&varSrc) = VT_EMPTY; 1154} 1155 1156inline VARIANT _variant_t::Detach() 1157{ 1158 VARIANT varResult = *this; 1159 V_VT(this) = VT_EMPTY; 1160 1161 return varResult; 1162} 1163 1164inline VARIANT &_variant_t::GetVARIANT() throw() 1165{ 1166 return *(VARIANT*) this; 1167} 1168 1169inline VARIANT *_variant_t::GetAddress() { 1170 Clear(); 1171 return (VARIANT*) this; 1172} 1173inline 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} 1179inline void _variant_t::SetString(const char *pSrc) { operator=(pSrc); } 1180inline _variant_t::~_variant_t() throw() { ::VariantClear(this); } 1181inline _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} 1190inline _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 1201extern _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