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