T_SafeVector.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:11k
源码类别:

模拟服务器

开发平台:

C/C++

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