* Interaction.cs :
[mono.git] / mcs / class / Microsoft.VisualBasic / Microsoft.VisualBasic.CompilerServices / Utils.cs
1 //
2 // Utils.cs
3 //
4 // Author:
5 //   Chris J Breisch (cjbreisch@altavista.net) 
6 //   Rafael Teixeira (rafaelteixeirabr@hotmail.com)
7 //   Dennis Hayes (dennish@raytek.com)
8 //
9 // Copyright 2002 Chris J Breisch
10 // (C) 2004 Rafael Teixeira
11 //
12  /*
13   * Copyright (c) 2002-2003 Mainsoft Corporation.
14   * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15   *
16   * Permission is hereby granted, free of charge, to any person obtaining a
17   * copy of this software and associated documentation files (the "Software"),
18   * to deal in the Software without restriction, including without limitation
19   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20   * and/or sell copies of the Software, and to permit persons to whom the
21   * Software is furnished to do so, subject to the following conditions:
22   * 
23   * The above copyright notice and this permission notice shall be included in
24   * all copies or substantial portions of the Software.
25   * 
26   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32   * DEALINGS IN THE SOFTWARE.
33   */
34 /**
35  * The class Utils.
36  * 
37  * CURRENT LIMITATIONS
38  * 1. Method MethodToString(MethodBase Method) is not implemented
39  * 2. Method SetTime is not supported (throw exception)
40  * 3. Method SetDate is not supported (throw exception)
41  */
42
43 using System;
44 using System.Globalization;
45 using System.Text;
46 using System.Reflection;
47 using System.Resources;
48
49 namespace Microsoft.VisualBasic.CompilerServices {
50         [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
51         [Microsoft.VisualBasic.CompilerServices.StandardModule] 
52          public sealed class Utils {
53                 private Utils () {}
54
55                  internal const int SEVERITY_ERROR = Int32.MinValue;
56                  internal const int FACILITY_CONTROL = 655360;
57                  internal const int FACILITY_RPC = 65536;
58                  internal const int FACILITY_ITF = 262144;
59                  internal const int SCODE_FACILITY = 536805376;
60                  internal const char chPeriod = '.';
61                  internal const char chSpace = ' ';
62                  internal const char chIntlSpace = '\u3000';
63                  internal const char chZero = '0';
64                  internal const char chHyphen = '-';
65                  internal const char chPlus = '+';
66                  internal const char chNull = '\0';
67                  internal const char chLetterA = 'A';
68                  internal const char chLetterZ = 'Z';
69                  internal const char chColon = ':';
70                  internal const char chSlash = '/';
71                  internal const char chBackslash = '\\';
72                  internal const char chTab = '\t';
73                  internal const char chCharH0A = '\n';
74                  internal const char chCharH0B = '\t';
75                  internal const char chCharH0C = '\f';
76                  internal const char chCharH0D = '\r';
77                  internal const char chLineFeed = '\n';
78                  internal const char chDblQuote = '\"';
79                  //TODO: why is this static, should it be const?
80                  internal static char[] m_achIntlSpace = new char[] { ' ', '\u3000' };
81
82                  private const  String FILE_NAME = "Microsoft.VisualBasic.VBUtils";
83                  private static ResourceManager RESOURCE_BUNDLE = new ResourceManager(FILE_NAME, Assembly.GetExecutingAssembly()) ;
84
85                  //    public static ResourceManager get_VBAResourceManager() throws NotImplementedException
86                  //    {
87                  //        throw new NotImplementedException("The method get_VBAResourceManager in class VisualBasic.CompilerServices.Utils is not supported");
88                  //    }
89
90                  internal static string GetResourceString(string key) 
91                  {
92                          string str = null;
93                          try {
94                                  str = RESOURCE_BUNDLE.GetString(key);
95                          }
96                          catch (Exception e) {
97                                  str =  RESOURCE_BUNDLE.GetString("ID95");
98                          }
99
100                          return str;
101                  }
102
103                  internal static string GetResourceString(string key, bool notUsed) 
104                  {
105                          return GetResourceString(key);
106                  }
107
108                  internal static string GetResourceString (string key,string paramValue) 
109                  {
110                          StringBuilder sb = new StringBuilder(GetResourceString(key));
111                          sb.Replace("|1", paramValue);
112                          return sb.ToString();
113                  }
114
115                  internal static string GetResourceString (string key, string paramValue1, string paramValue2) 
116                  {
117                          StringBuilder sb = new StringBuilder(GetResourceString(key));
118                          sb.Replace("|1", paramValue1);
119                          sb.Replace("|2", paramValue2);
120                          return sb.ToString();
121                  }
122
123                  internal static string GetResourceString (string key, string param1, string param2, string param3) 
124                  {
125                          StringBuilder sb = new StringBuilder(GetResourceString(key));
126                          sb.Replace("|1", param1);
127                          sb.Replace("|2", param2);
128                          sb.Replace("|3", param3);
129                          return sb.ToString();
130                  }
131
132
133                  internal static string GetResourceString (string key, string param1, string param2, string param3,
134                                                          string param4) 
135                  {
136                          StringBuilder sb = new StringBuilder(GetResourceString(key));
137                          sb.Replace("|1", param1);
138                          sb.Replace("|2", param2);
139                          sb.Replace("|3", param3);
140                          sb.Replace("|4", param4);
141                          return sb.ToString();
142                  }
143
144                  internal static string GetResourceString (int ResourceId) 
145                  {
146                          string str = "ID" + ResourceId.ToString();
147                          return GetResourceString(str);
148                  }
149
150                  public static void ThrowException (int hr) 
151                  {
152                          throw ExceptionUtils.VbMakeException(hr);
153                  }
154
155                  internal static bool IsNumericType (Type tc) 
156                  {
157                          TypeCode typeCode = Type.GetTypeCode(tc);
158                          return IsNumericTypeCode((int)typeCode);
159                  }
160     
161                  internal static bool IsNumericTypeCode (int i) 
162                  {
163                          switch (i) {
164                          case (int)TypeCode.Boolean:
165                          case (int)TypeCode.Byte:
166                          case (int)TypeCode.Int16:
167                          case (int)TypeCode.Int32:
168                          case (int)TypeCode.Int64:
169                          case (int)TypeCode.Double:
170                          case (int)TypeCode.Single:
171                          case (int)TypeCode.Decimal:
172                                  return true;
173                          default:
174                                  return false;
175                          }
176                  }
177
178                 /**
179                  * This method change the given string which contains the suffix of array
180                  * representation so that the the signs '(', ')'  and  ',' will appear in the
181                  * end of the string. 
182                  * @param sRank the given suffix 
183                  * @return string the suffix after the change
184                  */
185                  private static string changeArraySuffix(string sRank) 
186                  {
187                          StringBuilder sb = new StringBuilder(sRank);
188                          char currentChar;
189
190                          for (int i = sRank.Length-1; i >= 0; i--) {
191                                  currentChar = sb[i];
192                                  if (currentChar == '(') { 
193                                          sb.Remove(i,1);
194                                          sb.Append(')');
195
196                                  }
197                                  else if (currentChar == ')') { 
198                                          sb.Remove(i,1);
199                                          sb.Append('(');
200
201                                  }
202                                  else if (currentChar == ',') { 
203                                          sb.Remove(i,1);
204                                          sb.Append(',');
205
206                                  }
207                          }
208                          return sb.ToString();
209                  }
210     
211                  internal static string VBFriendlyName (object obj) 
212                  {
213                          if (obj == null)
214                                  return "Nothing";
215                          Type type = obj.GetType();
216                          return VBFriendlyName(type,obj);
217                  }
218
219                  internal static string VBFriendlyName (Type type) 
220                  {
221                          return VBFriendlyNameOfTypeName(type.Name);
222                  }
223     
224                  internal static string VBFriendlyName (Type type, object obj) 
225                  {
226                         
227                          //if (StringStaticWrapper.CompareOrdinal(type.FullName, "System.__ComObject") //java code
228                          if (string.CompareOrdinal(type.FullName, "System.__ComObject") == 0) {
229                                  //this shape of if was writen  since get_IsCOMObject is not implemented
230                                  //yet. in this flow only when the type name is "System.__ComObject" the
231                                  //not implementedException is thrown.
232                         
233                                  //TODO:
234                                  //if (type.IsCOMObject)
235                                  //     Information.TypeNameOfCOMObject(obj, false);
236                          }
237                          return VBFriendlyNameOfTypeName(type.Name);
238                  }
239     
240                  /**
241                  * This method return a Vb representation of the given type name.
242                  * If this is an array it is changed to vb presentation with () instead of 
243                  * []. 
244                  * @param typename the given type name.
245                  * @return string the vb presentation of the type name
246                  */
247                  internal static string VBFriendlyNameOfTypeName (string typename) 
248                  {
249                          string tmpStr = null;
250                          int bracketIndex = 0;
251                          int length = typename.Length - 1;
252                          //if this is array type
253                          if (typename[length] == ']') {
254                                  bracketIndex = typename.IndexOf("[");
255                                  if (bracketIndex + 1 == length)
256                                          tmpStr = "()";
257                                  //when there is more than one dimention    
258                                  else
259                                          tmpStr =
260                                                  typename
261                                                  .Substring(bracketIndex, length - bracketIndex + 1)
262                                                  .Replace('[', '(')
263                                                  .Replace(']', ')');
264
265                                  typename = typename.Substring(0, bracketIndex);
266                          }
267         
268                          tmpStr = (tmpStr==null) ? "" :changeArraySuffix(tmpStr);
269
270                          //this method returns the C# equivalent name if this type name is vb unique
271                          //it returns null if the type name is like in C#
272                          string str = Information.VbTypeName(typename);     
273                          if (str == null)
274                                  str = typename;
275                          return str + tmpStr;
276                  }
277
278                 /**
279                  * This method change the presentation of a number.
280                  * if the decimal separator isn't '.' then it's changed to '.' and the updated
281                  * string return, otherwise if the string start in one of the four way : 
282                  * "0." , "-0." , "+0." or " 0." ,then the '0' character is removed.
283                  * if the input string doesn't contain the decimal separator the input value 
284                  * is returned.    
285                  * @param s the string that need to be changed
286                  * @return string the updated string. 
287                  */
288                 internal static string StdFormat(string s) {
289                         string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
290
291                         int index = s.IndexOf(separator);
292                         if (index == -1)
293                                 return s;
294
295
296                         //StringBuffer sb = new StringBuffer(s);
297                         StringBuilder sb = new StringBuilder(s);
298                         if (s[index] != '.') {
299                                 sb[index]= '.';
300                         }
301
302                         if (sb.Length > 1 && sb[0] == '0' && sb[1] == '.')
303                                 return sb.ToString().Substring(0,1);// sb.substring(1);//java version
304
305                         if (sb.Length > 2 && 
306                                 (sb[0] == '-' || sb[0] == '+'|| sb[0] == ' ') && 
307                                 sb[1] == '0' && sb[2] == '.') {
308                                 //sb = sb.deleteCharAt(1);//java version
309                                 sb = sb.Remove(0,1);
310                         }
311                         return sb.ToString();
312                 }
313
314                 /**
315                  * This method returns the octal string representation of the given long
316                  * @param Val the given long value
317                  * @return string the Octal string representation
318                  */
319                 internal static string OctFromLong(long Val) {
320                         return Convert.ToString(Val, 8);
321                 }
322
323                 internal static void SetTime(DateTime dtTime) {
324                         throw new NotImplementedException("Method SetTime in VisualBasic.CompilerServices.Utils is not supported");
325                 }
326
327                 internal static void SetDate(DateTime vDate) {
328                         throw new NotImplementedException("Method SetDate in VisualBasic.CompilerServices.Utils is not supported");
329                 }
330
331                 //TODO:
332                 internal static DateTimeFormatInfo GetDateTimeFormatInfo() {
333                         return CultureInfo.CurrentCulture.DateTimeFormat;
334                 }
335
336                 /**
337                  * This method maps exception id to message id in   
338                  * @param lNumber the exception constant
339                  * @return int the exception message id in the resource file
340                  */
341                 internal static int MapHRESULT(int lNumber) {
342                         return ExceptionUtils.fromDotNetToVB(lNumber);
343                 }
344
345                 internal static CultureInfo GetCultureInfo() {
346                         return CultureInfo.CurrentCulture;
347                 }
348
349                 public static object SetCultureInfo(CultureInfo culture) {
350                         CultureInfo currentCulture = CultureInfo.CurrentCulture;
351                         //CultureInfo.set_CurrentCulture(culture);//java code
352                         //TODO: CultureInfo.CurrentCulture is read only
353                         //CultureInfo.CurrentCulture = culture;
354                         return currentCulture;
355                 }
356
357                 internal static CultureInfo GetInvariantCultureInfo() {
358                         return CultureInfo.InvariantCulture;
359                 }
360
361                 internal static Encoding GetFileIOEncoding() {
362                         return Encoding.Default;
363                 }
364
365                 internal static int GetLocaleCodePage() {
366                         return CultureInfo.CurrentCulture.TextInfo.ANSICodePage;
367                 }
368 //mono implmentation
369 //              [MonoTODO]
370 //              public static System.Array CopyArray (System.Array SourceArray, System.Array DestinationArray)
371 //              { 
372 //#if NET_1_1
373 //                      long SourceLength = SourceArray.LongLength;
374 //                      long DestinationLength = DestinationArray.LongLength;
375 //                      long LengthToCopy = (SourceLength < DestinationLength) ? SourceLength : DestinationLength;
376 //                      Array.Copy(SourceArray, DestinationArray, LengthToCopy); 
377 //#else
378 //                      int SourceLength = SourceArray.Length;
379 //                      int DestinationLength = DestinationArray.Length;
380 //                      int LengthToCopy = (SourceLength < DestinationLength) ? SourceLength : DestinationLength;
381 //                      Array.Copy(SourceArray, DestinationArray, LengthToCopy); 
382 //#endif
383 //                      return DestinationArray;
384 //              }
385 //
386
387                 /**
388                  * This method copy the information from one array to another.
389                  */
390                 public static Array CopyArray(Array source, Array destination) {
391                         if (source == null || destination == null)
392                                 return destination;
393
394 #if NET_1_1
395                         long lengthToCopy = source.LongLength;
396                         if (lengthToCopy == 0)
397                                 return destination;
398
399                         int totalRanks = source.Rank;
400                         if (totalRanks != destination.Rank)
401                                 throw (InvalidCastException)ExceptionUtils.VbMakeException(new InvalidCastException(GetResourceString("Array_RankMismatch")), 9);
402
403                         int ranksThatMustBeEqual = (totalRanks - 1);
404                         for (int rank = 0; rank < ranksThatMustBeEqual; rank++) {
405                                 if (destination.GetUpperBound(rank) != source.GetUpperBound(rank)) 
406                                         throw (ArrayTypeMismatchException)ExceptionUtils.VbMakeException(new ArrayTypeMismatchException(GetResourceString("Array_TypeMismatch")), 9);
407                         }
408
409                         if (totalRanks == 1) {
410                                 if (lengthToCopy > destination.LongLength)
411                                         lengthToCopy = destination.LongLength;          
412                                 Array.Copy(source, destination, lengthToCopy);
413                         } else {
414                                 long sourceLengthInLastRank = source.GetLongLength(totalRanks - 1);
415                                 long destinationLengthInLastRank = destination.GetLongLength(totalRanks - 1);
416                                 if (destinationLengthInLastRank > 0) {
417                                         long lengthToCopyInLastRank = Math.Min(destinationLengthInLastRank, sourceLengthInLastRank);
418                                         long lowerRankBlocksToCopy = source.LongLength / sourceLengthInLastRank;
419                                         for (long block = 0; block < lowerRankBlocksToCopy; block++)
420                                                 Array.Copy(source, (block * sourceLengthInLastRank), destination, (block * destinationLengthInLastRank), lengthToCopyInLastRank);
421                                 }
422                         }
423 #else
424                         int lengthToCopy = source.Length;
425                         if (lengthToCopy == 0)
426                                 return destination;
427
428                         int totalRanks = source.Rank;
429                         if (totalRanks != destination.Rank)
430                                 throw (InvalidCastException)ExceptionUtils.VbMakeException(new InvalidCastException(GetResourceString("Array_RankMismatch")), 9);
431
432                         int ranksThatMustBeEqual = (totalRanks - 1);
433                         for (int rank = 0; rank < ranksThatMustBeEqual; rank++) {
434                                 if (destination.GetUpperBound(rank) != source.GetUpperBound(rank)) 
435                                         throw (ArrayTypeMismatchException)ExceptionUtils.VbMakeException(new ArrayTypeMismatchException(GetResourceString("Array_TypeMismatch")), 9);
436                         }
437
438                         if (totalRanks == 1) {
439                                 if (lengthToCopy > destination.Length)
440                                         lengthToCopy = destination.Length;              
441                                 Array.Copy(source, destination, lengthToCopy);
442                         } else {
443                                 int sourceLengthInLastRank = source.GetLength(totalRanks - 1);
444                                 int destinationLengthInLastRank = destination.GetLength(totalRanks - 1);
445                                 if (destinationLengthInLastRank > 0) {
446                                         int lengthToCopyInLastRank = Math.Min(destinationLengthInLastRank, sourceLengthInLastRank);
447                                         int lowerRankBlocksToCopy = source.Length / sourceLengthInLastRank;
448                                         for (int block = 0; block < lowerRankBlocksToCopy; block++)
449                                                 Array.Copy(source, (block * sourceLengthInLastRank), destination, (block * destinationLengthInLastRank), lengthToCopyInLastRank);
450                                 }
451                         }
452 #endif 
453                         return destination;
454                 }
455
456                 [MonoTODO]
457                 public static string MethodToString(MethodBase Method) {
458                         throw new NotImplementedException("The method MethodToString in class VisualBasic.CompilerServices.Utils is not supported");
459                 }
460
461                 [MonoTODO]
462                 internal static string FieldToString(FieldInfo fieldinfo) {
463                         throw new NotImplementedException("The method FieldToString in class VisualBasic.CompilerServices.Utils is not supported");
464                 }
465
466                 internal static string MemberToString(MemberInfo memberinfo) {
467                         switch (memberinfo.MemberType) {
468                                 case MemberTypes.Method :
469                                         return MethodToString((MethodInfo)memberinfo);
470
471                                 case MemberTypes.Field :
472                                         return FieldToString((FieldInfo)memberinfo);
473                         }
474                         return memberinfo.Name;
475                 }
476
477         }
478 }