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