home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / comutil.h < prev    next >
C/C++ Source or Header  |  2000-02-01  |  44KB  |  1,796 lines

  1. /***
  2. * comutil.h - Native C++ compiler COM support - BSTR, VARIANT wrappers header
  3. *
  4. *    Copyright (C) 1996-1997 Microsoft Corporation
  5. *    All rights reserved.
  6. *
  7. ****/
  8.  
  9. #if !defined(_INC_COMUTIL)
  10. #pragma option push -b -a8 -pc -A- -w-inl /*P_O_Push __BORLANDC__: This file was forgotten in the PSDK so it was taken from the VC++ 6.0 */
  11. #define _INC_COMUTIL
  12.  
  13. #if _MSC_VER > 1000
  14. #pragma once
  15. #endif
  16.  
  17. #include <ole2.h>
  18.  
  19. #pragma warning(push)
  20. #pragma warning(disable:4290)
  21. #pragma warning(disable:4310)
  22.  
  23. class _com_error;
  24.  
  25. void __stdcall _com_issue_error(HRESULT)
  26. #ifdef __BORLANDC__
  27. throw(_com_error)
  28. #endif
  29. ;
  30.  
  31. //////////////////////////////////////////////////////////////////////////////
  32. //
  33. // Forward class declarations
  34. //
  35. //////////////////////////////////////////////////////////////////////////////
  36.  
  37. class _bstr_t;
  38. class _variant_t;
  39.  
  40. //////////////////////////////////////////////////////////////////////////////
  41. //
  42. // Error checking routines
  43. //
  44. //////////////////////////////////////////////////////////////////////////////
  45.  
  46. namespace _com_util {
  47.     inline void CheckError(HRESULT hr) throw(_com_error)
  48.     {
  49.         if (FAILED(hr)) {
  50.             _com_issue_error(hr);
  51.         }
  52.     }
  53. }
  54.  
  55. //////////////////////////////////////////////////////////////////////////////
  56. //
  57. // Routines for handling conversions between BSTR and char*
  58. //
  59. //////////////////////////////////////////////////////////////////////////////
  60.  
  61. namespace _com_util {
  62.     // Convert char * to BSTR
  63.     //
  64.     BSTR __stdcall ConvertStringToBSTR(const char* pSrc) throw(_com_error);
  65.  
  66.     // Convert BSTR to char *
  67.     //
  68.     char* __stdcall ConvertBSTRToString(BSTR pSrc) throw(_com_error);
  69. }
  70.  
  71. //////////////////////////////////////////////////////////////////////////////
  72. //
  73. // Wrapper class for BSTR
  74. //
  75. //////////////////////////////////////////////////////////////////////////////
  76.  
  77. class _bstr_t {
  78. public:
  79.     // Constructors
  80.     //
  81.     _bstr_t() throw();
  82.     _bstr_t(const _bstr_t& s) throw();
  83.     _bstr_t(const char* s) throw(_com_error);
  84.     _bstr_t(const wchar_t* s) throw(_com_error);
  85.     _bstr_t(const _variant_t& var) throw(_com_error);
  86.     _bstr_t(BSTR bstr, bool fCopy) throw(_com_error);
  87.  
  88.     // Destructor
  89.     //
  90.     ~_bstr_t() throw();
  91.  
  92.     // Assignment operators
  93.     //
  94.     _bstr_t& operator=(const _bstr_t& s) throw();
  95.     _bstr_t& operator=(const char* s) throw(_com_error);
  96.     _bstr_t& operator=(const wchar_t* s) throw(_com_error);
  97.     _bstr_t& operator=(const _variant_t& var) throw(_com_error);
  98.  
  99.     // Operators
  100.     //
  101.     _bstr_t& operator+=(const _bstr_t& s) throw(_com_error);
  102.     _bstr_t operator+(const _bstr_t& s) const throw(_com_error);
  103.  
  104.     // Friend operators
  105.     //
  106.     friend _bstr_t operator+(const char* s1, const _bstr_t& s2) throw(_com_error);
  107.     friend _bstr_t operator+(const wchar_t* s1, const _bstr_t& s2) throw(_com_error);
  108.  
  109.     // Extractors
  110.     //
  111.     operator const wchar_t*() const throw();
  112.     operator wchar_t*() const throw();
  113.     operator const char*() const throw(_com_error);
  114.     operator char*() const throw(_com_error);
  115.  
  116.     // Comparison operators
  117.     //
  118.     bool operator!() const throw();
  119.     bool operator==(const _bstr_t& str) const throw();
  120.     bool operator!=(const _bstr_t& str) const throw();
  121.     bool operator<(const _bstr_t& str) const throw();
  122.     bool operator>(const _bstr_t& str) const throw();
  123.     bool operator<=(const _bstr_t& str) const throw();
  124.     bool operator>=(const _bstr_t& str) const throw();
  125.  
  126.     // Low-level helper functions
  127.     //
  128.     BSTR copy() const throw(_com_error);
  129.     unsigned int length() const throw();
  130.  
  131.     // Binary string assign
  132.     //
  133.     void Assign(BSTR s) throw(_com_error);
  134.  
  135. private:
  136.     // Referenced counted wrapper
  137.     //
  138.     class Data_t {
  139.     public:
  140.         // Constructors
  141.         //
  142.         Data_t(const char* s) throw(_com_error);
  143.         Data_t(const wchar_t* s) throw(_com_error);
  144.         Data_t(BSTR bstr, bool fCopy) throw(_com_error);
  145.         Data_t(const _bstr_t& s1, const _bstr_t& s2) throw(_com_error);
  146.  
  147.         // Reference counting routines
  148.         //
  149.         unsigned long AddRef() throw();
  150.         unsigned long Release() throw();
  151.  
  152.         // Extractors
  153.         //
  154.         operator const wchar_t*() const throw();
  155.         operator const char*() const throw(_com_error);
  156.  
  157.         // Low-level helper functions
  158.         //
  159.         const wchar_t* GetWString() const throw();
  160.         const char* GetString() const throw(_com_error);
  161.  
  162.         BSTR Copy() const throw(_com_error);
  163.         void Assign(BSTR s) throw(_com_error);
  164.         unsigned int Length() const throw();
  165.         int Compare(const Data_t& str) const throw();
  166.  
  167.     private:
  168.         wchar_t*        m_wstr;
  169.         mutable char*    m_str;
  170.         unsigned long    m_RefCount;
  171.  
  172.         // Never allow default construction
  173.         //
  174.         Data_t() throw();
  175.  
  176.         // Never allow copy
  177.         //
  178.         Data_t(const Data_t& s) throw();
  179.  
  180.         // Prevent deletes from outside. Release() must be used.
  181.         //
  182.         ~Data_t() throw();
  183.  
  184.         void _Free() throw();
  185.     };
  186.  
  187. private:
  188.     // Reference counted representation
  189.     //
  190.     Data_t* m_Data;
  191.  
  192. private:
  193.     // Low-level utilities
  194.     //
  195.     void _AddRef() throw();
  196.     void _Free() throw();
  197.     int _Compare(const _bstr_t& str) const throw();
  198. };
  199.  
  200. //////////////////////////////////////////////////////////////////////////////
  201. //
  202. // Constructors
  203. //
  204. //////////////////////////////////////////////////////////////////////////////
  205.  
  206. // Default constructor
  207. //
  208. inline _bstr_t::_bstr_t() throw()
  209.     : m_Data(NULL)
  210. {
  211. }
  212.  
  213. // Copy constructor
  214. //
  215. inline _bstr_t::_bstr_t(const _bstr_t& s) throw()
  216.     : m_Data(s.m_Data)
  217. {
  218.     _AddRef();
  219. }
  220.  
  221. // Construct a _bstr_t from a const char*
  222. //
  223. inline _bstr_t::_bstr_t(const char* s) throw(_com_error)
  224.     : m_Data(new Data_t(s))
  225. {
  226.     if (m_Data == NULL) {
  227.         _com_issue_error(E_OUTOFMEMORY);
  228.     }
  229. }
  230.  
  231. // Construct a _bstr_t from a const whar_t*
  232. //
  233. inline _bstr_t::_bstr_t(const wchar_t* s) throw(_com_error)
  234.     : m_Data(new Data_t(s))
  235. {
  236.     if (m_Data == NULL) {
  237.         _com_issue_error(E_OUTOFMEMORY);
  238.     }
  239. }
  240.  
  241. // Construct a _bstr_t from a BSTR.  If fCopy is FALSE, give control of
  242. // data to the _bstr_t without making a new copy.
  243. //
  244. inline _bstr_t::_bstr_t(BSTR bstr, bool fCopy) throw(_com_error)
  245.     : m_Data(new Data_t(bstr, fCopy))
  246. {
  247.     if (m_Data == NULL) {
  248.         _com_issue_error(E_OUTOFMEMORY);
  249.     }
  250. }
  251.  
  252. // Destructor
  253. //
  254. inline _bstr_t::~_bstr_t() throw()
  255. {
  256.     _Free();
  257. }
  258.  
  259. //////////////////////////////////////////////////////////////////////////////
  260. //
  261. // Assignment operators
  262. //
  263. //////////////////////////////////////////////////////////////////////////////
  264.  
  265. // Default assign operator
  266. //
  267. inline _bstr_t& _bstr_t::operator=(const _bstr_t& s) throw()
  268. {
  269.     const_cast<_bstr_t*>(&s)->_AddRef();
  270.     _Free();
  271.     m_Data = s.m_Data;
  272.  
  273.     return *this;
  274. }
  275.  
  276. // Assign a const char* to a _bstr_t
  277. //
  278. inline _bstr_t& _bstr_t::operator=(const char* s) throw(_com_error)
  279. {
  280.     _Free();
  281.     m_Data = new Data_t(s);
  282.  
  283.     return *this;
  284. }
  285.  
  286. // Assign a const wchar_t* to a _bstr_t
  287. //
  288. inline _bstr_t& _bstr_t::operator=(const wchar_t* s) throw(_com_error)
  289. {
  290.     _Free();
  291.     m_Data = new Data_t(s);
  292.  
  293.     return *this;
  294. }
  295.  
  296. //////////////////////////////////////////////////////////////////////////////
  297. //
  298. // Operators
  299. //
  300. //////////////////////////////////////////////////////////////////////////////
  301.  
  302. // Concatenate a _bstr_t onto this _bstr_t
  303. //
  304. inline _bstr_t& _bstr_t::operator+=(const _bstr_t& s) throw(_com_error)
  305. {
  306.     Data_t* newData = new Data_t(*this, s);
  307.  
  308.     _Free();
  309.     m_Data = newData;
  310.  
  311.     return *this;
  312. }
  313.  
  314. // Return the concatenation of this _bstr_t with another _bstr_t
  315. //
  316. inline _bstr_t _bstr_t::operator+(const _bstr_t& s) const throw(_com_error)
  317. {
  318.     _bstr_t b = *this;
  319.     b += s;
  320.  
  321.     return b;
  322. }
  323.  
  324. //////////////////////////////////////////////////////////////////////////////
  325. //
  326. // Friend Operators
  327. //
  328. //////////////////////////////////////////////////////////////////////////////
  329.  
  330. // Return the concatenation of a const char* with a _bstr_t
  331. //
  332. inline _bstr_t operator+(const char* s1, const _bstr_t& s2) throw(_com_error)
  333. {
  334.     _bstr_t b = s1; 
  335.     b += s2;
  336.  
  337.     return b;
  338. }
  339.  
  340. // Return the concatenation of a const char* with a _bstr_t
  341. //
  342. inline _bstr_t operator+(const wchar_t* s1, const _bstr_t& s2) throw(_com_error)
  343. {
  344.     _bstr_t b = s1; 
  345.     b += s2;
  346.  
  347.     return b;
  348. }
  349.  
  350. //////////////////////////////////////////////////////////////////////////////
  351. //
  352. // Extractors
  353. //
  354. //////////////////////////////////////////////////////////////////////////////
  355.  
  356. // Extract a const wchar_t*
  357. //
  358. inline _bstr_t::operator const wchar_t*() const throw()
  359. {
  360.     return (m_Data != NULL) ? m_Data->GetWString() : NULL;
  361. }
  362.  
  363. // Extract a wchar_t*
  364. //
  365. inline _bstr_t::operator wchar_t*() const throw()
  366. {
  367.     return const_cast<wchar_t*>((m_Data != NULL) ? m_Data->GetWString() : NULL);
  368. }
  369.  
  370. // Extract a const char_t*
  371. //
  372. inline _bstr_t::operator const char*() const throw(_com_error)
  373. {
  374.     return (m_Data != NULL) ? m_Data->GetString() : NULL;
  375. }
  376.  
  377. // Extract a char_t*
  378. //
  379. inline _bstr_t::operator char*() const throw(_com_error)
  380. {
  381.     return const_cast<char*>((m_Data != NULL) ? m_Data->GetString() : NULL);
  382. }
  383.  
  384. //////////////////////////////////////////////////////////////////////////////
  385. //
  386. // Comparison operators
  387. //
  388. //////////////////////////////////////////////////////////////////////////////
  389.  
  390. inline bool _bstr_t::operator!() const throw()
  391. {
  392.     return (m_Data != NULL) ? !m_Data->GetWString() : true;
  393. }
  394.  
  395. inline bool _bstr_t::operator==(const _bstr_t& str) const throw()
  396. {
  397.     return _Compare(str) == 0;
  398. }
  399.  
  400. inline bool _bstr_t::operator!=(const _bstr_t& str) const throw()
  401. {
  402.     return _Compare(str) != 0;
  403. }
  404.  
  405. inline bool _bstr_t::operator<(const _bstr_t& str) const throw()
  406. {
  407.     return _Compare(str) < 0;
  408. }
  409.  
  410. inline bool _bstr_t::operator>(const _bstr_t& str) const throw()
  411. {
  412.     return _Compare(str) > 0;
  413. }
  414.  
  415. inline bool _bstr_t::operator<=(const _bstr_t& str) const throw()
  416. {
  417.     return _Compare(str) <= 0;
  418. }
  419.  
  420. inline bool _bstr_t::operator>=(const _bstr_t& str) const throw()
  421. {
  422.     return _Compare(str) >= 0;
  423. }
  424.  
  425. //////////////////////////////////////////////////////////////////////////////
  426. //
  427. // Low-level help functions
  428. //
  429. //////////////////////////////////////////////////////////////////////////////
  430.  
  431. // Extract a copy of the wrapped BSTR
  432. //
  433. inline BSTR _bstr_t::copy() const throw(_com_error)
  434. {
  435.     return (m_Data != NULL) ? m_Data->Copy() : NULL;
  436. }
  437.  
  438. // Return the length of the wrapped BSTR
  439. //
  440. inline unsigned int _bstr_t::length() const throw()
  441. {
  442.     return (m_Data != NULL) ? m_Data->Length() : 0;
  443. }
  444.  
  445. // Binary string assign
  446. //
  447. inline void _bstr_t::Assign(BSTR s) throw(_com_error)
  448. {
  449.     if (m_Data != NULL) {
  450.         m_Data->Assign(s); 
  451.     } 
  452.     else {
  453.         m_Data = new Data_t(s, TRUE);
  454.         if (m_Data == NULL) {
  455.             _com_issue_error(E_OUTOFMEMORY);
  456.         }
  457.     }
  458. }
  459.  
  460. // AddRef the BSTR
  461. //
  462. inline void _bstr_t::_AddRef() throw()
  463. {
  464.     if (m_Data != NULL) {
  465.         m_Data->AddRef();
  466.     }
  467. }
  468.  
  469. // Free the BSTR
  470. //
  471. inline void _bstr_t::_Free() throw()
  472. {
  473.     if (m_Data != NULL) {
  474.         m_Data->Release();
  475.         m_Data = NULL;
  476.     }
  477. }
  478.  
  479. // Compare two _bstr_t objects
  480. //
  481. inline int _bstr_t::_Compare(const _bstr_t& str) const throw()
  482. {
  483.     if (m_Data == str.m_Data) {
  484.         return 0;
  485.     }
  486.  
  487.     if (m_Data == NULL) {
  488.         return -1;
  489.     }
  490.  
  491.     if (str.m_Data == NULL) {
  492.         return 1;
  493.     }
  494.  
  495.     return m_Data->Compare(*str.m_Data);
  496. }
  497.  
  498. //////////////////////////////////////////////////////////////////////////////
  499. //
  500. // Reference counted wrapper - Constructors
  501. //
  502. //////////////////////////////////////////////////////////////////////////////
  503.  
  504. // Construct a Data_t from a const char*
  505. //
  506. inline _bstr_t::Data_t::Data_t(const char* s) throw(_com_error)
  507.     : m_str(NULL), m_RefCount(1)
  508. {
  509.     m_wstr = _com_util::ConvertStringToBSTR(s);
  510.  
  511.     if (m_wstr == NULL && s != NULL) {
  512.         _com_issue_error(E_OUTOFMEMORY);
  513.     }
  514. }
  515.  
  516. // Construct a Data_t from a const wchar_t*
  517. //
  518. inline _bstr_t::Data_t::Data_t(const wchar_t* s) throw(_com_error)
  519.     : m_str(NULL), m_RefCount(1)
  520. {
  521.     m_wstr = ::SysAllocString(s);
  522.  
  523.     if (m_wstr == NULL && s != NULL) {
  524.         _com_issue_error(E_OUTOFMEMORY);
  525.     }
  526. }
  527.  
  528. // Construct a Data_t from a BSTR.  If fCopy is FALSE, give control of
  529. // data to the Data_t without doing a SysAllocStringByteLen.
  530. //
  531. inline _bstr_t::Data_t::Data_t(BSTR bstr, bool fCopy) throw(_com_error)
  532.     : m_str(NULL), m_RefCount(1)
  533. {
  534.     if (fCopy && bstr != NULL) {
  535.         m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char*>(bstr),
  536.                                          ::SysStringByteLen(bstr));
  537.  
  538.         if (m_wstr == NULL) {
  539.             _com_issue_error(E_OUTOFMEMORY);
  540.         }
  541.     }
  542.     else {
  543.         m_wstr = bstr;
  544.     }
  545. }
  546.  
  547. // Construct a Data_t from the concatenation of two _bstr_t objects
  548. //
  549. inline _bstr_t::Data_t::Data_t(const _bstr_t& s1, const _bstr_t& s2) throw(_com_error)
  550.     : m_str(NULL), m_RefCount(1)
  551. {
  552.     const unsigned int l1 = s1.length();
  553.     const unsigned int l2 = s2.length();
  554.  
  555.     m_wstr = ::SysAllocStringByteLen(NULL, (l1 + l2) * sizeof(wchar_t));
  556.  
  557.     if (m_wstr == NULL) {
  558.         if (l1 + l2 == 0) {
  559.             return;
  560.         }
  561.         _com_issue_error(E_OUTOFMEMORY);
  562.     }
  563.  
  564.     const wchar_t* wstr1 = static_cast<const wchar_t*>(s1);
  565.  
  566.     if (wstr1 != NULL) {
  567.         memcpy(m_wstr, wstr1, (l1 + 1) * sizeof(wchar_t));
  568.     }
  569.  
  570.     const wchar_t* wstr2 = static_cast<const wchar_t*>(s2);
  571.  
  572.     if (wstr2 != NULL) {
  573.         memcpy(m_wstr + l1, wstr2, (l2 + 1) * sizeof(wchar_t));
  574.     }
  575. }
  576.  
  577. //////////////////////////////////////////////////////////////////////////////
  578. //
  579. // Reference counted wrapper - reference counting routines
  580. //
  581. //////////////////////////////////////////////////////////////////////////////
  582.  
  583. inline unsigned long _bstr_t::Data_t::AddRef() throw()
  584. {
  585.     InterlockedIncrement(reinterpret_cast<long*>(&m_RefCount));
  586.     return m_RefCount;
  587. }
  588.  
  589. inline unsigned long _bstr_t::Data_t::Release() throw()
  590. {
  591.     if (!InterlockedDecrement(reinterpret_cast<long*>(&m_RefCount))) {
  592.         delete this;
  593.         return 0;
  594.     }
  595.  
  596.     return m_RefCount;
  597. }
  598.  
  599. //////////////////////////////////////////////////////////////////////////////
  600. //
  601. // Reference counted wrapper - extractors
  602. //
  603. //////////////////////////////////////////////////////////////////////////////
  604.  
  605. // Extract a const wchar_t*
  606. //
  607. inline _bstr_t::Data_t::operator const wchar_t*() const throw()
  608. {
  609.     return m_wstr;
  610. }
  611.  
  612. // Extract a const char_t*
  613. //
  614. inline _bstr_t::Data_t::operator const char*() const throw(_com_error)
  615. {
  616.     return GetString();
  617. }
  618.  
  619. //////////////////////////////////////////////////////////////////////////////
  620. //
  621. // Reference counted wrapper - helper functions
  622. //
  623. //////////////////////////////////////////////////////////////////////////////
  624.  
  625. inline const wchar_t* _bstr_t::Data_t::GetWString() const throw()
  626. {
  627.     return m_wstr;
  628. }
  629.  
  630. inline const char* _bstr_t::Data_t::GetString() const throw(_com_error)
  631. {
  632.     if (m_str == NULL) {
  633.         m_str = _com_util::ConvertBSTRToString(m_wstr);
  634.  
  635.         if (m_str == NULL && m_wstr != NULL) {
  636.             _com_issue_error(E_OUTOFMEMORY);
  637.         }
  638.     }
  639.  
  640.     return m_str;
  641. }
  642.  
  643. // Return a copy of the wrapped BSTR
  644. //
  645. inline BSTR _bstr_t::Data_t::Copy() const throw(_com_error)
  646. {
  647.     if (m_wstr != NULL) {
  648.         BSTR bstr = ::SysAllocStringByteLen(reinterpret_cast<char*>(m_wstr),
  649.                                             ::SysStringByteLen(m_wstr));
  650.  
  651.         if (bstr == NULL) {
  652.             _com_issue_error(E_OUTOFMEMORY);
  653.         }
  654.  
  655.         return bstr;
  656.     }
  657.  
  658.     return NULL;
  659. }
  660.  
  661. inline void _bstr_t::Data_t::Assign(BSTR s) throw(_com_error)
  662. {
  663.     _Free();
  664.     if (s != NULL) {
  665.         m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char*>(s), 
  666.                                             ::SysStringByteLen(s));
  667.     }
  668. }
  669.  
  670. // Return the length of the wrapper BSTR
  671. //
  672. inline unsigned int _bstr_t::Data_t::Length() const throw()
  673. {
  674.     return m_wstr ? ::SysStringLen(m_wstr) : 0;
  675. }
  676.  
  677. // Compare two wrapped BSTRs
  678. //
  679. inline int _bstr_t::Data_t::Compare(const _bstr_t::Data_t& str) const throw()
  680. {
  681.     if (m_wstr == NULL) {
  682.         return str.m_wstr ? -1 : 0;
  683.     }
  684.  
  685.     if (str.m_wstr == NULL) {
  686.         return 1;
  687.     }
  688.  
  689.     const unsigned int l1 = ::SysStringLen(m_wstr);
  690.     const unsigned int l2 = ::SysStringLen(str.m_wstr);
  691.  
  692.     unsigned int len = l1;
  693.     if (len > l2) {
  694.         len = l2;
  695.     }
  696.  
  697.     BSTR bstr1 = m_wstr;
  698.     BSTR bstr2 = str.m_wstr;
  699.  
  700.     while (len-- > 0) {
  701.         if (*bstr1++ != *bstr2++) {
  702.             return bstr1[-1] - bstr2[-1];
  703.         }
  704.     }
  705.  
  706.     return (l1 < l2) ? -1 : (l1 == l2) ? 0 : 1;
  707. }
  708.  
  709. // Destruct this object
  710. //
  711. inline _bstr_t::Data_t::~Data_t() throw()
  712. {
  713.     _Free();
  714. }
  715.  
  716. // Free up this object
  717. //
  718. inline void _bstr_t::Data_t::_Free() throw()
  719. {
  720.     if (m_wstr != NULL) {
  721.         ::SysFreeString(m_wstr);
  722.     }
  723.  
  724.     if (m_str != NULL) {
  725.         delete [] m_str;
  726.     }
  727. }
  728.  
  729. //////////////////////////////////////////////////////////////////////////////
  730. //
  731. // Wrapper class for VARIANT
  732. //
  733. //////////////////////////////////////////////////////////////////////////////
  734.  
  735. /*
  736.  * VARENUM usage key,
  737.  *
  738.  * * [V] - may appear in a VARIANT
  739.  * * [T] - may appear in a TYPEDESC
  740.  * * [P] - may appear in an OLE property set
  741.  * * [S] - may appear in a Safe Array
  742.  * * [C] - supported by class _variant_t
  743.  *
  744.  *
  745.  *  VT_EMPTY            [V]   [P]        nothing
  746.  *  VT_NULL             [V]   [P]        SQL style Null
  747.  *  VT_I2               [V][T][P][S][C]  2 byte signed int
  748.  *  VT_I4               [V][T][P][S][C]  4 byte signed int
  749.  *  VT_R4               [V][T][P][S][C]  4 byte real
  750.  *  VT_R8               [V][T][P][S][C]  8 byte real
  751.  *  VT_CY               [V][T][P][S][C]  currency
  752.  *  VT_DATE             [V][T][P][S][C]  date
  753.  *  VT_BSTR             [V][T][P][S][C]  OLE Automation string
  754.  *  VT_DISPATCH         [V][T][P][S][C]  IDispatch *
  755.  *  VT_ERROR            [V][T]   [S][C]  SCODE
  756.  *  VT_BOOL             [V][T][P][S][C]  True=-1, False=0
  757.  *  VT_VARIANT          [V][T][P][S]     VARIANT *
  758.  *  VT_UNKNOWN          [V][T]   [S][C]  IUnknown *
  759.  *  VT_DECIMAL          [V][T]   [S][C]  16 byte fixed point
  760.  *  VT_I1                  [T]           signed char
  761.  *  VT_UI1              [V][T][P][S][C]  unsigned char
  762.  *  VT_UI2                 [T][P]        unsigned short
  763.  *  VT_UI4                 [T][P]        unsigned short
  764.  *  VT_I8                  [T][P]        signed 64-bit int
  765.  *  VT_UI8                 [T][P]        unsigned 64-bit int
  766.  *  VT_INT                 [T]           signed machine int
  767.  *  VT_UINT                [T]           unsigned machine int
  768.  *  VT_VOID                [T]           C style void
  769.  *  VT_HRESULT             [T]           Standard return type
  770.  *  VT_PTR                 [T]           pointer type
  771.  *  VT_SAFEARRAY           [T]          (use VT_ARRAY in VARIANT)
  772.  *  VT_CARRAY              [T]           C style array
  773.  *  VT_USERDEFINED         [T]           user defined type
  774.  *  VT_LPSTR               [T][P]        null terminated string
  775.  *  VT_LPWSTR              [T][P]        wide null terminated string
  776.  *  VT_FILETIME               [P]        FILETIME
  777.  *  VT_BLOB                   [P]        Length prefixed bytes
  778.  *  VT_STREAM                 [P]        Name of the stream follows
  779.  *  VT_STORAGE                [P]        Name of the storage follows
  780.  *  VT_STREAMED_OBJECT        [P]        Stream contains an object
  781.  *  VT_STORED_OBJECT          [P]        Storage contains an object
  782.  *  VT_BLOB_OBJECT            [P]        Blob contains an object
  783.  *  VT_CF                     [P]        Clipboard format
  784.  *  VT_CLSID                  [P]        A Class ID
  785.  *  VT_VECTOR                 [P]        simple counted array
  786.  *  VT_ARRAY            [V]              SAFEARRAY*
  787.  *  VT_BYREF            [V]              void* for local use
  788.  */
  789.  
  790. class _variant_t : public ::tagVARIANT {
  791. public:
  792.     // Constructors
  793.     //
  794.     _variant_t() throw();
  795.  
  796.     _variant_t(const VARIANT& varSrc) throw(_com_error);
  797.     _variant_t(const VARIANT* pSrc) throw(_com_error);
  798.     _variant_t(const _variant_t& varSrc) throw(_com_error);
  799.  
  800.     _variant_t(VARIANT& varSrc, bool fCopy) throw(_com_error);            // Attach VARIANT if !fCopy
  801.  
  802.     _variant_t(short sSrc, VARTYPE vtSrc = VT_I2) throw(_com_error);    // Creates a VT_I2, or a VT_BOOL
  803.     _variant_t(long lSrc, VARTYPE vtSrc = VT_I4) throw(_com_error);        // Creates a VT_I4, a VT_ERROR, or a VT_BOOL
  804.     _variant_t(float fltSrc) throw();                                    // Creates a VT_R4
  805.     _variant_t(double dblSrc, VARTYPE vtSrc = VT_R8) throw(_com_error);    // Creates a VT_R8, or a VT_DATE
  806.     _variant_t(const CY& cySrc) throw();                                // Creates a VT_CY
  807.     _variant_t(const _bstr_t& bstrSrc) throw(_com_error);                // Creates a VT_BSTR
  808.     _variant_t(const wchar_t *pSrc) throw(_com_error);                    // Creates a VT_BSTR
  809.     _variant_t(const char* pSrc) throw(_com_error);                        // Creates a VT_BSTR
  810.     _variant_t(IDispatch* pSrc, bool fAddRef = true) throw();            // Creates a VT_DISPATCH
  811.     _variant_t(bool bSrc) throw();                                        // Creates a VT_BOOL
  812.     _variant_t(IUnknown* pSrc, bool fAddRef = true) throw();            // Creates a VT_UNKNOWN
  813.     _variant_t(const DECIMAL& decSrc) throw();                            // Creates a VT_DECIMAL
  814.     _variant_t(BYTE bSrc) throw();                                        // Creates a VT_UI1
  815.  
  816.     // Destructor
  817.     //
  818.     ~_variant_t() throw(_com_error);
  819.  
  820.     // Extractors
  821.     //
  822.     operator short() const throw(_com_error);            // Extracts a short from a VT_I2
  823.     operator long() const throw(_com_error);            // Extracts a long from a VT_I4
  824.     operator float() const throw(_com_error);            // Extracts a float from a VT_R4
  825.     operator double() const throw(_com_error);            // Extracts a double from a VT_R8
  826.     operator CY() const throw(_com_error);                // Extracts a CY from a VT_CY
  827.     operator _bstr_t() const throw(_com_error);            // Extracts a _bstr_t from a VT_BSTR
  828.     operator IDispatch*() const throw(_com_error);        // Extracts a IDispatch* from a VT_DISPATCH
  829.     operator bool() const throw(_com_error);            // Extracts a bool from a VT_BOOL
  830.     operator IUnknown*() const throw(_com_error);        // Extracts a IUnknown* from a VT_UNKNOWN
  831.     operator DECIMAL() const throw(_com_error);            // Extracts a DECIMAL from a VT_DECIMAL
  832.     operator BYTE() const throw(_com_error);            // Extracts a BTYE (unsigned char) from a VT_UI1
  833.     
  834.     // Assignment operations
  835.     //
  836.     _variant_t& operator=(const VARIANT& varSrc) throw(_com_error);
  837.     _variant_t& operator=(const VARIANT* pSrc) throw(_com_error);
  838.     _variant_t& operator=(const _variant_t& varSrc) throw(_com_error);
  839.  
  840.     _variant_t& operator=(short sSrc) throw(_com_error);                // Assign a VT_I2, or a VT_BOOL
  841.     _variant_t& operator=(long lSrc) throw(_com_error);                    // Assign a VT_I4, a VT_ERROR or a VT_BOOL
  842.     _variant_t& operator=(float fltSrc) throw(_com_error);                // Assign a VT_R4
  843.     _variant_t& operator=(double dblSrc) throw(_com_error);                // Assign a VT_R8, or a VT_DATE
  844.     _variant_t& operator=(const CY& cySrc) throw(_com_error);            // Assign a VT_CY
  845.     _variant_t& operator=(const _bstr_t& bstrSrc) throw(_com_error);    // Assign a VT_BSTR
  846.     _variant_t& operator=(const wchar_t* pSrc) throw(_com_error);        // Assign a VT_BSTR
  847.     _variant_t& operator=(const char* pSrc) throw(_com_error);            // Assign a VT_BSTR
  848.     _variant_t& operator=(IDispatch* pSrc) throw(_com_error);            // Assign a VT_DISPATCH
  849.      _variant_t& operator=(bool bSrc) throw(_com_error);                    // Assign a VT_BOOL
  850.     _variant_t& operator=(IUnknown* pSrc) throw(_com_error);            // Assign a VT_UNKNOWN
  851.     _variant_t& operator=(const DECIMAL& decSrc) throw(_com_error);        // Assign a VT_DECIMAL
  852.     _variant_t& operator=(BYTE bSrc) throw(_com_error);                    // Assign a VT_UI1
  853.  
  854.     // Comparison operations
  855.     //
  856.     bool operator==(const VARIANT& varSrc) const throw(_com_error);
  857.     bool operator==(const VARIANT* pSrc) const throw(_com_error);
  858.  
  859.     bool operator!=(const VARIANT& varSrc) const throw(_com_error);
  860.     bool operator!=(const VARIANT* pSrc) const throw(_com_error);
  861.  
  862.     // Low-level operations
  863.     //
  864.     void Clear() throw(_com_error);
  865.  
  866.     void Attach(VARIANT& varSrc) throw(_com_error);
  867.     VARIANT Detach() throw(_com_error);
  868.  
  869.     void ChangeType(VARTYPE vartype, const _variant_t* pSrc = NULL) throw(_com_error);
  870.  
  871.     void SetString(const char* pSrc) throw(_com_error); // used to set ANSI string
  872. };
  873.  
  874. //////////////////////////////////////////////////////////////////////////////////////////
  875. //
  876. // Constructors
  877. //
  878. //////////////////////////////////////////////////////////////////////////////////////////
  879.  
  880. // Default constructor
  881. //
  882. inline _variant_t::_variant_t() throw()
  883. {
  884.     ::VariantInit(this);
  885. }
  886.  
  887. // Construct a _variant_t from a const VARIANT&
  888. //
  889. inline _variant_t::_variant_t(const VARIANT& varSrc) throw(_com_error)
  890. {
  891.     ::VariantInit(this);
  892.     _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(&varSrc)));
  893. }
  894.  
  895. // Construct a _variant_t from a const VARIANT*
  896. //
  897. inline _variant_t::_variant_t(const VARIANT* pSrc) throw(_com_error)
  898. {
  899.     ::VariantInit(this);
  900.     _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(pSrc)));
  901. }
  902.  
  903. // Construct a _variant_t from a const _variant_t&
  904. //
  905. inline _variant_t::_variant_t(const _variant_t& varSrc) throw(_com_error)
  906. {
  907.     ::VariantInit(this);
  908.     _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
  909. }
  910.  
  911. // Construct a _variant_t from a VARIANT&.  If fCopy is FALSE, give control of
  912. // data to the _variant_t without doing a VariantCopy.
  913. //
  914. inline _variant_t::_variant_t(VARIANT& varSrc, bool fCopy) throw(_com_error)
  915. {
  916.     if (fCopy) {
  917.         ::VariantInit(this);
  918.         _com_util::CheckError(::VariantCopy(this, &varSrc));
  919.     } else {
  920.         memcpy(this, &varSrc, sizeof(varSrc));
  921.         V_VT(&varSrc) = VT_EMPTY;
  922.     }
  923. }
  924.  
  925. // Construct either a VT_I2 VARIANT or a VT_BOOL VARIANT from
  926. // a short (the default is VT_I2)
  927. //
  928. inline _variant_t::_variant_t(short sSrc, VARTYPE vtSrc) throw(_com_error)
  929. {
  930.     if ((vtSrc != VT_I2) && (vtSrc != VT_BOOL)) {
  931.         _com_issue_error(E_INVALIDARG);
  932.     }
  933.  
  934.     if (vtSrc == VT_BOOL) {
  935.         V_VT(this) = VT_BOOL;
  936.         V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
  937.     }
  938.     else {
  939.         V_VT(this) = VT_I2;
  940.         V_I2(this) = sSrc;
  941.     }
  942. }
  943.  
  944. // Construct either a VT_I4 VARIANT, a VT_BOOL VARIANT, or a
  945. // VT_ERROR VARIANT from a long (the default is VT_I4)
  946. //
  947. inline _variant_t::_variant_t(long lSrc, VARTYPE vtSrc) throw(_com_error)
  948. {
  949.     if ((vtSrc != VT_I4) && (vtSrc != VT_ERROR) && (vtSrc != VT_BOOL)) {
  950.         _com_issue_error(E_INVALIDARG);
  951.     }
  952.  
  953.     if (vtSrc == VT_ERROR) {
  954.         V_VT(this) = VT_ERROR;
  955.         V_ERROR(this) = lSrc;
  956.     }
  957.     else if (vtSrc == VT_BOOL) {
  958.         V_VT(this) = VT_BOOL;
  959.         V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
  960.     }
  961.     else {
  962.         V_VT(this) = VT_I4;
  963.         V_I4(this) = lSrc;
  964.     }
  965. }
  966.  
  967. // Construct a VT_R4 VARIANT from a float
  968. //
  969. inline _variant_t::_variant_t(float fltSrc) throw()
  970. {
  971.     V_VT(this) = VT_R4;
  972.     V_R4(this) = fltSrc;
  973. }
  974.  
  975. // Construct either a VT_R8 VARIANT, or a VT_DATE VARIANT from
  976. // a double (the default is VT_R8)
  977. //
  978. inline _variant_t::_variant_t(double dblSrc, VARTYPE vtSrc) throw(_com_error)
  979. {
  980.     if ((vtSrc != VT_R8) && (vtSrc != VT_DATE)) {
  981.         _com_issue_error(E_INVALIDARG);
  982.     }
  983.  
  984.     if (vtSrc == VT_DATE) {
  985.         V_VT(this) = VT_DATE;
  986.         V_DATE(this) = dblSrc;
  987.     }
  988.     else {
  989.         V_VT(this) = VT_R8;
  990.         V_R8(this) = dblSrc;
  991.     }
  992. }
  993.  
  994. // Construct a VT_CY from a CY
  995. //
  996. inline _variant_t::_variant_t(const CY& cySrc) throw()
  997. {
  998.     V_VT(this) = VT_CY;
  999.     V_CY(this) = cySrc;
  1000. }
  1001.  
  1002. // Construct a VT_BSTR VARIANT from a const _bstr_t&
  1003. //
  1004. inline _variant_t::_variant_t(const _bstr_t& bstrSrc) throw(_com_error)
  1005. {
  1006.     V_VT(this) = VT_BSTR;
  1007.  
  1008.     BSTR bstr = static_cast<wchar_t*>(bstrSrc);
  1009.     V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char*>(bstr),
  1010.                                            ::SysStringByteLen(bstr));
  1011.  
  1012.     if (V_BSTR(this) == NULL) {
  1013.         _com_issue_error(E_OUTOFMEMORY);
  1014.     }
  1015. }
  1016.  
  1017. // Construct a VT_BSTR VARIANT from a const wchar_t*
  1018. //
  1019. inline _variant_t::_variant_t(const wchar_t* pSrc) throw(_com_error)
  1020. {
  1021.     V_VT(this) = VT_BSTR;
  1022.     V_BSTR(this) = ::SysAllocString(pSrc);
  1023.  
  1024.     if (V_BSTR(this) == NULL && pSrc != NULL) {
  1025.         _com_issue_error(E_OUTOFMEMORY);
  1026.     }
  1027. }
  1028.  
  1029. // Construct a VT_BSTR VARIANT from a const char*
  1030. //
  1031. inline _variant_t::_variant_t(const char* pSrc) throw(_com_error)
  1032. {
  1033.     V_VT(this) = VT_BSTR;
  1034.     V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
  1035.  
  1036.     if (V_BSTR(this) == NULL && pSrc != NULL) {
  1037.         _com_issue_error(E_OUTOFMEMORY);
  1038.     }
  1039. }
  1040.  
  1041. // Construct a VT_DISPATCH VARIANT from an IDispatch*
  1042. //
  1043. inline _variant_t::_variant_t(IDispatch* pSrc, bool fAddRef) throw()
  1044. {
  1045.     V_VT(this) = VT_DISPATCH;
  1046.     V_DISPATCH(this) = pSrc;
  1047.  
  1048.     // Need the AddRef() as VariantClear() calls Release(), unless fAddRef
  1049.     // false indicates we're taking ownership
  1050.     //
  1051.     if (fAddRef) {
  1052.         V_DISPATCH(this)->AddRef();
  1053.     }
  1054. }
  1055.  
  1056. // Construct a VT_BOOL VARIANT from a bool
  1057. //
  1058. inline _variant_t::_variant_t(bool bSrc) throw()
  1059. {
  1060.     V_VT(this) = VT_BOOL;
  1061.     V_BOOL(this) = (bSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1062. }
  1063.  
  1064. // Construct a VT_UNKNOWN VARIANT from an IUnknown*
  1065. //
  1066. inline _variant_t::_variant_t(IUnknown* pSrc, bool fAddRef) throw()
  1067. {
  1068.     V_VT(this) = VT_UNKNOWN;
  1069.     V_UNKNOWN(this) = pSrc;
  1070.  
  1071.     // Need the AddRef() as VariantClear() calls Release(), unless fAddRef
  1072.     // false indicates we're taking ownership
  1073.     //
  1074.     if (fAddRef) {
  1075.         V_UNKNOWN(this)->AddRef();
  1076.     }
  1077. }
  1078.  
  1079. // Construct a VT_DECIMAL VARIANT from a DECIMAL
  1080. //
  1081. inline _variant_t::_variant_t(const DECIMAL& decSrc) throw()
  1082. {
  1083.     // Order is important here! Setting V_DECIMAL wipes out the entire VARIANT
  1084.     //
  1085.     V_DECIMAL(this) = decSrc;
  1086.     V_VT(this) = VT_DECIMAL;
  1087. }
  1088.  
  1089. // Construct a VT_UI1 VARIANT from a BYTE (unsigned char)
  1090. //
  1091. inline _variant_t::_variant_t(BYTE bSrc) throw()
  1092. {
  1093.     V_VT(this) = VT_UI1;
  1094.     V_UI1(this) = bSrc;
  1095. }
  1096.  
  1097. //////////////////////////////////////////////////////////////////////////////////////////
  1098. //
  1099. // Extractors
  1100. //
  1101. //////////////////////////////////////////////////////////////////////////////////////////
  1102.  
  1103. // Extracts a VT_I2 into a short
  1104. //
  1105. inline _variant_t::operator short() const throw(_com_error)
  1106. {
  1107.     if (V_VT(this) == VT_I2) {
  1108.         return V_I2(this); 
  1109.     }
  1110.  
  1111.     _variant_t varDest;
  1112.  
  1113.     varDest.ChangeType(VT_I2, this);
  1114.  
  1115.     return V_I2(&varDest);
  1116. }
  1117.  
  1118. // Extracts a VT_I4 into a long
  1119. //
  1120. inline _variant_t::operator long() const throw(_com_error)
  1121. {
  1122.     if (V_VT(this) == VT_I4) {
  1123.         return V_I4(this); 
  1124.     }
  1125.  
  1126.     _variant_t varDest;
  1127.  
  1128.     varDest.ChangeType(VT_I4, this);
  1129.  
  1130.     return V_I4(&varDest);
  1131. }
  1132.  
  1133. // Extracts a VT_R4 into a float
  1134. //
  1135. inline _variant_t::operator float() const throw(_com_error)
  1136. {
  1137.     if (V_VT(this) == VT_R4) {
  1138.         return V_R4(this); 
  1139.     }
  1140.  
  1141.     _variant_t varDest;
  1142.  
  1143.     varDest.ChangeType(VT_R4, this);
  1144.  
  1145.     return V_R4(&varDest);
  1146. }
  1147.  
  1148. // Extracts a VT_R8 into a double
  1149. //
  1150. inline _variant_t::operator double() const throw(_com_error)
  1151. {
  1152.     if (V_VT(this) == VT_R8) {
  1153.         return V_R8(this); 
  1154.     }
  1155.  
  1156.     _variant_t varDest;
  1157.  
  1158.     varDest.ChangeType(VT_R8, this);
  1159.  
  1160.     return V_R8(&varDest);
  1161. }
  1162.  
  1163. // Extracts a VT_CY into a CY
  1164. //
  1165. inline _variant_t::operator CY() const throw(_com_error)
  1166. {
  1167.     if (V_VT(this) == VT_CY) {
  1168.         return V_CY(this); 
  1169.     }
  1170.  
  1171.     _variant_t varDest;
  1172.  
  1173.     varDest.ChangeType(VT_CY, this);
  1174.  
  1175.     return V_CY(&varDest);
  1176. }
  1177.  
  1178. // Extracts a VT_BSTR into a _bstr_t
  1179. //
  1180. inline _variant_t::operator _bstr_t() const throw(_com_error)
  1181. {
  1182.     if (V_VT(this) == VT_BSTR) {
  1183.         return V_BSTR(this);
  1184.     }
  1185.  
  1186.     _variant_t varDest;
  1187.  
  1188.     varDest.ChangeType(VT_BSTR, this);
  1189.  
  1190.     return V_BSTR(&varDest);
  1191. }
  1192.  
  1193. // Extracts a VT_DISPATCH into an IDispatch*
  1194. //
  1195. inline _variant_t::operator IDispatch*() const throw(_com_error)
  1196. {
  1197.     if (V_VT(this) == VT_DISPATCH) {
  1198.         V_DISPATCH(this)->AddRef();
  1199.         return V_DISPATCH(this);
  1200.     }
  1201.  
  1202.     _variant_t varDest;
  1203.  
  1204.     varDest.ChangeType(VT_DISPATCH, this);
  1205.  
  1206.     V_DISPATCH(&varDest)->AddRef();
  1207.     return V_DISPATCH(&varDest);
  1208. }
  1209.  
  1210. // Extract a VT_BOOL into a bool
  1211. //
  1212. inline _variant_t::operator bool() const throw(_com_error)
  1213. {
  1214.     if (V_VT(this) == VT_BOOL) {
  1215.         return V_BOOL(this) ? true : false;
  1216.     }
  1217.  
  1218.     _variant_t varDest;
  1219.  
  1220.     varDest.ChangeType(VT_BOOL, this);
  1221.  
  1222.     return V_BOOL(&varDest) ? true : false;
  1223. }
  1224.  
  1225. // Extracts a VT_UNKNOWN into an IUnknown*
  1226. //
  1227. inline _variant_t::operator IUnknown*() const throw(_com_error)
  1228. {
  1229.     if (V_VT(this) == VT_UNKNOWN) {
  1230.         V_UNKNOWN(this)->AddRef();
  1231.         return V_UNKNOWN(this);
  1232.     }
  1233.  
  1234.     _variant_t varDest;
  1235.  
  1236.     varDest.ChangeType(VT_UNKNOWN, this);
  1237.  
  1238.     V_UNKNOWN(&varDest)->AddRef();
  1239.     return V_UNKNOWN(&varDest);
  1240. }
  1241.  
  1242. // Extracts a VT_DECIMAL into a DECIMAL
  1243. //
  1244. inline _variant_t::operator DECIMAL() const throw(_com_error)
  1245. {
  1246.     if (V_VT(this) == VT_DECIMAL) {
  1247.         return V_DECIMAL(this);
  1248.     }
  1249.  
  1250.     _variant_t varDest;
  1251.  
  1252.     varDest.ChangeType(VT_DECIMAL, this);
  1253.  
  1254.     return V_DECIMAL(&varDest);
  1255. }
  1256.  
  1257. // Extracts a VT_UI1 into a BYTE (unsigned char)
  1258. //
  1259. inline _variant_t::operator BYTE() const throw(_com_error)
  1260. {
  1261.     if (V_VT(this) == VT_UI1) {
  1262.         return V_UI1(this);
  1263.     }
  1264.  
  1265.     _variant_t varDest;
  1266.  
  1267.     varDest.ChangeType(VT_UI1, this);
  1268.  
  1269.     return V_UI1(&varDest);
  1270. }
  1271.  
  1272. //////////////////////////////////////////////////////////////////////////////////////////
  1273. //
  1274. // Assignment operations
  1275. //
  1276. //////////////////////////////////////////////////////////////////////////////////////////
  1277.  
  1278. // Assign a const VARIANT& (::VariantCopy handles everything)
  1279. //
  1280. inline _variant_t& _variant_t::operator=(const VARIANT& varSrc) throw(_com_error)
  1281. {
  1282.     _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(&varSrc)));
  1283.  
  1284.     return *this;
  1285. }
  1286.  
  1287. // Assign a const VARIANT* (::VariantCopy handles everything)
  1288. //
  1289. inline _variant_t& _variant_t::operator=(const VARIANT* pSrc) throw(_com_error)
  1290. {
  1291.     _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(pSrc)));
  1292.  
  1293.     return *this;
  1294. }
  1295.  
  1296. // Assign a const _variant_t& (::VariantCopy handles everything)
  1297. //
  1298. inline _variant_t& _variant_t::operator=(const _variant_t& varSrc) throw(_com_error)
  1299. {
  1300.     _com_util::CheckError(::VariantCopy(this, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
  1301.  
  1302.     return *this;
  1303. }
  1304.  
  1305. // Assign a short creating either VT_I2 VARIANT or a 
  1306. // VT_BOOL VARIANT (VT_I2 is the default)
  1307. //
  1308. inline _variant_t& _variant_t::operator=(short sSrc) throw(_com_error)
  1309. {
  1310.     if (V_VT(this) == VT_I2) {
  1311.         V_I2(this) = sSrc;
  1312.     }
  1313.     else if (V_VT(this) == VT_BOOL) {
  1314.         V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1315.     }
  1316.     else {
  1317.         // Clear the VARIANT and create a VT_I2
  1318.         //
  1319.         Clear();
  1320.  
  1321.         V_VT(this) = VT_I2;
  1322.         V_I2(this) = sSrc;
  1323.     }
  1324.  
  1325.     return *this;
  1326. }
  1327.  
  1328. // Assign a long creating either VT_I4 VARIANT, a VT_ERROR VARIANT
  1329. // or a VT_BOOL VARIANT (VT_I4 is the default)
  1330. //
  1331. inline _variant_t& _variant_t::operator=(long lSrc) throw(_com_error)
  1332. {
  1333.     if (V_VT(this) == VT_I4) {
  1334.         V_I4(this) = lSrc;
  1335.     }
  1336.     else if (V_VT(this) == VT_ERROR) {
  1337.         V_ERROR(this) = lSrc;
  1338.     }
  1339.     else if (V_VT(this) == VT_BOOL) {
  1340.         V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1341.     }
  1342.     else {
  1343.         // Clear the VARIANT and create a VT_I4
  1344.         //
  1345.         Clear();
  1346.  
  1347.         V_VT(this) = VT_I4;
  1348.         V_I4(this) = lSrc;
  1349.     }
  1350.  
  1351.     return *this;
  1352. }
  1353.  
  1354. // Assign a float creating a VT_R4 VARIANT 
  1355. //
  1356. inline _variant_t& _variant_t::operator=(float fltSrc) throw(_com_error)
  1357. {
  1358.     if (V_VT(this) != VT_R4) {
  1359.         // Clear the VARIANT and create a VT_R4
  1360.         //
  1361.         Clear();
  1362.  
  1363.         V_VT(this) = VT_R4;
  1364.     }
  1365.  
  1366.     V_R4(this) = fltSrc;
  1367.  
  1368.     return *this;
  1369. }
  1370.  
  1371. // Assign a double creating either a VT_R8 VARIANT, or a VT_DATE
  1372. // VARIANT (VT_R8 is the default)
  1373. //
  1374. inline _variant_t& _variant_t::operator=(double dblSrc) throw(_com_error)
  1375. {
  1376.     if (V_VT(this) == VT_R8) {
  1377.         V_R8(this) = dblSrc;
  1378.     }
  1379.     else if(V_VT(this) == VT_DATE) {
  1380.         V_DATE(this) = dblSrc;
  1381.     }
  1382.     else {
  1383.         // Clear the VARIANT and create a VT_R8
  1384.         //
  1385.         Clear();
  1386.  
  1387.         V_VT(this) = VT_R8;
  1388.         V_R8(this) = dblSrc;
  1389.     }
  1390.  
  1391.     return *this;
  1392. }
  1393.  
  1394. // Assign a CY creating a VT_CY VARIANT 
  1395. //
  1396. inline _variant_t& _variant_t::operator=(const CY& cySrc) throw(_com_error)
  1397. {
  1398.     if (V_VT(this) != VT_CY) {
  1399.         // Clear the VARIANT and create a VT_CY
  1400.         //
  1401.         Clear();
  1402.  
  1403.         V_VT(this) = VT_CY;
  1404.     }
  1405.  
  1406.     V_CY(this) = cySrc;
  1407.  
  1408.     return *this;
  1409. }
  1410.  
  1411. // Assign a const _bstr_t& creating a VT_BSTR VARIANT
  1412. //
  1413. inline _variant_t& _variant_t::operator=(const _bstr_t& bstrSrc) throw(_com_error)
  1414. {
  1415.     // Clear the VARIANT (This will SysFreeString() any previous occupant)
  1416.     //
  1417.     Clear();
  1418.  
  1419.     V_VT(this) = VT_BSTR;
  1420.  
  1421.     if (!bstrSrc) {
  1422.         V_BSTR(this) = NULL;
  1423.     }
  1424.     else {
  1425.         BSTR bstr = static_cast<wchar_t*>(bstrSrc);
  1426.         V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char*>(bstr),
  1427.                                                ::SysStringByteLen(bstr));
  1428.  
  1429.         if (V_BSTR(this) == NULL) {
  1430.             _com_issue_error(E_OUTOFMEMORY);
  1431.         }
  1432.     }
  1433.  
  1434.     return *this;
  1435. }
  1436.  
  1437. // Assign a const wchar_t* creating a VT_BSTR VARIANT
  1438. //
  1439. inline _variant_t& _variant_t::operator=(const wchar_t* pSrc) throw(_com_error)
  1440. {
  1441.     // Clear the VARIANT (This will SysFreeString() any previous occupant)
  1442.     //
  1443.     Clear();
  1444.  
  1445.     V_VT(this) = VT_BSTR;
  1446.  
  1447.     if (pSrc == NULL) {
  1448.         V_BSTR(this) = NULL;
  1449.     }
  1450.     else {
  1451.         V_BSTR(this) = ::SysAllocString(pSrc);
  1452.  
  1453.         if (V_BSTR(this) == NULL) {
  1454.             _com_issue_error(E_OUTOFMEMORY);
  1455.         }
  1456.     }
  1457.  
  1458.     return *this;
  1459. }
  1460.  
  1461. // Assign a const char* creating a VT_BSTR VARIANT
  1462. //
  1463. inline _variant_t& _variant_t::operator=(const char* pSrc) throw(_com_error)
  1464. {
  1465.     // Clear the VARIANT (This will SysFreeString() any previous occupant)
  1466.     //
  1467.     Clear();
  1468.  
  1469.     V_VT(this) = VT_BSTR;
  1470.     V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
  1471.  
  1472.     if (V_BSTR(this) == NULL && pSrc != NULL) {
  1473.         _com_issue_error(E_OUTOFMEMORY);
  1474.     }
  1475.  
  1476.     return *this;
  1477. }
  1478.  
  1479. // Assign an IDispatch* creating a VT_DISPATCH VARIANT 
  1480. //
  1481. inline _variant_t& _variant_t::operator=(IDispatch* pSrc) throw(_com_error)
  1482. {
  1483.     // Clear the VARIANT (This will Release() any previous occupant)
  1484.     //
  1485.     Clear();
  1486.  
  1487.     V_VT(this) = VT_DISPATCH;
  1488.     V_DISPATCH(this) = pSrc;
  1489.  
  1490.     // Need the AddRef() as VariantClear() calls Release()
  1491.     //
  1492.     V_DISPATCH(this)->AddRef();
  1493.  
  1494.     return *this;
  1495. }
  1496.  
  1497. // Assign a bool creating a VT_BOOL VARIANT 
  1498. //
  1499. inline _variant_t& _variant_t::operator=(bool bSrc) throw(_com_error)
  1500. {
  1501.     if (V_VT(this) != VT_BOOL) {
  1502.         // Clear the VARIANT and create a VT_BOOL
  1503.         //
  1504.         Clear();
  1505.  
  1506.         V_VT(this) = VT_BOOL;
  1507.     }
  1508.  
  1509.     V_BOOL(this) = (bSrc ? VARIANT_TRUE : VARIANT_FALSE);
  1510.  
  1511.     return *this;
  1512. }
  1513.  
  1514. // Assign an IUnknown* creating a VT_UNKNOWN VARIANT 
  1515. //
  1516. inline _variant_t& _variant_t::operator=(IUnknown* pSrc) throw(_com_error)
  1517. {
  1518.     // Clear VARIANT (This will Release() any previous occupant)
  1519.     //
  1520.     Clear();
  1521.  
  1522.     V_VT(this) = VT_UNKNOWN;
  1523.     V_UNKNOWN(this) = pSrc;
  1524.  
  1525.     // Need the AddRef() as VariantClear() calls Release()
  1526.     //
  1527.     V_UNKNOWN(this)->AddRef();
  1528.  
  1529.     return *this;
  1530. }
  1531.  
  1532. // Assign a DECIMAL creating a VT_DECIMAL VARIANT
  1533. //
  1534. inline _variant_t& _variant_t::operator=(const DECIMAL& decSrc) throw(_com_error)
  1535. {
  1536.     if (V_VT(this) != VT_DECIMAL) {
  1537.         // Clear the VARIANT
  1538.         //
  1539.         Clear();
  1540.     }
  1541.  
  1542.     // Order is important here! Setting V_DECIMAL wipes out the entire VARIANT
  1543.     V_DECIMAL(this) = decSrc;
  1544.     V_VT(this) = VT_DECIMAL;
  1545.  
  1546.     return *this;
  1547. }
  1548.  
  1549. // Assign a BTYE (unsigned char) creating a VT_UI1 VARIANT
  1550. //
  1551. inline _variant_t& _variant_t::operator=(BYTE bSrc) throw(_com_error)
  1552. {
  1553.     if (V_VT(this) != VT_UI1) {
  1554.         // Clear the VARIANT and create a VT_UI1
  1555.         //
  1556.         Clear();
  1557.  
  1558.         V_VT(this) = VT_UI1;
  1559.     }
  1560.  
  1561.     V_UI1(this) = bSrc;
  1562.  
  1563.     return *this;
  1564. }
  1565.  
  1566. //////////////////////////////////////////////////////////////////////////////////////////
  1567. //
  1568. // Comparison operations
  1569. //
  1570. //////////////////////////////////////////////////////////////////////////////////////////
  1571.  
  1572. // Compare a _variant_t against a const VARIANT& for equality
  1573. //
  1574. inline bool _variant_t::operator==(const VARIANT& varSrc) const throw(_com_error)
  1575. {
  1576.     return *this == &varSrc;
  1577. }
  1578.  
  1579. // Compare a _variant_t against a const VARIANT* for equality
  1580. //
  1581. inline bool _variant_t::operator==(const VARIANT* pSrc) const throw(_com_error)
  1582. {
  1583.     if (this == pSrc) {
  1584.         return true;
  1585.     }
  1586.  
  1587.     //
  1588.     // Variants not equal if types don't match
  1589.     //
  1590.     if (V_VT(this) != V_VT(pSrc)) {
  1591.         return false;
  1592.     }
  1593.  
  1594.     //
  1595.     // Check type specific values
  1596.     //
  1597.     switch (V_VT(this)) {
  1598.         case VT_EMPTY:
  1599.         case VT_NULL:
  1600.             return true;
  1601.  
  1602.         case VT_I2:
  1603.             return V_I2(this) == V_I2(pSrc);
  1604.  
  1605.         case VT_I4:
  1606.             return V_I4(this) == V_I4(pSrc);
  1607.  
  1608.         case VT_R4:
  1609.             return V_R4(this) == V_R4(pSrc);
  1610.  
  1611.         case VT_R8:
  1612.             return V_R8(this) == V_R8(pSrc);
  1613.  
  1614.         case VT_CY:
  1615.             return memcmp(&(V_CY(this)), &(V_CY(pSrc)), sizeof(CY)) == 0;
  1616.  
  1617.         case VT_DATE:
  1618.             return V_DATE(this) == V_DATE(pSrc);
  1619.  
  1620.         case VT_BSTR:
  1621.             return (::SysStringByteLen(V_BSTR(this)) == ::SysStringByteLen(V_BSTR(pSrc))) &&
  1622.                     (memcmp(V_BSTR(this), V_BSTR(pSrc), ::SysStringByteLen(V_BSTR(this))) == 0);
  1623.  
  1624.         case VT_DISPATCH:
  1625.             return V_DISPATCH(this) == V_DISPATCH(pSrc);
  1626.  
  1627.         case VT_ERROR:
  1628.             return V_ERROR(this) == V_ERROR(pSrc);
  1629.  
  1630.         case VT_BOOL:
  1631.             return V_BOOL(this) == V_BOOL(pSrc);
  1632.  
  1633.         case VT_UNKNOWN:
  1634.             return V_UNKNOWN(this) == V_UNKNOWN(pSrc);
  1635.  
  1636.         case VT_DECIMAL:
  1637.             return memcmp(&(V_DECIMAL(this)), &(V_DECIMAL(pSrc)), sizeof(DECIMAL)) == 0;
  1638.  
  1639.         case VT_UI1:
  1640.             return V_UI1(this) == V_UI1(pSrc);
  1641.  
  1642.         default:
  1643.             _com_issue_error(E_INVALIDARG);
  1644.             // fall through
  1645.     }
  1646.  
  1647.     return false;
  1648. }
  1649.  
  1650. // Compare a _variant_t against a const VARIANT& for in-equality
  1651. //
  1652. inline bool _variant_t::operator!=(const VARIANT& varSrc) const throw(_com_error)
  1653. {
  1654.     return !(*this == &varSrc);
  1655. }
  1656.  
  1657. // Compare a _variant_t against a const VARIANT* for in-equality
  1658. //
  1659. inline bool _variant_t::operator!=(const VARIANT* pSrc) const throw(_com_error)
  1660. {
  1661.     return !(*this == pSrc);
  1662. }
  1663.  
  1664. //////////////////////////////////////////////////////////////////////////////////////////
  1665. //
  1666. // Low-level operations
  1667. //
  1668. //////////////////////////////////////////////////////////////////////////////////////////
  1669.  
  1670. // Clear the _variant_t
  1671. //
  1672. inline void _variant_t::Clear() throw(_com_error)
  1673. {
  1674.     _com_util::CheckError(::VariantClear(this));
  1675. }
  1676.  
  1677. inline void _variant_t::Attach(VARIANT& varSrc) throw(_com_error)
  1678. {
  1679.     //
  1680.     // Free up previous VARIANT
  1681.     //
  1682.     Clear();
  1683.  
  1684.     //
  1685.     // Give control of data to _variant_t
  1686.     //
  1687.     memcpy(this, &varSrc, sizeof(varSrc));
  1688.     V_VT(&varSrc) = VT_EMPTY;
  1689. }
  1690.  
  1691. inline VARIANT _variant_t::Detach() throw(_com_error)
  1692. {
  1693.     VARIANT varResult = *this;
  1694.     V_VT(this) = VT_EMPTY;
  1695.  
  1696.     return varResult;
  1697. }
  1698.  
  1699. // Change the type and contents of this _variant_t to the type vartype and
  1700. // contents of pSrc
  1701. //
  1702. inline void _variant_t::ChangeType(VARTYPE vartype, const _variant_t* pSrc) throw(_com_error)
  1703. {
  1704.     //
  1705.     // If pDest is NULL, convert type in place
  1706.     //
  1707.     if (pSrc == NULL) {
  1708.         pSrc = this;
  1709.     }
  1710.  
  1711.     if ((this != pSrc) || (vartype != V_VT(this))) {
  1712.         _com_util::CheckError(::VariantChangeType(static_cast<VARIANT*>(this),
  1713.                                                   const_cast<VARIANT*>(static_cast<const VARIANT*>(pSrc)),
  1714.                                                   0, vartype));
  1715.     }
  1716. }
  1717.  
  1718. inline void _variant_t::SetString(const char* pSrc) throw(_com_error)
  1719. {
  1720.     //
  1721.     // Free up previous VARIANT
  1722.     //
  1723.     Clear();
  1724.  
  1725.     V_VT(this) = VT_BSTR;
  1726.     V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
  1727.  
  1728.     if (V_BSTR(this) == NULL && pSrc != NULL) {
  1729.         _com_issue_error(E_OUTOFMEMORY);
  1730.     }
  1731. }
  1732.  
  1733. //////////////////////////////////////////////////////////////////////////////////////////
  1734. //
  1735. // Destructor
  1736. //
  1737. //////////////////////////////////////////////////////////////////////////////////////////
  1738.  
  1739. inline _variant_t::~_variant_t() throw(_com_error)
  1740. {
  1741.     _com_util::CheckError(::VariantClear(this));
  1742. }
  1743.  
  1744. //////////////////////////////////////////////////////////////////////////////////////////
  1745. //
  1746. // Mutually-dependent definitions
  1747. //
  1748. //////////////////////////////////////////////////////////////////////////////////////////
  1749.  
  1750. // Construct a _bstr_t from a const _variant_t&
  1751. //
  1752. inline _bstr_t::_bstr_t(const _variant_t &var) throw(_com_error)
  1753.     : m_Data(NULL)
  1754. {
  1755.     if (V_VT(&var) == VT_BSTR) {
  1756.         *this = V_BSTR(&var);
  1757.         return;
  1758.     }
  1759.  
  1760.     _variant_t varDest;
  1761.  
  1762.     varDest.ChangeType(VT_BSTR, &var);
  1763.  
  1764.     *this = V_BSTR(&varDest);
  1765. }
  1766.  
  1767. // Assign a const _variant_t& to a _bstr_t
  1768. //
  1769. inline _bstr_t& _bstr_t::operator=(const _variant_t &var) throw(_com_error)
  1770. {
  1771.     if (V_VT(&var) == VT_BSTR) {
  1772.         *this = V_BSTR(&var);
  1773.         return *this;
  1774.     }
  1775.  
  1776.     _variant_t varDest;
  1777.  
  1778.     varDest.ChangeType(VT_BSTR, &var);
  1779.  
  1780.     *this = V_BSTR(&varDest);
  1781.  
  1782.     return *this;
  1783. }
  1784.  
  1785. extern _variant_t vtMissing;
  1786.  
  1787. #ifndef _USE_RAW
  1788. #define bstr_t _bstr_t
  1789. #define variant_t _variant_t
  1790. #endif
  1791.  
  1792. #pragma warning(pop)
  1793.  
  1794. #pragma option pop /*P_O_Pop*/
  1795. #endif    // _INC_COMUTIL
  1796.