07b0f554ca2e46070afdafe6eec3b777bc6635b7
[mono.git] / mcs / class / corlib / System / Variant.cs
1 //
2 // System.Variant
3 //
4 // Authors:
5 //   Jonathan Chambers <jonathan.chambers@ansys.com>
6 //
7 // Copyright (C) 2006 Novell (http://www.novell.com)
8 //
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Runtime.InteropServices;
31
32 namespace System
33 {
34         [StructLayout(LayoutKind.Explicit, Size = 16)]
35         internal unsafe struct Variant
36         {
37                 [FieldOffset(0)]
38                 public short vt;
39
40                 [FieldOffset(2)]
41                 public ushort wReserved1;
42
43                 [FieldOffset(4)]
44                 public ushort wReserved2;
45
46                 [FieldOffset(6)]
47                 public ushort wReserved3;
48
49                 [FieldOffset(8)]
50                 public long llVal;
51
52                 [FieldOffset(8)]
53                 public int lVal;
54
55                 [FieldOffset(8)]
56                 public byte bVal;
57
58                 [FieldOffset(8)]
59                 public short iVal;
60
61                 [FieldOffset(8)]
62                 public float fltVal;
63
64                 [FieldOffset(8)]
65                 public double dblVal;
66
67                 [FieldOffset(8)]
68                 public short boolVal;
69
70                 [FieldOffset(8)]
71                 public IntPtr bstrVal;
72
73                 [FieldOffset(8)]
74                 public sbyte cVal;
75
76                 [FieldOffset(8)]
77                 public ushort uiVal;
78
79                 [FieldOffset(8)]
80                 public uint ulVal;
81
82                 [FieldOffset(8)]
83                 public ulong ullVal;
84
85                 [FieldOffset(8)]
86                 public int intVal;
87
88                 [FieldOffset(8)]
89                 public uint uintVal;
90
91                 public void SetValue(object obj) {
92                         vt = (short)VarEnum.VT_EMPTY;
93                         if (obj == null)
94                                 return;
95
96                         Type t = obj.GetType();
97                         if (t == typeof(sbyte))
98                         {
99                                 vt = (short)VarEnum.VT_I1;
100                                 cVal = (sbyte)obj;
101                         }
102                         else if (t == typeof(byte))
103                         {
104                                 vt = (short)VarEnum.VT_UI1;
105                                 bVal = (byte)obj;
106                         }
107                         else if (t == typeof(short))
108                         {
109                                 vt = (short)VarEnum.VT_I2;
110                                 iVal = (short)obj;
111                         }
112                         else if (t == typeof(ushort))
113                         {
114                                 vt = (short)VarEnum.VT_UI2;
115                                 uiVal = (ushort)obj;
116                         }
117                         else if (t == typeof(int))
118                         {
119                                 vt = (short)VarEnum.VT_I4;
120                                 lVal = (int)obj;
121                         }
122                         else if (t == typeof(uint))
123                         {
124                                 vt = (short)VarEnum.VT_UI4;
125                                 ulVal = (uint)obj;
126                         }
127                         else if (t == typeof(long))
128                         {
129                                 vt = (short)VarEnum.VT_I8;
130                                 llVal = (long)obj;
131                         }
132                         else if (t == typeof(ulong))
133                         {
134                                 vt = (short)VarEnum.VT_UI8;
135                                 ullVal = (ulong)obj;
136                         }
137                         else if (t == typeof(float))
138                         {
139                                 vt = (short)VarEnum.VT_R4;
140                                 fltVal = (float)obj;
141                         }
142                         else if (t == typeof(double))
143                         {
144                                 vt = (short)VarEnum.VT_R8;
145                                 dblVal = (double)obj;
146                         }
147                         else if (t == typeof(string))
148                         {
149                                 vt = (short)VarEnum.VT_BSTR;
150                                 bstrVal = Marshal.StringToBSTR((string)obj);
151                         }
152                         else
153                         {
154                                 throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()));
155                         }
156                 }
157
158                 public object GetValue() {
159                         object obj = null;
160                         switch ((VarEnum)vt)
161                         {
162                         case VarEnum.VT_I1:
163                         obj = cVal;
164                         break;
165                         case VarEnum.VT_UI1:
166                                 obj = bVal;
167                                 break;
168                         case VarEnum.VT_I2:
169                                 obj = iVal;
170                                 break;
171                         case VarEnum.VT_UI2:
172                                 obj = uiVal;
173                                 break;
174                         case VarEnum.VT_I4:
175                                 obj = lVal;
176                                 break;
177                         case VarEnum.VT_UI4:
178                                 obj = ulVal;
179                                 break;
180                         case VarEnum.VT_I8:
181                                 obj = llVal;
182                                 break;
183                         case VarEnum.VT_UI8:
184                                 obj = ullVal;
185                                 break;
186                         case VarEnum.VT_R4:
187                                 obj = fltVal;
188                                 break;
189                         case VarEnum.VT_R8:
190                                 obj = dblVal;
191                                 break;
192                         case VarEnum.VT_BSTR:
193                                 obj = Marshal.PtrToStringBSTR(bstrVal);
194                                 break;
195                         }
196                         return obj;
197                 }
198
199                 public void Clear() {
200                         if ((VarEnum)vt == VarEnum.VT_BSTR)
201                         {
202                                 Marshal.FreeBSTR(bstrVal);
203                         }
204                 }
205         }
206 }