2005-06-06 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / Microsoft.VisualBasic / Microsoft.VisualBasic / ErrObject.cs
1 //
2 // ErrObject.cs
3 //
4 // Author:
5 //   Chris J Breisch (cjbreisch@altavista.net) 
6 //   Francesco Delfino (pluto@tipic.com)
7 //
8 // (C) 2002 Chris J Breisch
9 //     2002 pluto@tipic.com
10 //
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
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.Runtime.InteropServices;
38 using Microsoft.VisualBasic.CompilerServices;
39 using System.Diagnostics;
40
41 namespace Microsoft.VisualBasic 
42 {
43         sealed public class ErrObject {
44
45                 private System.Exception pException;
46                 private int pErl;
47                 private int pNumber;
48                 private string pSource;
49                 private string pDescription;
50                 private string pHelpFile;
51                 private int pHelpContext;
52
53                 private int pLastDllError;
54
55                 private bool m_bDontMapException = false;
56                 private bool NumberIsSet = false;
57                 private bool ClearOnCapture = false;
58                 private bool SourceIsSet = false;
59                 private bool DescriptionIsSet = false;
60                 private bool HelpFileIsSet = false;
61                 private bool HelpContextIsSet = false;
62
63                 internal ErrObject()
64                 {
65                         Clear();
66                 }
67
68                 public void Clear () 
69                 {
70                         pException = null;
71                         pErl = 0;
72                         pNumber = 0;
73                         pSource = "";
74                         pDescription = "";
75                         pHelpFile = "";
76                         pHelpContext = 0;
77
78                         m_bDontMapException = false;
79                         NumberIsSet = false;
80                         ClearOnCapture = false;
81                         SourceIsSet = false;
82                         DescriptionIsSet = false;
83                         HelpFileIsSet = false;
84                         HelpContextIsSet = false;
85                         ClearOnCapture = true;
86                 }
87
88                 internal void CaptureException (Exception ex)
89                 {
90                         if(ex == pException)
91                                 return;
92                         if(ClearOnCapture == true)
93                                 Clear();
94                         else
95                                 ClearOnCapture = true;
96
97                         pException = ex;
98                 }
99
100                 internal void CaptureException (Exception ex, int lErl)
101                 {
102                         CaptureException(ex);
103                         pErl = lErl;
104                 }
105
106                 internal Exception CreateException (int Number, String Description)
107                 {
108                         Exception ex;
109
110                         Clear();
111                         this.Number = Number;
112                         if(Number == 0)
113                                 throw new ArgumentException(Utils.GetResourceString("Argument_InvalidValue1", "Number"));
114                         ex = MapNumberToException(pNumber, Description);
115                         this.ClearOnCapture = false;
116                         return ex;
117                 }
118
119                 private String FilterDefaultMessage(String Msg)
120                 {
121                         if(pException == null)
122                                 return Msg;
123
124                         string Msg1 = Utils.GetResourceString(this.Number);
125
126                         if(Msg == null || Msg.Length == 0)
127                                 return Msg1;
128                         else if(String.CompareOrdinal("Exception from HRESULT: 0x", 0, Msg, 0, System.Math.Min(Msg.Length, 26)) == 0) {
129                                 return (Msg1 != null ? Msg1 : Msg);
130                         }
131                         else
132                                 return Msg;
133                 }
134
135                 private Exception MapNumberToException (int Number, String Description)
136                 {
137                         bool Ignored = false;
138                         return ExceptionUtils.BuildException(Number, Description, ref Ignored);
139                 }
140
141
142                 // This function needs to be reviewed
143                 private int MapExceptionToNumber (Exception ex)
144                 {
145                         int hResult = 0;
146
147                         if(ex is ArgumentException) {
148                                 hResult = unchecked((int)0x80070057);
149                         }
150                         else if(ex is ArithmeticException) {
151                                 if(ex is NotFiniteNumberException) { 
152                                         if((ex as NotFiniteNumberException).OffendingNumber == 0)
153                                                 return 11;
154                                         else
155                                                 return 6;
156                                 }
157                                 else {
158                                         hResult = unchecked((int)0x80070216);     
159                                 }
160                         }
161                         else if(ex is ArrayTypeMismatchException) {
162                                 hResult = unchecked((int)0x80131503);
163                         }
164                         // else if(exType.Equals(IndexOutOfRangeException)) {
165                         //      hResult = (exType.Equals(IndexOutOfRangeException)).HResult;     
166                         // }
167                         else if(ex is InvalidCastException) {
168                                 hResult = unchecked((int)0x80004002);
169                         }
170                         else if(ex is NotSupportedException) {
171                                 hResult = unchecked((int)0x80131515);
172                         }
173                         else if(ex is NullReferenceException) {
174                                 hResult = unchecked((int)0x80004003);
175                         }
176                         else if(ex is UnauthorizedAccessException) {
177                                 hResult = unchecked((int)0x80131500);
178                         }
179
180                         else {
181                                 hResult = unchecked((int)0x80004005);
182                         }
183
184                         hResult = ExceptionUtils.getVBFromDotNet(hResult);
185                         if(hResult != 0 )
186                                 return hResult;
187                         else
188                                 return 5;
189                 }
190
191                 private void ParseHelpLink (String HelpLink)
192                 {
193                         int ind;
194
195                         if(HelpLink == null || HelpLink.Length == 0) {
196                                 if(HelpContextIsSet == false)
197                                         this.HelpContext = 0;
198
199                                 if (HelpFileIsSet == false)
200                                         this.HelpFile = "";
201                         }
202                         else {
203                                 ind = HelpLink.IndexOf("#");
204
205                                 if(ind != -1) {
206                                         if(HelpContextIsSet == false) {
207                                                 if(ind < HelpLink.Length)
208                                                         this.HelpContext = IntegerType.FromString(HelpLink.Substring(ind + 1));
209                                                 else
210                                                         this.HelpContext = 0;
211                                         }
212                                         if (HelpFileIsSet == false)
213                                                 this.HelpFile = HelpLink.Substring(0, ind);
214                                 }
215                                 else {
216                                         if (HelpContextIsSet == false)
217                                                 this.HelpContext = 0;
218
219                                         if (!this.HelpFileIsSet)
220                                                 this.HelpFile = HelpLink;
221                                 }
222                         }
223                 }
224
225                 internal int MapErrorNumber (int Number)
226                 {
227                         if(Number > 65535)
228                                 throw new ArgumentException(VBUtils.GetResourceString("Argument_InvalidValue1", "Number"));
229
230
231                         if(Number >= 0)
232                                 return Number;
233                         else
234                                 return ExceptionUtils.fromDotNetToVB(Number);
235                 }
236
237                 private String MakeHelpLink(String HelpFile, int HelpContext)
238                 {
239                         return HelpFile + "#" + StringType.FromInteger(HelpContext);
240                 }
241
242                 [MonoTODO]
243                 public void Raise (System.Int32 Number, 
244                                    [Optional, __DefaultArgumentValue(null)] System.Object Source, 
245                                    [Optional, __DefaultArgumentValue(null)] System.Object Description, 
246                                    [Optional, __DefaultArgumentValue(null)] System.Object HelpFile, 
247                                    [Optional, __DefaultArgumentValue(null)] System.Object HelpContext) 
248                 { 
249                         Exception e;
250                         
251                         if(Number == 0)
252                                 throw new ArgumentException(Utils.GetResourceString("Argument_InvalidValue1", "Number"));
253
254                         this.Number = Number;
255
256                         if(Source != null)
257                                 this.Source = StringType.FromObject(Source);
258                         else
259                                 this.Source = Process.GetCurrentProcess().ProcessName;
260
261                         if(HelpFile != null)
262                                 this.HelpFile = StringType.FromObject(HelpFile);
263
264                         if(HelpContext != null)
265                                 this.HelpContext = IntegerType.FromObject(HelpContext);
266
267                         if(Description != null)
268                                 this.Description = StringType.FromObject(Description);
269                         else if (DescriptionIsSet == false) {
270                                 string desc;
271                                 desc = Utils.GetResourceString(pNumber);
272
273                                 if(desc == null)
274                                         desc = Utils.GetResourceString("ID95");
275
276                                 this.Description = desc;
277                         }
278
279                         e = MapNumberToException(pNumber, pDescription);
280
281
282                         e.Source = pSource;
283                         e.HelpLink = MakeHelpLink(pHelpFile, pHelpContext);
284
285
286                         ClearOnCapture = false;
287                         throw e;
288                 } 
289
290                 internal void SetUnmappedError (int Number)
291                 {
292                         Clear();
293                         this.Number = Number;
294                         ClearOnCapture = false;
295                 }
296
297                 public System.Exception GetException () 
298                 {
299                         return pException;
300                 }
301
302                 public System.String Description {  
303                         get { 
304                                 if(DescriptionIsSet)
305                                         return pDescription;
306
307                                 if(pException == null)
308                                         return "";
309
310                                 this.Description = FilterDefaultMessage(pException.Message);
311                                 return pDescription; 
312                         } 
313                         set { 
314                                 pDescription = value;
315                                 DescriptionIsSet = true;
316                         } 
317                 }
318
319                 public System.Int32 Erl {  
320                         get { 
321                                 return pErl;
322                         } 
323                 }
324
325                 public System.Int32 HelpContext 
326                 { 
327                         get { 
328                                 if(HelpContextIsSet)
329                                         return pHelpContext; 
330
331                                 if(pException != null) {
332                                         ParseHelpLink(pException.HelpLink);
333                                         return this.pHelpContext;
334                                 }
335                                 return 0;
336                         }
337
338                         set { 
339                                 pHelpContext = value;
340                                 HelpContextIsSet = true;
341                         } 
342                 }
343
344                 public System.String HelpFile {  
345                         get { 
346                                 if (HelpFileIsSet == true)
347                                         return pHelpFile;
348         
349                                 if(pException != null) {
350                                         ParseHelpLink((pException as Exception).HelpLink);
351                                         return pHelpFile;
352                                 }
353                                 return "";
354                         } 
355                         set { 
356                                 pHelpFile = value;
357                                 HelpFileIsSet = true;
358                         } 
359                 }
360
361                 [MonoTODO]
362                 public System.Int32 LastDllError {  
363                         get { 
364                                 return 0; 
365                         } 
366                 }
367
368                 public System.Int32 Number {  
369                         get { 
370                                 if(NumberIsSet)
371                                         return pNumber;
372
373                                 if(pException == null)
374                                         return 0;
375
376                                 this.Number = MapExceptionToNumber(pException);
377                                 return pNumber;
378                         } 
379                         set { 
380                                 pNumber = MapErrorNumber(value);
381                                 NumberIsSet = true;
382                         } 
383                 }
384
385                 [MonoTODO]
386                 public System.String Source {  
387                         get { 
388                                 if(SourceIsSet)
389                                         return pSource;
390
391                                 if(pException == null)
392                                         return "";
393
394                                 this.Source = pException.Source;
395                                 return pSource;
396                         } 
397                         set { 
398                                 pSource = value;
399                                 SourceIsSet = true;
400                         } 
401                 }
402
403
404         }
405 }
406