-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInt16LeTypeConverter.cs
More file actions
128 lines (119 loc) · 6.41 KB
/
Int16LeTypeConverter.cs
File metadata and controls
128 lines (119 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Reflection;
namespace Stardust.Utilities
{
/// <summary>
/// Used to support PropertyGrid editing of <see cref="Int16Le"/>.
/// Accepts decimal (culture-aware, signed), hex "0x…", and binary "0b…" input with
/// optional '_' digit separators and surrounding whitespace. Emits values as
/// zero-padded "0x" + two's-complement hex for strings. Supports the designer via
/// <see cref="InstanceDescriptor"/>.
/// </summary>
public class Int16LeTypeConverter : TypeConverter
{
private static readonly StandardValuesCollection STANDARD_VALUES =
new(new Int16Le[] { new(short.MinValue), new((short)0), new(short.MaxValue) });
/// <summary>
/// Returns whether this converter can convert from the specified source type.
/// </summary>
/// <param name="context">Context information.</param>
/// <param name="sourceType">The source type.</param>
/// <returns><see langword="true"/> for <see cref="string"/> or <see cref="short"/>; otherwise delegates to the base.</returns>
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
if (sourceType == typeof(string)) return true;
if (sourceType == typeof(short)) return true;
return base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// Returns whether this converter can convert to the specified destination type.
/// </summary>
/// <param name="context">Context information.</param>
/// <param name="destinationType">The destination type.</param>
/// <returns><see langword="true"/> for <see cref="string"/>, <see cref="short"/>, or <see cref="InstanceDescriptor"/>; otherwise delegates to the base.</returns>
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
{
if (destinationType == typeof(string)) return true;
if (destinationType == typeof(short)) return true;
if (destinationType == typeof(InstanceDescriptor)) return true;
return base.CanConvertTo(context, destinationType);
}
/// <summary>
/// Converts the given value to an <see cref="Int16Le"/> instance.
/// </summary>
/// <param name="context">Context information.</param>
/// <param name="culture">Culture information (used for decimal parsing).</param>
/// <param name="value">The value to convert.</param>
/// <returns>The converted <see cref="Int16Le"/>.</returns>
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string s)
{
return ConverterParsing.Parse<Int16Le>(s, culture,
(d, p) => Int16Le.Parse(d, p),
h => Int16Le.Parse(h, NumberStyles.HexNumber));
}
if (value is short i) return new Int16Le(i);
return base.ConvertFrom(context, culture, value);
}
/// <summary>
/// Converts the given value to the specified destination type.
/// </summary>
/// <param name="context">Context information.</param>
/// <param name="culture">Culture information.</param>
/// <param name="value">The value to convert.</param>
/// <param name="destinationType">The destination type.</param>
/// <returns>The converted value; <see langword="null"/> if <paramref name="value"/> is null and the target is <see cref="string"/>.</returns>
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture,
object? value, Type destinationType)
{
if (destinationType == typeof(string))
{
if (value is null) return null;
if (value is Int16Le v) return $"0x{(ushort)(short)v:x4}";
}
if (destinationType == typeof(short) && value is Int16Le v2) return (short)v2;
if (destinationType == typeof(InstanceDescriptor) && value is Int16Le v3)
{
ConstructorInfo ctor = typeof(Int16Le).GetConstructor(new[] { typeof(short) })!;
return new InstanceDescriptor(ctor, new object[] { (short)v3 });
}
return base.ConvertTo(context, culture, value, destinationType);
}
/// <summary>
/// Validates that <paramref name="value"/> is acceptable as input for this converter
/// without throwing. Strings are probed via TryParse.
/// </summary>
/// <param name="context">Context information.</param>
/// <param name="value">The candidate value.</param>
/// <returns>True when the value is acceptable.</returns>
public override bool IsValid(ITypeDescriptorContext? context, object? value)
{
if (value is Int16Le) return true;
if (value is short) return true;
if (value is string s)
{
return ConverterParsing.TryParse<Int16Le>(s, null,
(d, p) => Int16Le.Parse(d, p),
h => Int16Le.Parse(h, NumberStyles.HexNumber),
out _);
}
return base.IsValid(context, value);
}
/// <summary>Indicates that this converter supplies a short list of standard values.</summary>
/// <param name="context">Context information.</param>
/// <returns>Always true.</returns>
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
/// <summary>Standard values are suggestions, not an exclusive set — the user may type any value.</summary>
/// <param name="context">Context information.</param>
/// <returns>Always false.</returns>
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => false;
/// <summary>Returns <see cref="short.MinValue"/>, 0, and <see cref="short.MaxValue"/> for PropertyGrid drop-down hints.</summary>
/// <param name="context">Context information.</param>
/// <returns>The standard-values collection.</returns>
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context) => STANDARD_VALUES;
}
}