comutil.h 31 KB

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