home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / C++ / FreeCommandLineTools.exe / Include / t_safevector.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-31  |  11.4 KB  |  486 lines

  1. //-------------------------------------------------------------------------------------
  2. // T_SafeVector.h
  3. //
  4. //  The follwing template classes provide a way of creating and accessing SafeArrays.
  5. //  They are derived from the C++ standard library (STL) vector class and can be used
  6. //  the same way. They can be accessed just like an array (with the [] operator).
  7. //
  8. //  Use the constructors or assignment operators to extract the SafeArray from a 
  9. //  SAFEARRAY* or array variant (VARIANT or _variant_t). The elements will be 
  10. //  copied into the vector.  Use the GetSafeArray() or GetVariant() methods to pack
  11. //  the elements back into a SafeArray.
  12. //
  13. //  To create a new SafeArray, declare a varaible of the appropriate type and call
  14. //  resize() to set the size, or push_back() to grow the array. Call GetSafeArray() 
  15. //  or GetVariant() to produce a SafeArray.
  16. //
  17. //  See the T_SafeVector2 class at the bottom of this file for more information 
  18. //  about the constructors, extractors, and assignment operators.
  19. // 
  20. //  Use the following pre-defined array types:
  21. //
  22. //           Array Type              -    Element Type
  23. //    -----------------------------------------------------------------------------
  24. //       _bstr_tSafeVector           -    BSTR (uses _bstr_t)
  25. //       longSafeVector              -    long
  26. //       shortSafeVector             -    short
  27. //       byteSafeVector              -    byte 
  28. //       boolSafeVector              -    bool
  29. //       CWbemClassObjectSafeVector  -    IWbemClassObject (uses CWbemClassObject)
  30. //
  31. //  Copyright (c)1997-99 Microsoft Corporation, All Rights Reserved
  32. //------------------------------------------------------------------------------------
  33.  
  34. #if !defined(__T_SafeVector_H)
  35. #pragma option push -b -a8 -pc -A- /*P_O_Push*/
  36. #define      __T_SafeVector_H
  37. #pragma once
  38.  
  39. #pragma warning( disable : 4786) // identifier was truncated to 'number' characters in the debug information
  40. #pragma warning( disable : 4503) // decorated name length exceeded, name was truncated
  41.  
  42.  
  43. typedef std::vector<_bstr_t>            _bstr_tVec;
  44. typedef std::vector<long>               longVec;
  45. typedef std::vector<short>              shortVec;
  46. typedef std::vector<unsigned char>      byteVec;
  47. typedef std::vector<bool>               boolVec;
  48.  
  49. #if !defined(NO_WBEM)
  50. typedef std::vector<CWbemClassObject>   coVec;
  51. #endif
  52.  
  53.  
  54.  
  55. template<typename TNContainer,typename TNDataType>
  56. class T_SAExtractScaler
  57. {
  58.     public:
  59.          void SetToContainer(TNContainer& _cont,void * pData,int l,int u)
  60.          {
  61.              TNDataType * pWalk = reinterpret_cast<TNDataType *>(pData);
  62.              
  63.              for(;l < (u+1);l++,pWalk++)
  64.              {
  65.                  _cont.push_back( *pWalk);
  66.              }
  67.          }
  68.          
  69.          void GetFromContainer
  70.              (
  71.              TNContainer& _cont,
  72.              void * pData,
  73.              TNContainer::iterator walk,
  74.              TNContainer::iterator finish
  75.              )
  76.          {
  77.              TNDataType * pWalk = reinterpret_cast<TNDataType *>(pData);
  78.              
  79.              for(;walk != finish;walk++,pWalk++)
  80.              {
  81.                  *pWalk = *walk;
  82.              }
  83.          }
  84.          
  85.          _bstr_t FormatDebugOutput
  86.              (
  87.              TNContainer::iterator first,
  88.              TNContainer::iterator item,
  89.              TNContainer::iterator last
  90.              )
  91.          {
  92.              _bstr_t sRet;
  93.              
  94.              try
  95.              {
  96.                  _variant_t v;
  97.                  
  98.                  v = v.operator=(TNDataType(*item));
  99.                  
  100.                  v.ChangeType(VT_BSTR);
  101.                  
  102.                  sRet = (_bstr_t) v;
  103.                  
  104.                  if( (item+1)!=last )
  105.                  {
  106.                      sRet += ", ";
  107.                  }
  108.              }
  109.              catch(_com_error&)
  110.              {
  111.                  sRet = "Not supported";
  112.              }
  113.              
  114.              return sRet;
  115.          }
  116. };
  117.  
  118.  
  119.  
  120.  
  121.  
  122. template<typename TNContainer>
  123. class T_Extract_bstr_t
  124. {
  125.     public:
  126.          T_Extract_bstr_t()
  127.          {
  128.          }
  129.          
  130.          void SetToContainer(TNContainer& _cont,void * pData,int l,int u)
  131.          {
  132.              BSTR * pWalk = reinterpret_cast<BSTR*>(pData);
  133.              
  134.              for(;l < (u+1);l++,pWalk++)
  135.              {
  136.                  _cont.push_back( _bstr_t(*pWalk,true) );
  137.              }
  138.          }
  139.          
  140.          void GetFromContainer
  141.              (
  142.              TNContainer& _cont,
  143.              void * pData,
  144.              TNContainer::iterator walk,
  145.              TNContainer::iterator finish
  146.              )
  147.          {
  148.              BSTR * pWalk = reinterpret_cast<BSTR*>(pData);
  149.              
  150.              for(;walk != finish;walk++,pWalk++)
  151.              {
  152.                  *pWalk = (*walk).copy();
  153.              }
  154.          }
  155.          
  156.          _bstr_t FormatDebugOutput
  157.              (
  158.              TNContainer::iterator first,
  159.              TNContainer::iterator item,
  160.              TNContainer::iterator last
  161.              )
  162.          {
  163.              _bstr_t sRet;
  164.              
  165.              sRet += "\"";
  166.              sRet += (*item);
  167.              sRet += "\"";
  168.              
  169.              if( (item+1)!=last )
  170.              {
  171.                  sRet += ", ";
  172.              }
  173.              
  174.              return sRet;
  175.          }
  176.          
  177. };
  178.  
  179.  
  180.  
  181. #if !defined(NO_WBEM)
  182.  
  183. template<typename TNContainer>
  184. class T_Extract_IUnknown
  185. {
  186.     public:
  187.          T_Extract_IUnknown()
  188.          {
  189.          }
  190.          
  191.          void SetToContainer(TNContainer& _cont,void * pData,int l,int u)
  192.          {
  193.              IUnknown ** pWalk = reinterpret_cast<IUnknown **>(pData);
  194.              
  195.              for(;l< (u+1);l++,pWalk++)
  196.              {
  197.                  _cont.push_back( CWbemClassObject((IWbemClassObject*)*pWalk) );
  198.              }
  199.          }
  200.          
  201.          void GetFromContainer
  202.              (
  203.              TNContainer& _cont,
  204.              void * pData,
  205.              TNContainer::iterator walk,
  206.              TNContainer::iterator finish
  207.              )
  208.          {
  209.              IUnknown ** pWalk = reinterpret_cast<IUnknown **>(pData);
  210.              
  211.              for(;walk != finish;walk++,pWalk++)
  212.              {
  213.                  (*walk)->AddRef();
  214.                  *pWalk = (*walk);
  215.              }
  216.          }
  217.          
  218.          _bstr_t FormatDebugOutput
  219.              (
  220.              TNContainer::iterator   first,    
  221.              TNContainer::iterator   item,
  222.              TNContainer::iterator   last
  223.              )
  224.          {
  225.              _bstr_t sRet;
  226.              
  227.              try
  228.              {
  229.                  _variant_t v( long(item -first) );
  230.                  v.ChangeType(VT_BSTR);
  231.                  _variant_t v2( long(last-first-1) );
  232.                  v2.ChangeType(VT_BSTR);
  233.                  
  234.                  sRet += "Object [";
  235.                  sRet += (_bstr_t)v;
  236.                  sRet += " of ";
  237.                  sRet += (_bstr_t)v2;
  238.                  sRet += "]\n";
  239.                  
  240.                  sRet += (*item).GetObjectText();
  241.                  
  242.                  if( (item+1) != last )
  243.                  {
  244.                      sRet += "\n";
  245.                  }
  246.              }
  247.              catch(_com_error&)
  248.              {
  249.                  sRet = "Not supported";
  250.              }
  251.              
  252.              return sRet;
  253.          }
  254.          
  255. };
  256.  
  257. #endif
  258.  
  259.  
  260. typedef T_SAExtractScaler<longVec,long>             __exptExtractlong;
  261. typedef T_SAExtractScaler<shortVec,short>           __exptExtractshort;
  262. typedef T_SAExtractScaler<byteVec,unsigned char>    __exptExtractbyte;
  263. typedef T_SAExtractScaler<boolVec,bool>             __exptExtractbool;
  264. typedef T_Extract_bstr_t<_bstr_tVec>                __exptExtract_bstr_t;
  265.  
  266. #if !defined(NO_WBEM)
  267. typedef T_Extract_IUnknown<coVec>                   __exptExtractco;
  268. #endif
  269.  
  270.  
  271. template<typename TNContainer,typename TNExtractor>
  272. class T_SafeArrayImp
  273. {
  274.     public:
  275.          void ConstructContainerFromSafeArray
  276.              (
  277.              TNExtractor&  _extract,
  278.              TNContainer& _cont,
  279.              SAFEARRAY * _pSA
  280.              )
  281.          {
  282.              long l = 0;
  283.              long u = 0;
  284.              
  285.              HRESULT hr;
  286.              void * pData;
  287.              
  288.              hr = SafeArrayGetLBound(_pSA,1,&l);
  289.              hr = SafeArrayGetUBound(_pSA,1,&u);
  290.              
  291.              hr = SafeArrayAccessData(_pSA,&pData);
  292.              
  293.              if(hr == S_OK)
  294.              {
  295.                  _extract.SetToContainer(_cont,pData,l,u);
  296.                  
  297.                  SafeArrayUnaccessData(_pSA);
  298.              }
  299.          }
  300.          
  301.          SAFEARRAY * ConstructSafeArrayFromConatiner
  302.              (
  303.              TNExtractor&            _extract,
  304.              VARTYPE                 _vt,
  305.              TNContainer&            _cont,
  306.              TNContainer::iterator   start,
  307.              TNContainer::iterator   finish
  308.              )
  309.          {
  310.              HRESULT         hr   = S_OK;
  311.              SAFEARRAY *     pRet = NULL;
  312.              SAFEARRAYBOUND  rgsabound[1];
  313.              void * pData;
  314.              
  315.              rgsabound[0].lLbound    = 0;
  316.              rgsabound[0].cElements  = _cont.size();
  317.              
  318.              pRet = SafeArrayCreate(_vt,1,rgsabound);
  319.              
  320.              if(pRet)
  321.              {
  322.                  hr = SafeArrayAccessData(pRet,&pData);
  323.                  
  324.                  if(hr == S_OK)
  325.                  {
  326.                      _extract.GetFromContainer(_cont,pData,start,finish);
  327.                      
  328.                      SafeArrayUnaccessData(pRet);
  329.                  }
  330.              }
  331.              
  332.              return pRet;
  333.          }
  334. };
  335.  
  336. ///////////////////////////////////////////////////////////////////////////
  337. // T_SafeVector2
  338. //
  339. // Derived from TNContainer which should be a type of STL vector.
  340. // Provides for the conversion between vector and SafeArray.
  341. // 
  342.  
  343. template
  344. <
  345. VARTYPE TNVariant,
  346. typename TNDataType,
  347. typename TNContainer = std::vector<TNDataType>,
  348. typename TNExtractor = T_SAExtractScaler<TNContainer,TNDataType>
  349. >
  350. class T_SafeVector2 : public TNContainer 
  351. {
  352.     private:
  353.          T_SafeArrayImp<TNContainer,TNExtractor> m_Array;
  354.     protected:
  355.     public:
  356.          
  357.          T_SafeVector2()
  358.          {
  359.          }
  360.          
  361.          // copy constructor
  362.          T_SafeVector2(const TNContainer& _copy) : TNContainer(_copy)
  363.          {
  364.          }
  365.          
  366.          
  367.          // Construct vector from array variant, extracts elements
  368.          T_SafeVector2(_variant_t& _ValueArray)
  369.          {
  370.              if(_ValueArray.vt & VT_ARRAY)
  371.              {
  372.                  m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_ValueArray.parray);
  373.              }
  374.          }
  375.          
  376.          // Construct vector from SAFEARRAY, extracts elements
  377.          T_SafeVector2(SAFEARRAY * _pArray)
  378.          {
  379.              m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_pArray);
  380.          }
  381.          
  382.          // assign vector from array variant, extracts elements
  383.          T_SafeVector2& operator=(_variant_t& _ValueArray)
  384.          {
  385.              clear();
  386.              
  387.              if(_ValueArray.vt & VT_ARRAY)
  388.              {
  389.                  m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_ValueArray.parray);
  390.              }
  391.              
  392.              return *this;
  393.          }
  394.          
  395.          // assign vector from SAFEARRAY, extracts elements
  396.          T_SafeVector2& operator=(SAFEARRAY * _pArray)
  397.          {
  398.              clear();
  399.              m_Array.ConstructContainerFromSafeArray(TNExtractor(),*this,_pArray);
  400.              return *this;
  401.          }
  402.          
  403.          // assign vector from another vector, copies elements
  404.          T_SafeVector2& operator=(const TNContainer& _copy)
  405.          {
  406.              TNContainer::operator=(_copy);
  407.              return *this;
  408.          }
  409.          
  410.          ~T_SafeVector2()
  411.          {
  412.          }
  413.          
  414.          // create SafeArray from a portion of the vector elements and return a SAFEARRAY*
  415.          SAFEARRAY *  GetSafeArray(TNContainer::iterator start,TNContainer::iterator finish)
  416.          {
  417.              return m_Array.ConstructSafeArrayFromConatiner(TNExtractor(),TNVariant,*this,start,finish);
  418.          }
  419.          
  420.          // create SafeArray from the vector elements and return a SAFEARRAY*
  421.        SAFEARRAY * GetSafeArray()
  422.          {
  423.              return GetSafeArray(begin(),end());
  424.          }
  425.          
  426.        // create SafeArray from a portion of the vector elements and return as an array variant
  427.        _variant_t GetVariant(TNContainer::iterator start,TNContainer::iterator finish)
  428.          {
  429.              _variant_t vRet;
  430.              
  431.              vRet.vt        = TNVariant|VT_ARRAY;
  432.              vRet.parray    = GetSafeArray(start,finish);
  433.              
  434.              return vRet;
  435.          }
  436.          
  437.        // create SafeArray from the vector elements and return as an array variant
  438.        _variant_t GetVariant()
  439.          {
  440.              return GetVariant(begin(),end());
  441.          }
  442.          
  443.          _bstr_t FormatDebugOutput()
  444.          {
  445.              _bstr_t sOutput;
  446.              
  447.              for(iterator walk = begin();walk != end();walk++)
  448.              {
  449.                  sOutput += TNExtractor().FormatDebugOutput(begin(),walk,end());
  450.              }
  451.              
  452.              return sOutput;
  453.          }
  454. };
  455.  
  456.  
  457.  
  458. typedef T_SafeVector2
  459. <
  460. VT_BSTR,
  461. _bstr_t,
  462. _bstr_tVec,
  463. T_Extract_bstr_t<_bstr_tVec>
  464. >  
  465. _bstr_tSafeVector;
  466.  
  467.  
  468. typedef T_SafeVector2<VT_I4,long>           longSafeVector;
  469. typedef T_SafeVector2<VT_I2,short>          shortSafeVector;
  470. typedef T_SafeVector2<VT_UI1,unsigned char> byteSafeVector;
  471. typedef T_SafeVector2<VT_BOOL,bool>         boolSafeVector;
  472.  
  473. #if !defined(NO_WBEM)
  474. typedef T_SafeVector2
  475. <
  476. VT_UNKNOWN,
  477. CWbemClassObject,
  478. std::vector<CWbemClassObject>,
  479. T_Extract_IUnknown<std::vector<CWbemClassObject> >
  480. CWbemClassObjectSafeVector;
  481. #endif
  482.  
  483.  
  484. #pragma option pop /*P_O_Pop*/
  485. #endif // __T_SafeVector_H