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