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