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