home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / MetaInfo / cahlpr.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  5.7 KB  |  192 lines

  1. //*****************************************************************************
  2. // File: CAHLPR.H
  3. //
  4. // This file contains a set of "as is" code that may be used by developers
  5. // writing compilers and tools against the COM+ Runtime.  The code is not
  6. // officially supported, but is code being used by the Runtime itself.
  7. //
  8. // Copyright (c) 1996-1999 Microsoft Corporation.  All Rights Reserved.
  9. //*****************************************************************************
  10. #ifndef __CAHLPR_H__
  11. #define __CAHLPR_H__
  12.  
  13. //*****************************************************************************
  14. // This class assists in the parsing of CustomAttribute blobs.
  15. //*****************************************************************************
  16. #pragma warning(push)
  17. #pragma warning(disable : 4700)
  18.  
  19. struct CaValue
  20. {
  21.     union
  22.     {
  23.         signed __int8       i1;   
  24.         unsigned __int8     u1;
  25.         signed __int16      i2;
  26.         unsigned __int16    u2;
  27.         signed __int32      i4;
  28.         unsigned __int32    u4;
  29.         signed __int64      i8;
  30.         unsigned __int64    u8;
  31.         float               r4;
  32.         double              r8;
  33.         struct
  34.         {
  35.             LPCUTF8         pStr;
  36.             ULONG           cbStr;
  37.         };
  38.     };
  39.     unsigned __int8         tag;
  40. };
  41.  
  42.  
  43. class CustomAttributeParser {
  44. public:
  45.     CustomAttributeParser(                // Constructor for CustomAttributeParser.
  46.         const void *pvBlob,             // Pointer to the CustomAttribute blob.
  47.         ULONG     cbBlob)                 // Size of the CustomAttribute blob.
  48.      :  m_pbBlob(reinterpret_cast<const BYTE*>(pvBlob)),
  49.         m_pbCur(reinterpret_cast<const BYTE*>(pvBlob)),
  50.         m_cbBlob(cbBlob)
  51.     { }
  52.     
  53.  
  54.     signed __int8      GetI1() {signed __int8    tmp=0; return GetValue(tmp); }
  55.     unsigned __int8  GetU1() {unsigned __int8  tmp=0; return GetValue(tmp); }
  56.          
  57.     signed __int16      GetI2() {signed __int16   tmp=0; return GetValue(tmp); }
  58.     unsigned __int16 GetU2() {unsigned __int16 tmp=0; return GetValue(tmp); }
  59.          
  60.     signed __int32      GetI4() {signed __int32   tmp=0; return GetValue(tmp); }
  61.     unsigned __int32 GetU4() {unsigned __int32 tmp=0; return GetValue(tmp); }
  62.          
  63.     signed __int64      GetI8() {signed __int64   tmp=0; return GetValue(tmp); }
  64.     unsigned __int64 GetU8() {unsigned __int64 tmp=0; return GetValue(tmp); }
  65.          
  66.     float             GetR4() {float            tmp=0; return GetValue(tmp); }
  67.     double              GetR8() {double           tmp=0; return GetValue(tmp); }
  68.          
  69.     
  70.     HRESULT GetI1(signed __int8 *pVal)      {return GetValue2(pVal);}
  71.     HRESULT GetU1(unsigned __int8 *pVal)    {return GetValue2(pVal);}
  72.          
  73.     HRESULT GetI2(signed __int16 *pVal)     {return GetValue2(pVal);}
  74.     HRESULT GetU2(unsigned __int16 *pVal)   {return GetValue2(pVal);}
  75.          
  76.     HRESULT GetI4(signed __int32 *pVal)     {return GetValue2(pVal);}
  77.     HRESULT GetU4(unsigned __int32 *pVal)   {return GetValue2(pVal);}
  78.          
  79.     HRESULT GetI8(signed __int64 *pVal)     {return GetValue2(pVal);}
  80.     HRESULT GetU8(unsigned __int64 *pVal)   {return GetValue2(pVal);}
  81.          
  82.     HRESULT GetR4(float *pVal)              {return GetValue2(pVal);}
  83.     HRESULT GetR8(double *pVal)             {return GetValue2(pVal);}
  84.          
  85.     
  86.     short GetProlog() {m_pbCur = m_pbBlob; return GetI2(); }
  87.  
  88.     int GetTagType ( )    {return GetU1();}
  89.     
  90.     ULONG PeekStringLength() {ULONG cb; UnpackValue(m_pbCur, &cb); return cb;}
  91.     LPCUTF8 GetString(ULONG *pcbString) 
  92.     {
  93.         // Get the length, pointer to data following the length.
  94.         const BYTE *pb = UnpackValue(m_pbCur, pcbString); 
  95.         m_pbCur = pb;
  96.         // If null pointer is coded, no data follows length.
  97.         if (*pcbString == -1)
  98.             return (0);
  99.         // Adjust current pointer for string data.
  100.         m_pbCur += *pcbString;
  101.         // Return pointer to string data.
  102.         return (reinterpret_cast<LPCUTF8>(pb));
  103.     }
  104.  
  105.     ULONG GetArraySize () 
  106.     {
  107.         ULONG cb;
  108.         m_pbCur = UnpackValue(m_pbCur, &cb);
  109.         return cb;
  110.     }
  111.  
  112.     int BytesLeft() {return (int)(m_cbBlob - (m_pbCur - m_pbBlob));}
  113.     
  114. private:
  115.     const BYTE     *m_pbCur;
  116.     const BYTE    *m_pbBlob;
  117.     ULONG        m_cbBlob;
  118.  
  119.     template<class type>
  120.         type GetValue(type tmp) 
  121.     {    // Cheating just a bit -- using the parameter to declare a temporary.
  122.         //  works as the template specialization, though.
  123.         tmp = *reinterpret_cast<const type*>(m_pbCur); 
  124.         m_pbCur += sizeof(type); 
  125.         return tmp; 
  126.     }
  127.  
  128.     template<class type>
  129.         HRESULT GetValue2(type *pval) 
  130.     {    // Check bytes remaining.
  131.         if (BytesLeft() < sizeof(type)) 
  132.             return META_E_CA_INVALID_BLOB;
  133.         // Get the value.
  134.         *pval = *reinterpret_cast<const type*>(m_pbCur); 
  135.         m_pbCur += sizeof(type); 
  136.         return S_OK; 
  137.     }
  138.  
  139.     const BYTE *UnpackValue(                // Uppack a coded integer.
  140.         const BYTE    *pBytes,                 // First byte of length.
  141.         ULONG         *pcb)                    // Put the value here.
  142.     {
  143.         int iLeft = BytesLeft();
  144.         if (iLeft < 1)
  145.         {
  146.             *pcb = -1;
  147.             return 0;
  148.         }
  149.         if ((*pBytes & 0x80) == 0x00)        // 0??? ????
  150.         {
  151.             *pcb = (*pBytes & 0x7f);
  152.             return pBytes + 1;
  153.         }
  154.     
  155.         if ((*pBytes & 0xC0) == 0x80)        // 10?? ????
  156.         {
  157.             if (iLeft < 2)
  158.             {
  159.                 *pcb = -1;
  160.                 return 0;
  161.             }
  162.             *pcb = ((*pBytes & 0x3f) << 8 | *(pBytes+1));
  163.             return pBytes + 2;
  164.         }
  165.     
  166.         if ((*pBytes & 0xE0) == 0xC0)        // 110? ????
  167.         {
  168.             if (iLeft < 4)
  169.             {
  170.                 *pcb = -1;
  171.                 return 0;
  172.             }
  173.             *pcb = ((*pBytes & 0x1f) << 24 | *(pBytes+1) << 16 | *(pBytes+2) << 8 | *(pBytes+3));
  174.             return pBytes + 4;
  175.         }
  176.     
  177.         if (*pBytes == 0xff)                // Special value for "NULL pointer"
  178.         {
  179.             *pcb = (-1);
  180.             return pBytes + 1;
  181.         }
  182.  
  183.         _ASSERTE(!"Unexpected packed value");
  184.         *pcb = -1;
  185.         return pBytes + 1;
  186.     } // ULONG UnpackValue()
  187. };
  188. #pragma warning(pop)
  189.  
  190. #endif // __CAHLPR_H__
  191.  
  192.