1 
2 //------------------------------------------------------------------------------
3 // <copyright file="basenumberconverter.cs" company="Microsoft">
4 //     Copyright (c) Microsoft Corporation.  All rights reserved.
5 // </copyright>
6 //------------------------------------------------------------------------------
7 
8 /*
9  */
10 namespace System.ComponentModel {
11     using Microsoft.Win32;
12     using System.Diagnostics;
13     using System.Globalization;
14     using System.Runtime.InteropServices;
15     using System.Runtime.Remoting;
16     using System.Runtime.Serialization.Formatters;
17     using System.Security.Permissions;
18 
19     /// <devdoc>
20     ///    <para>Provides a base type converter for integral types.</para>
21     /// </devdoc>
22     [HostProtection(SharedState = true)]
23     public abstract class BaseNumberConverter : TypeConverter {
24 
25 
26         /// <devdoc>
27         /// Determines whether this editor will attempt to convert hex (0x or #) strings
28         /// </devdoc>
29         internal virtual bool AllowHex {
30                 get {
31                      return true;
32                 }
33         }
34 
35 
36         /// <devdoc>
37         /// The Type this converter is targeting (e.g. Int16, UInt32, etc.)
38         /// </devdoc>
39         internal abstract Type TargetType {
40                 get;
41         }
42 
43         /// <devdoc>
44         /// Convert the given value to a string using the given radix
45         /// </devdoc>
FromString(string value, int radix)46         internal abstract object FromString(string value, int radix);
47 
48         /// <devdoc>
49         /// Convert the given value to a string using the given formatInfo
50         /// </devdoc>
FromString(string value, NumberFormatInfo formatInfo)51         internal abstract object FromString(string value, NumberFormatInfo formatInfo);
52 
53         /// <devdoc>
54         /// Convert the given value to a string using the given CultureInfo
55         /// </devdoc>
FromString(string value, CultureInfo culture)56         internal abstract object FromString(string value, CultureInfo culture);
57 
58         /// <devdoc>
59         /// Create an error based on the failed text and the exception thrown.
60         /// </devdoc>
FromStringError(string failedText, Exception innerException)61         internal virtual Exception FromStringError(string failedText, Exception innerException) {
62                 return new Exception(SR.GetString(SR.ConvertInvalidPrimitive, failedText, TargetType.Name), innerException);
63         }
64 
65         /// <devdoc>
66         /// Convert the given value from a string using the given formatInfo
67         /// </devdoc>
ToString(object value, NumberFormatInfo formatInfo)68         internal abstract string ToString(object value, NumberFormatInfo formatInfo);
69 
70         /// <devdoc>
71         ///    <para>Gets a value indicating whether this converter can convert an object in the
72         ///       given source type to a 64-bit signed integer object using the specified context.</para>
73         /// </devdoc>
CanConvertFrom(ITypeDescriptorContext context, Type sourceType)74         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
75             if (sourceType == typeof(string)) {
76                 return true;
77             }
78             return base.CanConvertFrom(context, sourceType);
79         }
80 
81         /// <devdoc>
82         ///    <para>Converts the given value object to a 64-bit signed integer object.</para>
83         /// </devdoc>
ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)84         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
85             if (value is string) {
86                 string text = ((string)value).Trim();
87 
88                 try {
89                     if (AllowHex && text[0] == '#') {
90                         return FromString(text.Substring(1), 16);
91                     }
92                     else if (AllowHex && text.StartsWith("0x")
93                              || text.StartsWith("0X")
94                              || text.StartsWith("&h")
95                              || text.StartsWith("&H")) {
96                         return FromString(text.Substring(2), 16);
97                     }
98                     else {
99                         if (culture == null) {
100                             culture = CultureInfo.CurrentCulture;
101                         }
102                         NumberFormatInfo formatInfo = (NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo));
103                         return FromString(text, formatInfo);
104                     }
105                 }
106                 catch (Exception e) {
107                     throw FromStringError(text, e);
108                 }
109             }
110             return base.ConvertFrom(context, culture, value);
111         }
112 
113         /// <devdoc>
114         ///    <para>Converts the given value object to a 64-bit signed integer object using the
115         ///       arguments.</para>
116         /// </devdoc>
ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)117         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
118             if (destinationType == null) {
119                 throw new ArgumentNullException("destinationType");
120             }
121 
122             if (destinationType == typeof(string) && value != null && TargetType.IsInstanceOfType(value)) {
123 
124                 if (culture == null) {
125                     culture = CultureInfo.CurrentCulture;
126                 }
127                 NumberFormatInfo formatInfo = (NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo));
128                 return ToString(value, formatInfo);
129             }
130 
131             if (destinationType.IsPrimitive) {
132                 return Convert.ChangeType(value, destinationType, culture);
133             }
134             return base.ConvertTo(context, culture, value, destinationType);
135         }
136 
CanConvertTo(ITypeDescriptorContext context, Type t)137         public override bool CanConvertTo(ITypeDescriptorContext context, Type t) {
138             if (base.CanConvertTo(context, t) || t.IsPrimitive) {
139                 return true;
140             }
141             return false;
142         }
143     }
144 }
145 
146