-
Notifications
You must be signed in to change notification settings - Fork 540
Expand file tree
/
Copy pathCosmosSystemTextJsonSerializer.cs
More file actions
141 lines (122 loc) · 5.71 KB
/
CosmosSystemTextJsonSerializer.cs
File metadata and controls
141 lines (122 loc) · 5.71 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
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using System;
using System.IO;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Azure.Cosmos.CosmosElements;
using Microsoft.Azure.Cosmos.Json;
using Microsoft.Azure.Cosmos.Serializer;
/// <summary>
/// This class provides a default implementation of System.Text.Json Cosmos Linq Serializer.
/// </summary>
internal class CosmosSystemTextJsonSerializer : CosmosLinqSerializer
{
/// <summary>
/// A read-only instance of <see cref="JsonSerializerOptions"/>.
/// </summary>
private readonly JsonSerializerOptions jsonSerializerOptions;
/// <summary>
/// Creates an instance of <see cref="CosmosSystemTextJsonSerializer"/>
/// with the default values for the Cosmos SDK
/// </summary>
/// <param name="jsonSerializerOptions">An instance of <see cref="JsonSerializerOptions"/> containing the json serialization options.</param>
internal CosmosSystemTextJsonSerializer(
JsonSerializerOptions jsonSerializerOptions)
{
this.jsonSerializerOptions = jsonSerializerOptions;
}
/// <inheritdoc/>
public override T FromStream<T>(Stream stream)
{
if (stream == null)
throw new ArgumentNullException(nameof(stream));
if (typeof(Stream).IsAssignableFrom(typeof(T)) && stream is T typedStream)
{
return typedStream;
}
if (stream.CanSeek && stream.Length == 0)
{
return default;
}
using (stream)
{
if (stream is Documents.CloneableStream cloneableStream)
{
using (CosmosBufferedStreamWrapper bufferedStream = new (cloneableStream, shouldDisposeInnerStream: false))
{
if (bufferedStream.GetJsonSerializationFormat() == JsonSerializationFormat.Binary)
{
byte[] content = bufferedStream.ReadAll();
if (CosmosObject.TryCreateFromBuffer(content, out CosmosObject cosmosObject))
{
IJsonWriter jsonWriter = JsonWriter.Create(JsonSerializationFormat.Text);
cosmosObject.WriteTo(jsonWriter);
return System.Text.Json.JsonSerializer.Deserialize<T>(jsonWriter.GetResult().Span, this.jsonSerializerOptions);
}
else
{
using Stream textStream = CosmosSerializationUtil.ConvertToStreamUsingJsonSerializationFormat(content, JsonSerializationFormat.Text);
return this.DeserializeStream<T>(textStream);
}
}
}
}
return this.DeserializeStream<T>(stream);
}
}
/// <inheritdoc/>
public override Stream ToStream<T>(T input)
{
MemoryStream streamPayload = new ();
using Utf8JsonWriter writer = new (streamPayload);
System.Text.Json.JsonSerializer.Serialize(writer, input, this.jsonSerializerOptions);
streamPayload.Position = 0;
return streamPayload;
}
/// <summary>
/// Convert a MemberInfo to a string for use in LINQ query translation.
/// </summary>
/// <param name="memberInfo">Any MemberInfo used in the query.</param>
/// <returns>A serialized representation of the member.</returns>
/// <remarks>
/// Note that this is just a default implementation which handles the basic scenarios.To handle any special cases,
/// please create a custom serializer which inherits from the <see cref="CosmosSystemTextJsonSerializer"/> and overrides the
/// SerializeMemberName() method.
/// </remarks>
public override string SerializeMemberName(MemberInfo memberInfo)
{
JsonExtensionDataAttribute jsonExtensionDataAttribute =
memberInfo.GetCustomAttribute<JsonExtensionDataAttribute>(true);
if (jsonExtensionDataAttribute != null)
{
return null;
}
JsonPropertyNameAttribute jsonPropertyNameAttribute = memberInfo.GetCustomAttribute<JsonPropertyNameAttribute>(true);
if (!string.IsNullOrEmpty(jsonPropertyNameAttribute?.Name))
{
return jsonPropertyNameAttribute.Name;
}
if (this.jsonSerializerOptions.PropertyNamingPolicy != null)
{
return this.jsonSerializerOptions.PropertyNamingPolicy.ConvertName(memberInfo.Name);
}
return memberInfo.Name;
}
/// <summary>
/// Deserializes the stream into the specified type using STJ Serializer.
/// </summary>
/// <typeparam name="T">The desired type, the input stream to be deserialize into</typeparam>
/// <param name="stream">An instance of <see cref="Stream"/> containing th raw input stream.</param>
/// <returns>The deserialized output of type <typeparamref name="T"/>.</returns>
private T DeserializeStream<T>(
Stream stream)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(stream, this.jsonSerializerOptions);
}
}
}