forked from OptimShi/CustomClothingBase
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHexConverter.cs
120 lines (99 loc) · 3.9 KB
/
HexConverter.cs
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
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Text.Json.Serialization.Metadata;
namespace CustomClothingBase;
public class HexConverter<T> : JsonConverter<T> where T : INumber<T>
{
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
=> writer.WriteStringValue($"0x{value:X}");
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String &&
reader.GetString() is string hexString &&
hexString.TryParseHex<T>(out var result))
return result;
throw new JsonException("Invalid format for hex number");
}
}
/// <summary>
/// Generic Dictionary converted with numeric keys
/// </summary>
public class HexKeyDictionaryConverter<TKey, TValue> : JsonConverter<Dictionary<TKey, TValue>> where TKey : INumber<TKey>
{
public override Dictionary<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Expected StartObject token");
}
var dictionary = new Dictionary<TKey, TValue>();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return dictionary;
}
// Read the key as a string
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string keyHex = reader.GetString();
if (!keyHex.TryParseHex<TKey>(out var key))
{
throw new JsonException($"Invalid hex key: {keyHex}");
}
// Read the value
reader.Read();
TValue value = JsonSerializer.Deserialize<TValue>(ref reader, options);
dictionary.Add(key, value);
}
throw new JsonException("Unexpected end of JSON");
}
public override void Write(Utf8JsonWriter writer, Dictionary<TKey, TValue> value, JsonSerializerOptions options)
{
writer.WriteStartObject();
foreach (var kvp in value)
{
string keyHex = "0x" + kvp.Key.ToString("X", CultureInfo.InvariantCulture);
writer.WritePropertyName(keyHex);
JsonSerializer.Serialize(writer, kvp.Value, options);
}
writer.WriteEndObject();
}
}
public static class HexExtensions
{
public static bool TryParseHex<T>(this string hexString, out T result) where T : INumber<T>
=> hexString.StartsWith("0x") ?
T.TryParse(hexString.Substring(2), NumberStyles.HexNumber, null, out result) :
T.TryParse(hexString, NumberStyles.HexNumber, null, out result);
}
public class HexTypeResolver(HashSet<string> Keys) : DefaultJsonTypeInfoResolver
{
public HashSet<string> Keys { get; set; } = Keys;
HexConverter<uint> uintConverter = new();
HexConverter<int> intConverter = new();
public override JsonTypeInfo? GetTypeInfo(Type type, JsonSerializerOptions options)
{
var jsonTypeInfo = base.GetTypeInfo(type, options);
// Apply the converter only to the target types
if (jsonTypeInfo != null)
{
foreach (var property in jsonTypeInfo.Properties)
{
//Base it off names?
var name = property.Name;
if (!Keys.Contains(name))
continue;
var pType = property.PropertyType;
if (property.PropertyType == typeof(int))
property.CustomConverter = intConverter;
if (property.PropertyType == typeof(uint))
property.CustomConverter = uintConverter;
}
}
return jsonTypeInfo;
}
}