Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
EnumConverter.cs
Go to the documentation of this file.
5
7
8internal sealed class EnumConverter<T> : JsonConverter<T> where T : struct, Enum
9{
10 private static readonly TypeCode s_enumTypeCode = Type.GetTypeCode(typeof(T));
11
12 private static readonly string s_negativeSign = (((int)s_enumTypeCode % 2 == 0) ? null : NumberFormatInfo.CurrentInfo.NegativeSign);
13
15
17
19
21
22 public override bool CanConvert(Type type)
23 {
24 return type.IsEnum;
25 }
26
31
33 {
37 string[] names = Enum.GetNames(TypeToConvert);
39 JavaScriptEncoder encoder = serializerOptions.Encoder;
40 for (int i = 0; i < names.Length; i++)
41 {
42 if (_nameCache.Count >= 64)
43 {
44 break;
45 }
46 T val = (T)values.GetValue(i);
47 ulong key = ConvertToUInt64(val);
48 string value = names[i];
49 _nameCache.TryAdd(key, (namingPolicy == null) ? JsonEncodedText.Encode(value, encoder) : FormatEnumValue(value, encoder));
50 }
51 }
52
54 {
55 switch (reader.TokenType)
56 {
57 case JsonTokenType.String:
58 if (!_converterOptions.HasFlag(EnumConverterOptions.AllowStrings))
59 {
61 return default(T);
62 }
64 case JsonTokenType.Number:
65 if (_converterOptions.HasFlag(EnumConverterOptions.AllowNumbers))
66 {
67 switch (s_enumTypeCode)
68 {
69 case TypeCode.Int32:
70 {
71 if (reader.TryGetInt32(out var value8))
72 {
73 return Unsafe.As<int, T>(ref value8);
74 }
75 break;
76 }
77 case TypeCode.UInt32:
78 {
79 if (reader.TryGetUInt32(out var value4))
80 {
81 return Unsafe.As<uint, T>(ref value4);
82 }
83 break;
84 }
85 case TypeCode.UInt64:
86 {
87 if (reader.TryGetUInt64(out var value6))
88 {
89 return Unsafe.As<ulong, T>(ref value6);
90 }
91 break;
92 }
93 case TypeCode.Int64:
94 {
95 if (reader.TryGetInt64(out var value2))
96 {
97 return Unsafe.As<long, T>(ref value2);
98 }
99 break;
100 }
101 case TypeCode.SByte:
102 {
103 if (reader.TryGetSByte(out var value7))
104 {
105 return Unsafe.As<sbyte, T>(ref value7);
106 }
107 break;
108 }
109 case TypeCode.Byte:
110 {
111 if (reader.TryGetByte(out var value5))
112 {
113 return Unsafe.As<byte, T>(ref value5);
114 }
115 break;
116 }
117 case TypeCode.Int16:
118 {
119 if (reader.TryGetInt16(out var value3))
120 {
121 return Unsafe.As<short, T>(ref value3);
122 }
123 break;
124 }
125 case TypeCode.UInt16:
126 {
127 if (reader.TryGetUInt16(out var value))
128 {
129 return Unsafe.As<ushort, T>(ref value);
130 }
131 break;
132 }
133 }
135 return default(T);
136 }
137 goto default;
138 default:
140 return default(T);
141 }
142 }
143
145 {
146 if (_converterOptions.HasFlag(EnumConverterOptions.AllowStrings))
147 {
148 ulong key = ConvertToUInt64(value);
149 if (_nameCache.TryGetValue(key, out var value2))
150 {
151 writer.WriteStringValue(value2);
152 return;
153 }
154 string text = value.ToString();
156 {
157 JavaScriptEncoder encoder = options.Encoder;
158 if (_nameCache.Count < 64)
159 {
160 value2 = ((_namingPolicy == null) ? JsonEncodedText.Encode(text, encoder) : FormatEnumValue(text, encoder));
161 writer.WriteStringValue(value2);
162 _nameCache.TryAdd(key, value2);
163 }
164 else
165 {
166 writer.WriteStringValue((_namingPolicy == null) ? text : FormatEnumValueToString(text, encoder));
167 }
168 return;
169 }
170 }
171 if (!_converterOptions.HasFlag(EnumConverterOptions.AllowNumbers))
172 {
174 }
175 switch (s_enumTypeCode)
176 {
177 case TypeCode.Int32:
178 writer.WriteNumberValue(Unsafe.As<T, int>(ref value));
179 break;
180 case TypeCode.UInt32:
181 writer.WriteNumberValue(Unsafe.As<T, uint>(ref value));
182 break;
183 case TypeCode.UInt64:
184 writer.WriteNumberValue(Unsafe.As<T, ulong>(ref value));
185 break;
186 case TypeCode.Int64:
187 writer.WriteNumberValue(Unsafe.As<T, long>(ref value));
188 break;
189 case TypeCode.Int16:
190 writer.WriteNumberValue(Unsafe.As<T, short>(ref value));
191 break;
192 case TypeCode.UInt16:
193 writer.WriteNumberValue(Unsafe.As<T, ushort>(ref value));
194 break;
195 case TypeCode.Byte:
196 writer.WriteNumberValue(Unsafe.As<T, byte>(ref value));
197 break;
198 case TypeCode.SByte:
199 writer.WriteNumberValue(Unsafe.As<T, sbyte>(ref value));
200 break;
201 default:
203 break;
204 }
205 }
206
207 private static ulong ConvertToUInt64(object value)
208 {
209 return s_enumTypeCode switch
210 {
211 TypeCode.Int32 => (ulong)(int)value,
212 TypeCode.UInt32 => (uint)value,
213 TypeCode.UInt64 => (ulong)value,
214 TypeCode.Int64 => (ulong)(long)value,
215 TypeCode.SByte => (ulong)(sbyte)value,
216 TypeCode.Byte => (byte)value,
217 TypeCode.Int16 => (ulong)(short)value,
218 TypeCode.UInt16 => (ushort)value,
219 _ => throw new InvalidOperationException(),
220 };
221 }
222
223 private static bool IsValidIdentifier(string value)
224 {
225 if (value[0] >= 'A')
226 {
227 if (s_negativeSign != null)
228 {
229 return !value.StartsWith(s_negativeSign);
230 }
231 return true;
232 }
233 return false;
234 }
235
237 {
238 string value2 = FormatEnumValueToString(value, encoder);
239 return JsonEncodedText.Encode(value2, encoder);
240 }
241
242 private string FormatEnumValueToString(string value, JavaScriptEncoder encoder)
243 {
244 if (!value.Contains(", "))
245 {
247 }
248 string[] array = value.Split(", ");
249 for (int i = 0; i < array.Length; i++)
250 {
252 }
253 return string.Join(", ", array);
254 }
255
257 {
258 string @string = reader.GetString();
259 if (!Enum.TryParse<T>(@string, out var result) && !Enum.TryParse<T>(@string, ignoreCase: true, out result))
260 {
262 }
263 return result;
264 }
265
267 {
268 ulong key = ConvertToUInt64(value);
270 if (options.DictionaryKeyPolicy != null)
271 {
273 {
274 writer.WritePropertyName(value2);
275 return;
276 }
277 }
278 else if (_nameCache.TryGetValue(key, out value3))
279 {
280 writer.WritePropertyName(value3);
281 return;
282 }
283 string text = value.ToString();
285 {
286 if (options.DictionaryKeyPolicy != null)
287 {
288 text = options.DictionaryKeyPolicy.ConvertName(text);
289 if (text == null)
290 {
292 }
293 if (_dictionaryKeyPolicyCache == null)
294 {
296 }
297 if (_dictionaryKeyPolicyCache.Count < 64)
298 {
299 JavaScriptEncoder encoder = options.Encoder;
301 writer.WritePropertyName(jsonEncodedText);
303 }
304 else
305 {
306 writer.WritePropertyName(text);
307 }
308 }
309 else
310 {
312 if (_nameCache.Count < 64)
313 {
315 writer.WritePropertyName(jsonEncodedText2);
317 }
318 else
319 {
320 writer.WritePropertyName(text);
321 }
322 }
323 return;
324 }
325 switch (s_enumTypeCode)
326 {
327 case TypeCode.Int32:
328 writer.WritePropertyName(Unsafe.As<T, int>(ref value));
329 break;
330 case TypeCode.UInt32:
331 writer.WritePropertyName(Unsafe.As<T, uint>(ref value));
332 break;
333 case TypeCode.UInt64:
334 writer.WritePropertyName(Unsafe.As<T, ulong>(ref value));
335 break;
336 case TypeCode.Int64:
337 writer.WritePropertyName(Unsafe.As<T, long>(ref value));
338 break;
339 case TypeCode.Int16:
340 writer.WritePropertyName(Unsafe.As<T, short>(ref value));
341 break;
342 case TypeCode.UInt16:
343 writer.WritePropertyName(Unsafe.As<T, ushort>(ref value));
344 break;
345 case TypeCode.Byte:
346 writer.WritePropertyName(Unsafe.As<T, byte>(ref value));
347 break;
348 case TypeCode.SByte:
349 writer.WritePropertyName(Unsafe.As<T, sbyte>(ref value));
350 break;
351 default:
353 break;
354 }
355 }
356}
static string[] GetNames(Type enumType)
Definition Enum.cs:295
static Array GetValues(Type enumType)
Definition Enum.cs:323
static bool TryParse(Type enumType, string? value, out object? result)
Definition Enum.cs:416
string ConvertName(string name)
JsonEncodedText FormatEnumValue(string value, JavaScriptEncoder encoder)
EnumConverter(EnumConverterOptions converterOptions, JsonSerializerOptions serializerOptions)
override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
override T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
readonly ConcurrentDictionary< ulong, JsonEncodedText > _nameCache
override void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, JsonSerializerOptions options, bool isWritingExtensionDataProperty)
ConcurrentDictionary< ulong, JsonEncodedText > _dictionaryKeyPolicyCache
EnumConverter(EnumConverterOptions converterOptions, JsonNamingPolicy namingPolicy, JsonSerializerOptions serializerOptions)
string FormatEnumValueToString(string value, JavaScriptEncoder encoder)
static void ThrowInvalidOperationException_NamingPolicyReturnNull(JsonNamingPolicy namingPolicy)
static void ThrowJsonException(string message=null)
static TypeCode GetTypeCode(Type? type)
Definition Type.cs:919
TypeCode
Definition TypeCode.cs:4
static JsonEncodedText Encode(string value, JavaScriptEncoder? encoder=null)