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