The Labs \ Source Viewer \ SSCLI \ System.Reflection.Emit \ UnmanagedMarshal

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Reflection.Emit
  16. {
  17.     using System.Runtime.InteropServices;
  18.     using System;
  19.     using System.Security.Permissions;
  20.    
  21.     // This class is describing the fieldmarshal.
  22.     [Serializable()]
  23.     [HostProtection(MayLeakOnAbort = true)]
  24.     [System.Runtime.InteropServices.ComVisible(true)]
  25.     [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
  26.     public sealed class UnmanagedMarshal
  27.     {
  28. /******************************
  29. [System.Runtime.InteropServices.ComVisible(true)]
  30.         * public static constructors. You can only construct
  31.         * UnmanagedMarshal using these static constructors.
  32.         ******************************/       
  33.         public static UnmanagedMarshal DefineUnmanagedMarshal(UnmanagedType unmanagedType)
  34.         {
  35.             if (unmanagedType == UnmanagedType.ByValTStr || unmanagedType == UnmanagedType.ByValArray || unmanagedType == UnmanagedType.LPArray || unmanagedType == UnmanagedType.CustomMarshaler) {
  36.                 // not a simple native marshal
  37.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotASimpleNativeType"));
  38.             }
  39.             return new UnmanagedMarshal(unmanagedType, Guid.Empty, 0, (UnmanagedType)0);
  40.         }
  41.         public static UnmanagedMarshal DefineByValTStr(int elemCount)
  42.         {
  43.             return new UnmanagedMarshal(UnmanagedType.ByValTStr, Guid.Empty, elemCount, (UnmanagedType)0);
  44.         }
  45.        
  46.        
  47.         public static UnmanagedMarshal DefineByValArray(int elemCount)
  48.         {
  49.             return new UnmanagedMarshal(UnmanagedType.ByValArray, Guid.Empty, elemCount, (UnmanagedType)0);
  50.         }
  51.        
  52.         public static UnmanagedMarshal DefineLPArray(UnmanagedType elemType)
  53.         {
  54.             return new UnmanagedMarshal(UnmanagedType.LPArray, Guid.Empty, 0, elemType);
  55.         }
  56.        
  57.        
  58.        
  59.        
  60.        
  61.        
  62.         // accessor function for the native type
  63.         public UnmanagedType GetUnmanagedType {
  64.             get { return m_unmanagedType; }
  65.         }
  66.        
  67.         public Guid IIDGuid {
  68.             get {
  69.                 if (m_unmanagedType != UnmanagedType.CustomMarshaler) {
  70.                     // throw exception here. There is Guid only if CustomMarshaler
  71.                     throw new ArgumentException(Environment.GetResourceString("Argument_NotACustomMarshaler"));
  72.                 }
  73.                 return m_guid;
  74.             }
  75.         }
  76.         public int ElementCount {
  77.             get {
  78.                 if (m_unmanagedType != UnmanagedType.ByValArray && m_unmanagedType != UnmanagedType.ByValTStr) {
  79.                     // throw exception here. There is NumElement only if NativeTypeFixedArray
  80.                     throw new ArgumentException(Environment.GetResourceString("Argument_NoUnmanagedElementCount"));
  81.                 }
  82.                 return m_numElem;
  83.             }
  84.         }
  85.         public UnmanagedType BaseType {
  86.             get {
  87.                 if (m_unmanagedType != UnmanagedType.LPArray) {
  88.                     // throw exception here. There is NestedUnmanagedType only if LPArray or SafeArray
  89.                     throw new ArgumentException(Environment.GetResourceString("Argument_NoNestedMarshal"));
  90.                 }
  91.                 return m_baseType;
  92.             }
  93.         }
  94.        
  95.         private UnmanagedMarshal(UnmanagedType unmanagedType, Guid guid, int numElem, UnmanagedType type)
  96.         {
  97.             m_unmanagedType = unmanagedType;
  98.             m_guid = guid;
  99.             m_numElem = numElem;
  100.             m_baseType = type;
  101.         }
  102.        
  103. /************************
  104.         *
  105.         * Data member
  106.         *
  107.         *************************/       
  108.         internal UnmanagedType m_unmanagedType;
  109.         internal Guid m_guid;
  110.         internal int m_numElem;
  111.         internal UnmanagedType m_baseType;
  112.        
  113.        
  114. /************************
  115.         * this function return the byte representation of the marshal info.
  116.         *************************/       
  117.         internal byte[] InternalGetBytes()
  118.         {
  119.             byte[] buf;
  120.             if (m_unmanagedType == UnmanagedType.LPArray) {
  121.                
  122.                 // syntax for NativeTypeSafeArray is
  123.                 // <SafeArray | LPArray> <base type>
  124.                 //
  125.                 int cBuf = 2;
  126.                 buf = new byte[cBuf];
  127.                 buf[0] = (byte)(m_unmanagedType);
  128.                 buf[1] = (byte)(m_baseType);
  129.                 return buf;
  130.             }
  131.             else if (m_unmanagedType == UnmanagedType.ByValArray || m_unmanagedType == UnmanagedType.ByValTStr) {
  132.                 // <ByValArray | ByValTStr> <encoded integer>
  133.                 //
  134.                 int cBuf;
  135.                 int iBuf = 0;
  136.                
  137.                 if (m_numElem <= 127)
  138.                     cBuf = 1;
  139.                 else if (m_numElem <= 16383)
  140.                     cBuf = 2;
  141.                 else
  142.                     cBuf = 4;
  143.                
  144.                 // the total buffer size is the one byte + encoded integer size
  145.                 cBuf = cBuf + 1;
  146.                 buf = new byte[cBuf];
  147.                
  148.                
  149.                 buf[iBuf++] = (byte)(m_unmanagedType);
  150.                 if (m_numElem <= 127) {
  151.                     buf[iBuf++] = (byte)(m_numElem & 255);
  152.                 }
  153.                 else if (m_numElem <= 16383) {
  154.                     buf[iBuf++] = (byte)((m_numElem >> 8) | 128);
  155.                     buf[iBuf++] = (byte)(m_numElem & 255);
  156.                 }
  157.                 else if (m_numElem <= 536870911) {
  158.                     buf[iBuf++] = (byte)((m_numElem >> 24) | 192);
  159.                     buf[iBuf++] = (byte)((m_numElem >> 16) & 255);
  160.                     buf[iBuf++] = (byte)((m_numElem >> 8) & 255);
  161.                     buf[iBuf++] = (byte)((m_numElem)&255);
  162.                 }
  163.                 return buf;
  164.             }
  165.             buf = new byte[1];
  166.             buf[0] = (byte)(m_unmanagedType);
  167.             return buf;
  168.         }
  169.     }
  170. }

Developer Fusion