fc9da06b539cd2e01350a7f1530689e8e348b569
[mono.git] / mcs / class / Microsoft.JScript / Microsoft.JScript / Convert.cs
1 //
2 // Convert.cs:
3 //
4 // Author:
5 //      Cesar Lopez Nataren (cesar@ciencias.unam.mx)
6 //
7 // (C) 2003, Cesar Lopez Nataren
8 // (C) 2005, Novell Inc, (http://novell.com)
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System;
33 using System.Diagnostics;
34 using Microsoft.JScript.Vsa;
35 using System.Globalization;
36
37 namespace Microsoft.JScript {
38
39         public sealed class Convert {
40
41                 public static bool IsBadIndex (AST ast)
42                 {
43                         throw new NotImplementedException ();
44                 }
45
46                 internal static bool IsNumberTypeCode (TypeCode tc)
47                 {
48                         switch (tc) {
49                         case TypeCode.Byte:
50                         case TypeCode.Char:
51                         case TypeCode.Decimal:
52                         case TypeCode.Double:
53                         case TypeCode.Int16:
54                         case TypeCode.Int32:
55                         case TypeCode.Int64:
56                         case TypeCode.SByte:
57                         case TypeCode.Single:
58                         case TypeCode.UInt16:
59                         case TypeCode.UInt32:
60                         case TypeCode.UInt64:
61                                 return true;
62                         default:
63                                 return false;
64                         }
65                 }
66
67                 internal static bool IsFloatTypeCode (TypeCode tc)
68                 {
69                         switch (tc) {
70                         case TypeCode.Decimal:
71                         case TypeCode.Double:
72                         case TypeCode.Single:
73                                 return true;
74                         default:
75                                 return false;
76                         }
77                 }
78
79                 public static double CheckIfDoubleIsInteger (double d)
80                 {
81                         if (d == Math.Round (d))
82                                 return d;
83                         throw new NotImplementedException ();
84                 }
85
86
87                 public static Single CheckIfSingleIsInteger (Single s)
88                 {
89                         if (s == Math.Round (s))
90                                 return s;
91                         throw new NotImplementedException ();
92                 }
93
94
95                 public static object Coerce (object value, object type)
96                 {
97                         throw new NotImplementedException ();
98                 }
99
100
101                 public static object CoerceT (object value, Type t, bool explicitOK)
102                 {
103                         throw new NotImplementedException ();
104                 }
105
106
107                 public static object Coerce2 (object value, TypeCode target,
108                                                   bool truncationPermitted)
109                 {
110                         throw new NotImplementedException ();
111                 }
112
113                 [DebuggerStepThroughAttribute]
114                 [DebuggerHiddenAttribute]
115                 public static void ThrowTypeMismatch (object val)
116                 {
117                         throw new NotImplementedException ();
118                 }
119
120                 internal static object ToPrimitive (object value, Type hint)
121                 {
122                         IConvertible ic = value as IConvertible;
123                         TypeCode tc = Convert.GetTypeCode (value, ic);
124                         switch (tc) {
125                         case TypeCode.Object:
126                                 if (value is JSObject)
127                                         return ((JSObject) value).GetDefaultValue (hint);
128                                 else
129                                         throw new NotImplementedException ();
130                         default:
131                                 return value;
132                         }
133                 }
134
135                 public static bool ToBoolean (double d)
136                 {
137                         return Convert.ToBoolean (d, true);
138                 }
139
140                 [DebuggerStepThroughAttribute]
141                 [DebuggerHiddenAttribute]
142                 public static bool ToBoolean (object value)
143                 {
144                         return Convert.ToBoolean (value, true);
145                 }
146
147                 [DebuggerStepThroughAttribute]
148                 [DebuggerHiddenAttribute]
149                 public static bool ToBoolean (object value, bool explicitConversion)
150                 {
151                         IConvertible ic = value as IConvertible;
152                         TypeCode tc = Convert.GetTypeCode (value, ic);
153
154                         switch (tc) {
155                         case TypeCode.Empty:
156                         case TypeCode.DBNull:
157                                 return false;
158
159                         case TypeCode.Boolean:
160                                 return ic.ToBoolean (null);
161
162                         case TypeCode.Char:
163                         case TypeCode.Byte:
164                         case TypeCode.SByte:
165                         case TypeCode.UInt16:
166                         case TypeCode.UInt32:
167                         case TypeCode.Int16:
168                         case TypeCode.Int32:
169                         case TypeCode.Single:
170                         case TypeCode.Double:
171                                 double num = ic.ToDouble (null);
172                                 return !double.IsNaN (num) && (num != 0.0);
173
174                         case TypeCode.String:
175                                 string str = ic.ToString (null);
176                                 return str.Length != 0;
177
178                         case TypeCode.Object:
179                                 return true;
180
181                         default:
182                                 Console.WriteLine ("\nToBoolean: tc = {0}", tc);
183                                 break;
184                         }
185                         throw new NotImplementedException ();
186                 }
187
188                 public static object ToForInObject (object value, VsaEngine engine)
189                 {
190                         throw new NotImplementedException ();
191                 }
192
193
194                 public static int ToInt32 (object value)
195                 {
196                         IConvertible ic = value as IConvertible;
197                         TypeCode tc = Convert.GetTypeCode (value, ic);
198
199                         switch (tc) {
200                         case TypeCode.Empty:
201                         case TypeCode.DBNull:
202                                 return 0;
203
204                         case TypeCode.Char:
205                         case TypeCode.Byte:
206                         case TypeCode.SByte:
207                         case TypeCode.UInt16:
208                         case TypeCode.UInt32:
209                         case TypeCode.Int16:
210                         case TypeCode.Int32:
211                                 return (int) value;
212
213                         case TypeCode.Single:
214                         case TypeCode.Double:
215                                 return (int) Math.Floor ((double) value);
216
217                         case TypeCode.String:
218                                 return (int) Math.Floor (GlobalObject.parseFloat (ic.ToString ()));
219
220                         default:
221                                 Console.WriteLine ("\nToInt32: value.GetType = {0}", value.GetType ());
222                                 break;
223                         }
224                         throw new NotImplementedException ();
225                 }
226
227                 internal static int ToUint16 (object value)
228                 {
229                         double val = Convert.ToNumber (value);
230                         if (Double.IsInfinity (val) || double.IsNaN (val))
231                                 return 0;
232                         else
233                                 return (int) val % 65536;
234                 }
235
236                 public static double ToNumber (object value)
237                 {
238                         IConvertible ic = value as IConvertible;
239                         TypeCode tc = Convert.GetTypeCode (value, ic);
240
241                         switch (tc) {
242                         case TypeCode.Empty:
243                                 return Double.NaN;
244
245                         case TypeCode.DBNull:
246                                 return 0;
247
248                         case TypeCode.Boolean:
249                                 if (ic.ToBoolean (null))
250                                         return 1;
251                                 return 0;
252
253                         case TypeCode.Char:
254                         case TypeCode.Byte:
255                         case TypeCode.SByte:
256                         case TypeCode.UInt16:
257                         case TypeCode.UInt32:
258                         case TypeCode.Int16:
259                         case TypeCode.Int32:
260                                 return (double) value;
261
262                         case TypeCode.Single:
263                         case TypeCode.Double:
264                                 return (double) value;
265
266                         case TypeCode.String:
267                                 return GlobalObject.parseFloat (value);
268
269                         default:
270                                 Console.WriteLine ("\nToNumber: value.GetType = {0}", value.GetType ());
271                                 break;
272                         }
273
274                         throw new NotImplementedException ();
275                 }
276
277
278                 public static double ToNumber (string str)
279                 {
280                         return GlobalObject.parseFloat (str);
281                 }
282
283
284                 public static object ToNativeArray (object value, RuntimeTypeHandle handle)
285                 {
286                         throw new NotImplementedException ();
287                 }
288
289
290                 public static object ToObject (object value, VsaEngine engine)
291                 {
292                         IConvertible ic = value as IConvertible;
293                         TypeCode tc = Convert.GetTypeCode (value, ic);
294
295                         switch (tc) {
296                         case TypeCode.String:
297                                 return new StringObject (ic.ToString (null));
298                         case TypeCode.Single:
299                         case TypeCode.Double:
300                         case TypeCode.Char:
301                         case TypeCode.Byte:
302                         case TypeCode.SByte:
303                         case TypeCode.UInt16:
304                         case TypeCode.UInt32:
305                         case TypeCode.Int16:
306                         case TypeCode.Int32:
307                                 return new NumberObject (ic.ToDouble (null));
308                         case TypeCode.Object:
309                                 return value;
310                         default:
311                                 Console.WriteLine ("\nToObject: value.GetType = {0}", value.GetType ());
312                                 break;
313                         }
314                         throw new NotImplementedException ();
315                 }
316
317
318                 public static object ToObject2 (object value, VsaEngine engine)
319                 {
320                         throw new NotImplementedException ();
321                 }
322
323
324                 internal static string ToString (object obj)
325                 {
326                         return Convert.ToString (obj, true);
327                 }
328
329                 [DebuggerStepThroughAttribute]
330                 [DebuggerHiddenAttribute]
331                 public static string ToString (object value, bool explicitOK)
332                 {
333                         IConvertible ic = value as IConvertible;
334                         TypeCode tc = Convert.GetTypeCode (value, ic);
335
336                         switch (tc) {
337                         case TypeCode.Empty:
338                                 return "";
339
340                         case TypeCode.DBNull:
341                                 return "null";
342
343                         case TypeCode.Boolean:
344                                 bool r = (bool) value;
345                                 if (r)
346                                         return "true";
347                                 else
348                                         return "false";
349
350                         case TypeCode.Char:
351                                 return ic.ToInt16 (null).ToString ();
352
353                         case TypeCode.Byte:
354                         case TypeCode.SByte:
355                         case TypeCode.UInt16:
356                         case TypeCode.UInt32:
357                         case TypeCode.Int16:
358                         case TypeCode.Int32:
359                         case TypeCode.String:
360                         case TypeCode.Double:
361                                 return ic.ToString (CultureInfo.InvariantCulture);
362
363                         case TypeCode.Object:
364                                 if (value is ArrayObject)
365                                         return ArrayPrototype.toString (value);
366                                 else if (value is BooleanObject)
367                                         return BooleanPrototype.toString (value);
368                                 else if (value is DateObject)
369                                         return DatePrototype.toString (value);
370                                 else if (value is ErrorObject)
371                                         return ErrorPrototype.toString (value);
372                                 else if (value is FunctionObject)
373                                         return FunctionPrototype.toString (value);
374                                 else if (value is NumberObject)
375                                         return NumberPrototype.toString (value, 10);
376                                 else if (value is ObjectPrototype)
377                                         return ObjectPrototype.toString (value);
378                                 else if (value is RegExpObject)
379                                         return RegExpPrototype.toString (value);
380                                 else if (value is StringObject)
381                                         return StringPrototype.toString (value);
382                                 else if (value is FunctionWrapper)
383                                         return FunctionPrototype.toString (value);
384                                 Console.WriteLine ("value.GetType = {0}", value.GetType ());
385                                 throw new NotImplementedException ();
386                         default:
387                                 Console.WriteLine ("tc = {0}", tc);
388                                 throw new NotImplementedException ();
389                         }
390                 }
391
392
393                 public static string ToString (bool b)
394                 {
395                         return b ? "true" : "false";
396                 }
397
398
399                 public static string ToString (double d)
400                 {
401                         IConvertible ic = d as IConvertible;
402                         return ic.ToString (null);
403                 }
404
405                 //
406                 // Utility methods
407                 //
408                 internal static TypeCode GetTypeCode (object obj, IConvertible ic)
409                 {
410                         if (obj == null)
411                                 return TypeCode.Empty;
412                         else if (ic == null)
413                                 return TypeCode.Object;
414                         else
415                                 return ic.GetTypeCode ();
416                 }
417         }
418 }