Merge pull request #347 from JamesB7/master
[mono.git] / mcs / class / IKVM.Reflection / Util.cs
1 /*
2   Copyright (C) 2008-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Runtime.Serialization;
27
28 namespace IKVM.Reflection
29 {
30         public interface ICustomAttributeProvider
31         {
32                 bool IsDefined(Type attributeType, bool inherit);
33                 IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit);
34         }
35
36         [Serializable]
37         public sealed class FileFormatLimitationExceededException : InvalidOperationException
38         {
39                 public const int META_E_STRINGSPACE_FULL = unchecked((int)0x80131198);
40
41                 public FileFormatLimitationExceededException(string message, int hresult)
42                         : base(message)
43                 {
44                         this.HResult = hresult;
45                 }
46
47                 private FileFormatLimitationExceededException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
48                         : base(info, context)
49                 {
50                 }
51
52                 public int ErrorCode
53                 {
54                         get { return this.HResult; }
55                 }
56         }
57
58         [Serializable]
59         public sealed class Missing : ISerializable
60         {
61                 public static readonly Missing Value = new Missing();
62
63                 private Missing() { }
64
65                 void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
66                 {
67                         info.SetType(typeof(SingletonSerializationHelper));
68                 }
69
70                 [Serializable]
71                 private sealed class SingletonSerializationHelper : IObjectReference
72                 {
73                         public object GetRealObject(StreamingContext context)
74                         {
75                                 return Value;
76                         }
77                 }
78         }
79
80         static class Empty<T>
81         {
82                 internal static readonly T[] Array = new T[0];
83         }
84
85         static class Util
86         {
87                 internal static int[] Copy(int[] array)
88                 {
89                         if (array == null || array.Length == 0)
90                         {
91                                 return Empty<int>.Array;
92                         }
93                         int[] copy = new int[array.Length];
94                         Array.Copy(array, copy, array.Length);
95                         return copy;
96                 }
97
98                 internal static Type[] Copy(Type[] array)
99                 {
100                         if (array == null || array.Length == 0)
101                         {
102                                 return Type.EmptyTypes;
103                         }
104                         Type[] copy = new Type[array.Length];
105                         Array.Copy(array, copy, array.Length);
106                         return copy;
107                 }
108
109                 internal static T[] ToArray<T, V>(List<V> list, T[] empty) where V : T
110                 {
111                         if (list == null || list.Count == 0)
112                         {
113                                 return empty;
114                         }
115                         T[] array = new T[list.Count];
116                         for (int i = 0; i < array.Length; i++)
117                         {
118                                 array[i] = list[i];
119                         }
120                         return array;
121                 }
122
123                 internal static T[] ToArray<T>(IEnumerable<T> values)
124                 {
125                         return values == null
126                                 ? Empty<T>.Array
127                                 : new List<T>(values).ToArray();
128                 }
129
130                 // note that an empty array matches a null reference
131                 internal static bool ArrayEquals(Type[] t1, Type[] t2)
132                 {
133                         if (t1 == t2)
134                         {
135                                 return true;
136                         }
137                         if (t1 == null)
138                         {
139                                 return t2.Length == 0;
140                         }
141                         else if (t2 == null)
142                         {
143                                 return t1.Length == 0;
144                         }
145                         if (t1.Length == t2.Length)
146                         {
147                                 for (int i = 0; i < t1.Length; i++)
148                                 {
149                                         if (!TypeEquals(t1[i], t2[i]))
150                                         {
151                                                 return false;
152                                         }
153                                 }
154                                 return true;
155                         }
156                         return false;
157                 }
158
159                 internal static bool TypeEquals(Type t1, Type t2)
160                 {
161                         if (t1 == t2)
162                         {
163                                 return true;
164                         }
165                         if (t1 == null)
166                         {
167                                 return false;
168                         }
169                         return t1.Equals(t2);
170                 }
171
172                 internal static int GetHashCode(Type[] types)
173                 {
174                         if (types == null)
175                         {
176                                 return 0;
177                         }
178                         int h = 0;
179                         foreach (Type t in types)
180                         {
181                                 if (t != null)
182                                 {
183                                         h *= 3;
184                                         h ^= t.GetHashCode();
185                                 }
186                         }
187                         return h;
188                 }
189
190                 internal static bool ArrayEquals(CustomModifiers[] m1, CustomModifiers[] m2)
191                 {
192                         if (m1 == null || m2 == null)
193                         {
194                                 return m1 == m2;
195                         }
196                         if (m1.Length != m2.Length)
197                         {
198                                 return false;
199                         }
200                         for (int i = 0; i < m1.Length; i++)
201                         {
202                                 if (!m1[i].Equals(m2[i]))
203                                 {
204                                         return false;
205                                 }
206                         }
207                         return true;
208                 }
209
210                 internal static int GetHashCode(CustomModifiers[] mods)
211                 {
212                         int h = 0;
213                         if (mods != null)
214                         {
215                                 foreach (CustomModifiers mod in mods)
216                                 {
217                                         h ^= mod.GetHashCode();
218                                 }
219                         }
220                         return h;
221                 }
222
223                 internal static T NullSafeElementAt<T>(T[] array, int index)
224                 {
225                         return array == null ? default(T) : array[index];
226                 }
227
228                 internal static int NullSafeLength<T>(T[] array)
229                 {
230                         return array == null ? 0 : array.Length;
231                 }
232         }
233
234         [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
235         struct SingleConverter
236         {
237                 [System.Runtime.InteropServices.FieldOffset(0)]
238                 private int i;
239                 [System.Runtime.InteropServices.FieldOffset(0)]
240                 private float f;
241
242                 internal static int SingleToInt32Bits(float v)
243                 {
244                         SingleConverter c = new SingleConverter();
245                         c.f = v;
246                         return c.i;
247                 }
248
249                 internal static float Int32BitsToSingle(int v)
250                 {
251                         SingleConverter c = new SingleConverter();
252                         c.i = v;
253                         return c.f;
254                 }
255         }
256 }