-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathBinaryConverter.cs
More file actions
132 lines (111 loc) · 3.67 KB
/
Copy pathBinaryConverter.cs
File metadata and controls
132 lines (111 loc) · 3.67 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
using System.Text.Json;
using System.Text.Json.Serialization;
using Ceras;
using Newtonsoft.Json.Linq;
//From https://gist.github.com/LorenzGit/2cd665b6b588a8bb75c1a53f4d6b240a
//Turned Async and Made Secure
////USING BINARY FORMATTER
// Convert an object to a byte array
//Updated; we now try with Ceras; if the object type isn't supported, we fall back to JSON serialization. This means we improve performance
//Whenever possible AND can handle weird custom objects
public static class BinaryConverter
{
private static readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters =
{
new JTokenConverter()
}
};
public static async Task<byte[]> NCObjectToByteArrayAsync<T>(
T obj,
SerializerConfig? config = null,
CancellationToken cancellationToken = default)
{
try
{
try
{
var serializer = config != null ? new CerasSerializer(config) : new CerasSerializer();
var data = serializer.Serialize(obj);
return data;
}
catch (Exception cerasEx)
{
// Fallback to JSON
await using var ms = new MemoryStream();
await JsonSerializer
.SerializeAsync(ms, obj, _options, cancellationToken)
.ConfigureAwait(false);
return ms.ToArray();
}
}
catch
{
throw new Exception("Failed to Convert Object to Byte Array.");
}
}
public static async Task<T?> NCByteArrayToObjectAsync<T>(
byte[] data,
SerializerConfig? config = null,
CancellationToken cancellationToken = default)
{
try
{
// First try Ceras
try
{
var serializer = config != null ? new CerasSerializer(config) : new CerasSerializer();
return serializer.Deserialize<T>(data);
}
catch (Exception cerasEx)
{
// Fallback to JSON
await using var ms = new MemoryStream(data);
return await JsonSerializer
.DeserializeAsync<T>(ms, _options, cancellationToken)
.ConfigureAwait(false);
}
}
catch
{
throw new Exception("Failed to Convert Byte Array to Object.");
}
}
private class JTokenConverter : JsonConverter<JToken>
{
public override JToken Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
try
{
// Parse the JSON fragment into a JsonDocument, then into a JToken.
using var doc = JsonDocument.ParseValue(ref reader);
return JToken.Parse(doc.RootElement.GetRawText());
}
catch
{
throw new Exception("Failed to Read JToken.");
}
}
public override void Write(
Utf8JsonWriter writer,
JToken value,
JsonSerializerOptions options)
{
try
{
// Write the JToken’s raw JSON directly into the Utf8JsonWriter
writer.WriteRawValue(value.ToString(Newtonsoft.Json.Formatting.None));
}
catch
{
throw new Exception("Failed to Write JToken.");
}
}
}
}