-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy pathDictionaryKeyEditorSerializer.cs
More file actions
159 lines (149 loc) · 4.46 KB
/
Copy pathDictionaryKeyEditorSerializer.cs
File metadata and controls
159 lines (149 loc) · 4.46 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
using RPGCore.DataEditor.Manifest;
using System;
using System.IO;
using System.Text;
using System.Text.Json;
namespace RPGCore.DataEditor;
/// <summary>
/// A serializer for reading and writing <see cref="IEditorValue"/>.
/// </summary>
public class DictionaryKeyEditorSerializer : IEditorSerializer
{
/// <inheritdoc/>
public IEditorValue DeserializeValue(EditorSession session, TypeName type, ReadOnlySpan<byte> data)
{
var encoding = new UTF8Encoding();
if (type.IsArray || type.IsDictionary || type.IsUnknown)
{
throw new InvalidOperationException($"Unable to read value of type \"{type}\".");
}
else if (type.Identifier == "string")
{
return new EditorScalarValue<string>(session, type, encoding.GetString(data.ToArray()));
}
else if (type.Identifier == "char")
{
return new EditorScalarValue<char>(session, type, encoding.GetString(data.ToArray())[0]);
}
var reader = new Utf8JsonReader(data, true, new JsonReaderState(new JsonReaderOptions()
{
CommentHandling = JsonCommentHandling.Allow,
AllowTrailingCommas = true,
}));
if (!reader.Read())
{
throw new InvalidOperationException("Unable to read value as the data is empty.");
}
var typeInfo = session.ResolveType(type);
if (typeInfo == null)
{
throw new InvalidOperationException($"Unable to resolve type information for \"{type}\".");
}
if (typeInfo.Fields != null && typeInfo.Fields.Count > 0)
{
throw new InvalidOperationException($"Read object type \"{type}\" as dictionary key.");
}
else
{
EditorScalarValue editorScalarValue = type.Identifier switch
{
"string" => new EditorScalarValue<string>(session, type, reader.GetString()),
"char" => new EditorScalarValue<char>(session, type, reader.GetString()![0]),
"bool" => new EditorScalarValue<bool>(session, type, reader.GetBoolean()),
"byte" => new EditorScalarValue<byte>(session, type, reader.GetByte()),
"sbyte" => new EditorScalarValue<sbyte>(session, type, reader.GetSByte()),
"short" => new EditorScalarValue<short>(session, type, reader.GetInt16()),
"ushort" => new EditorScalarValue<ushort>(session, type, reader.GetUInt16()),
"int" => new EditorScalarValue<int>(session, type, reader.GetInt32()),
"uint" => new EditorScalarValue<uint>(session, type, reader.GetUInt32()),
"long" => new EditorScalarValue<long>(session, type, reader.GetInt64()),
"ulong" => new EditorScalarValue<ulong>(session, type, reader.GetUInt64()),
"float" => new EditorScalarValue<float>(session, type, reader.GetSingle()),
"double" => new EditorScalarValue<double>(session, type, reader.GetDouble()),
"decimal" => new EditorScalarValue<decimal>(session, type, reader.GetDecimal()),
_ => throw new InvalidDataException($"Type \"{type.Identifier}\" is not readable as a scalar value."),
};
return editorScalarValue;
}
}
/// <inheritdoc/>
public void SerializeValue(IEditorValue value, TypeName type, Stream output)
{
var writer = new StreamWriter(output);
switch (value)
{
case EditorScalarValue editorScalar:
{
switch (editorScalar.Value)
{
case byte[] byteArray:
{
writer.Write(Convert.ToBase64String(byteArray));
break;
}
case Memory<byte> byteArray:
{
writer.Write(Convert.ToBase64String(byteArray.ToArray()));
break;
}
case ArraySegment<byte> byteArray:
{
writer.Write(Convert.ToBase64String(byteArray.Array, byteArray.Offset, byteArray.Count));
break;
}
case bool booleanValue:
{
writer.Write(booleanValue ? "true" : "false");
break;
}
case string:
case char:
case byte:
case sbyte:
case short:
case ushort:
case int:
case uint:
case long:
case ulong:
case decimal:
case double:
case float:
{
writer.Write(editorScalar.Value.ToString());
break;
}
case null:
{
writer.Write("null");
break;
}
default:
{
throw new InvalidOperationException($"unknown type {editorScalar?.Value?.GetType().Name ?? "null"}");
}
}
break;
}
case EditorNull:
{
writer.Write("null");
break;
}
case EditorObject:
{
break;
}
case EditorDictionary:
case EditorList:
{
break;
}
case null:
throw new ArgumentNullException("Cannot serialize \"null\" editor value.");
default:
throw new ArgumentException($"Cannot serialize editor value of type \"{value.GetType().Name}\".");
}
writer.Flush();
}
}