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