[dlr] Add interpreter increment emit
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Utils / ExceptionUtils.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
6  * copy of the license can be found in the License.html file at the root of this distribution. If 
7  * you cannot locate the  Apache License, Version 2.0, please send an email to 
8  * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Apache License, Version 2.0.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 using System;
17 using System.Linq;
18 using System.Runtime.CompilerServices;
19 using System.Collections.Generic;
20 using System.Threading;
21
22 namespace Microsoft.Scripting.Utils {
23     public static class ExceptionUtils {
24         public static ArgumentOutOfRangeException MakeArgumentOutOfRangeException(string paramName, object actualValue, string message) {
25 #if SILVERLIGHT || WP75 // ArgumentOutOfRangeException ctor overload
26             throw new ArgumentOutOfRangeException(paramName, string.Format("{0} (actual value is '{1}')", message, actualValue));
27 #else
28             throw new ArgumentOutOfRangeException(paramName, actualValue, message);
29 #endif
30         }
31
32         public static ArgumentNullException MakeArgumentItemNullException(int index, string arrayName) {
33             return new ArgumentNullException(String.Format("{0}[{1}]", arrayName, index));
34         }
35
36 #if FEATURE_REMOTING
37         public static object GetData(this Exception e, object key) {
38             return e.Data[key];
39         }
40
41         public static void SetData(this Exception e, object key, object data) {
42             e.Data[key] = data;
43         }
44
45         public static void RemoveData(this Exception e, object key) {
46             e.Data.Remove(key);
47         }
48 #else
49
50 #if WP75
51         private static WeakDictionary<Exception, List<KeyValuePair<object, object>>> _exceptionData;
52 #else
53         private static ConditionalWeakTable<Exception, List<KeyValuePair<object, object>>> _exceptionData;
54 #endif
55
56         public static void SetData(this Exception e, object key, object value) {
57             if (_exceptionData == null) {
58 #if WP75
59                 Interlocked.CompareExchange(ref _exceptionData, new WeakDictionary<Exception, List<KeyValuePair<object, object>>>(), null);
60 #else
61                 Interlocked.CompareExchange(ref _exceptionData, new ConditionalWeakTable<Exception, List<KeyValuePair<object, object>>>(), null);
62 #endif
63             }
64
65             lock (_exceptionData) {
66                 var data = _exceptionData.GetOrCreateValue(e);
67             
68                 int index = data.FindIndex(entry => entry.Key == key);
69                 if (index >= 0) {
70                     data[index] = new KeyValuePair<object, object>(key, value);
71                 } else {
72                     data.Add(new KeyValuePair<object, object>(key, value));
73                 }
74             }
75         }
76
77         public static object GetData(this Exception e, object key) {
78             if (_exceptionData == null) {
79                 return null;
80             }
81
82             lock (_exceptionData) {
83                 List<KeyValuePair<object, object>> data;
84                 if (!_exceptionData.TryGetValue(e, out data)) {
85                     return null;
86                 }
87
88                 return data.FirstOrDefault(entry => entry.Key == key).Value;
89             }
90         }
91
92         public static void RemoveData(this Exception e, object key) {
93             if (_exceptionData == null) {
94                 return;
95             }
96
97             lock (_exceptionData) {
98                 List<KeyValuePair<object, object>> data;
99                 if (!_exceptionData.TryGetValue(e, out data)) {
100                     return;
101                 }
102
103                 int index = data.FindIndex(entry => entry.Key == key);
104                 if (index >= 0) {
105                     data.RemoveAt(index);
106                 }
107             }
108         }
109 #endif
110     }
111 }