ModelSerializationExtensions
using Azure.Core;
using System;
using System.ClientModel.Primitives;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Xml;
namespace Azure.Storage.Common
{
internal static class ModelSerializationExtensions
{
internal static class TypeFormatters
{
private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ";
public const string DefaultNumberFormat = "G";
public static string ToString(bool value)
{
if (!value)
return "false";
return "true";
}
public static string ToString(DateTime value, string format)
{
if (value.Kind != DateTimeKind.Utc) {
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(143, 2);
defaultInterpolatedStringHandler.AppendLiteral("DateTime ");
defaultInterpolatedStringHandler.AppendFormatted(value);
defaultInterpolatedStringHandler.AppendLiteral(" has a Kind of ");
defaultInterpolatedStringHandler.AppendFormatted(value.Kind);
defaultInterpolatedStringHandler.AppendLiteral(". Azure SDK requires it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.");
throw new NotSupportedException(defaultInterpolatedStringHandler.ToStringAndClear());
}
return ToString((DateTimeOffset)value, format);
}
public static string ToString(DateTimeOffset value, string format)
{
if (format == "D")
return value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
if (format == "U")
return value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture);
DateTimeOffset dateTimeOffset;
if (format == "O") {
dateTimeOffset = value.ToUniversalTime();
return dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ", CultureInfo.InvariantCulture);
}
if (format == "o") {
dateTimeOffset = value.ToUniversalTime();
return dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ", CultureInfo.InvariantCulture);
}
if (format == "R")
return value.ToString("r", CultureInfo.InvariantCulture);
return value.ToString(format, CultureInfo.InvariantCulture);
}
public static string ToString(TimeSpan value, string format)
{
if (!(format == "P"))
return value.ToString(format, CultureInfo.InvariantCulture);
return XmlConvert.ToString(value);
}
public static string ToString(byte[] value, string format)
{
if (format == "U")
return ToBase64UrlString(value);
if (!(format == "D"))
throw new ArgumentException("Format is not supported: '" + format + "'", "format");
return Convert.ToBase64String(value);
}
public static string ToBase64UrlString(byte[] value)
{
char[] array;
int num;
int num2;
checked {
array = new char[unchecked(checked(value.Length + 2) / 3) * 4];
num = Convert.ToBase64CharArray(value, 0, value.Length, array, 0);
num2 = 0;
}
while (true) {
if (num2 < num) {
switch (array[num2]) {
case '+':
array[num2] = '-';
goto default;
case '/':
array[num2] = '_';
goto default;
default:
num2++;
continue;
case '=':
break;
}
}
break;
}
return new string(array, 0, num2);
}
public static byte[] FromBase64UrlString(string value)
{
int num;
switch (value.Length % 4) {
case 0:
num = 0;
break;
case 2:
num = 2;
break;
case 3:
num = 1;
break;
default:
throw new InvalidOperationException("Malformed input");
}
int num2 = num;
char[] array = new char[value.Length + num2];
int i;
for (i = 0; i < value.Length; i++) {
char c = value[i];
switch (c) {
case '-':
array[i] = '+';
break;
case '_':
array[i] = '/';
break;
default:
array[i] = c;
break;
}
}
for (; i < array.Length; i++) {
array[i] = '=';
}
return Convert.FromBase64CharArray(array, 0, array.Length);
}
public static DateTimeOffset ParseDateTimeOffset(string value, string format)
{
if (!(format == "U"))
return DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
return DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture));
}
public static TimeSpan ParseTimeSpan(string value, string format)
{
if (!(format == "P"))
return TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture);
return XmlConvert.ToTimeSpan(value);
}
public static string ConvertToString(object value, string format = null)
{
if (value == null)
return "null";
string text = value as string;
if (text != null)
return text;
if (!(value is bool)) {
if (!(value is int) && !(value is float) && !(value is double) && !(value is long) && !(value is decimal)) {
byte[] array = value as byte[];
if (array == null) {
IEnumerable<string> enumerable = value as IEnumerable<string>;
if (enumerable != null)
return string.Join(",", enumerable);
if (value is DateTimeOffset) {
DateTimeOffset value2 = (DateTimeOffset)value;
if (format != null)
return ToString(value2, format);
} else {
if (value is TimeSpan) {
TimeSpan value3 = (TimeSpan)value;
if (format == null)
return XmlConvert.ToString(value3);
return ToString(value3, format);
}
if (value is Guid)
return ((Guid)value).ToString();
BinaryData val = value as BinaryData;
if (val != null)
return ConvertToString(val.ToArray(), format);
}
} else if (format != null) {
return ToString(array, format);
}
return value.ToString();
}
return ((IFormattable)value).ToString("G", CultureInfo.InvariantCulture);
}
bool value4 = (bool)value;
return ToString(value4);
}
}
internal static readonly JsonDocumentOptions JsonDocumentOptions = new JsonDocumentOptions {
MaxDepth = 256
};
internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W");
public static object GetObject(this JsonElement element)
{
switch (element.ValueKind) {
case JsonValueKind.String:
return element.GetString();
case JsonValueKind.Number:
if (element.TryGetInt32(out int value))
return value;
if (element.TryGetInt64(out long value2))
return value2;
return element.GetDouble();
case JsonValueKind.True:
return true;
case JsonValueKind.False:
return false;
case JsonValueKind.Undefined:
case JsonValueKind.Null:
return null;
case JsonValueKind.Object: {
Dictionary<string, object> dictionary = new Dictionary<string, object>();
{
foreach (JsonProperty item in element.EnumerateObject()) {
dictionary.Add(item.Name, item.Value.GetObject());
}
return dictionary;
}
}
case JsonValueKind.Array: {
List<object> list = new List<object>();
foreach (JsonElement item2 in element.EnumerateArray()) {
list.Add(item2.GetObject());
}
return list.ToArray();
}
default: {
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 1);
defaultInterpolatedStringHandler.AppendLiteral("Not supported value kind ");
defaultInterpolatedStringHandler.AppendFormatted(element.ValueKind);
throw new NotSupportedException(defaultInterpolatedStringHandler.ToStringAndClear());
}
}
}
public static byte[] GetBytesFromBase64(this JsonElement element, string format)
{
if (element.ValueKind == JsonValueKind.Null)
return null;
if (format == "U")
return TypeFormatters.FromBase64UrlString(element.GetRequiredString());
if (!(format == "D"))
throw new ArgumentException("Format is not supported: '" + format + "'", "format");
return element.GetBytesFromBase64();
}
public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format)
{
if (format == "U" && element.ValueKind == JsonValueKind.Number)
return DateTimeOffset.FromUnixTimeSeconds(element.GetInt64());
return TypeFormatters.ParseDateTimeOffset(element.GetString(), format);
}
public static TimeSpan GetTimeSpan(this JsonElement element, string format)
{
return TypeFormatters.ParseTimeSpan(element.GetString(), format);
}
public static char GetChar(this JsonElement element)
{
if (element.ValueKind == JsonValueKind.String) {
string string = element.GetString();
if (string == null || string.Length != 1)
throw new NotSupportedException("Cannot convert \"" + string + "\" to a char");
return string[0];
}
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 1);
defaultInterpolatedStringHandler.AppendLiteral("Cannot convert ");
defaultInterpolatedStringHandler.AppendFormatted(element.ValueKind);
defaultInterpolatedStringHandler.AppendLiteral(" to a char");
throw new NotSupportedException(defaultInterpolatedStringHandler.ToStringAndClear());
}
[Conditional("DEBUG")]
public static void ThrowNonNullablePropertyIsNull(this JsonProperty property)
{
throw new JsonException("A property '" + property.Name + "' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build");
}
public static string GetRequiredString(this JsonElement element)
{
string string = element.GetString();
if (string == null) {
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(97, 1);
defaultInterpolatedStringHandler.AppendLiteral("The requested operation requires an element of type 'String', but the target element has type '");
defaultInterpolatedStringHandler.AppendFormatted(element.ValueKind);
defaultInterpolatedStringHandler.AppendLiteral("'.");
throw new InvalidOperationException(defaultInterpolatedStringHandler.ToStringAndClear());
}
return string;
}
public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format)
{
writer.WriteStringValue(TypeFormatters.ToString(value, format));
}
public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format)
{
writer.WriteStringValue(TypeFormatters.ToString(value, format));
}
public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format)
{
writer.WriteStringValue(TypeFormatters.ToString(value, format));
}
public static void WriteStringValue(this Utf8JsonWriter writer, char value)
{
writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
}
public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format)
{
if (value == null)
writer.WriteNullValue();
else if (!(format == "U")) {
if (!(format == "D"))
throw new ArgumentException("Format is not supported: '" + format + "'", "format");
writer.WriteBase64StringValue(value);
} else {
writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value));
}
}
public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format)
{
if (format != "U")
throw new ArgumentOutOfRangeException("format", "Only 'U' format is supported when writing a DateTimeOffset as a Number.");
writer.WriteNumberValue(value.ToUnixTimeSeconds());
}
public static void WriteObjectValue<T>(this Utf8JsonWriter writer, T value)
{
if (value != null) {
IUtf8JsonSerializable utf8JsonSerializable = value as IUtf8JsonSerializable;
if (utf8JsonSerializable == null) {
byte[] array = value as byte[];
if (array == null) {
BinaryData val = value as BinaryData;
if (val == null) {
if (!(((object)value) is JsonElement)) {
if (((object)value) is int) {
int value2 = value as int;
writer.WriteNumberValue(value2);
} else if (((object)value) is decimal) {
decimal value3 = value as decimal;
writer.WriteNumberValue(value3);
} else if (((object)value) is double) {
double num = value as double;
if (double.IsNaN(num))
writer.WriteStringValue("NaN");
else
writer.WriteNumberValue(num);
} else if (((object)value) is float) {
float value4 = value as float;
writer.WriteNumberValue(value4);
} else if (((object)value) is long) {
long value5 = value as long;
writer.WriteNumberValue(value5);
} else {
string text = value as string;
if (text == null) {
if (((object)value) is bool) {
bool value6 = value as bool;
writer.WriteBooleanValue(value6);
} else if (((object)value) is Guid) {
Guid value7 = value as Guid;
writer.WriteStringValue(value7);
} else if (((object)value) is DateTimeOffset) {
DateTimeOffset value8 = value as DateTimeOffset;
writer.WriteStringValue(value8, "O");
} else if (((object)value) is DateTime) {
DateTime value9 = value as DateTime;
writer.WriteStringValue(value9, "O");
} else {
IEnumerable<KeyValuePair<string, object>> enumerable = value as IEnumerable<KeyValuePair<string, object>>;
if (enumerable == null) {
IEnumerable<object> enumerable2 = value as IEnumerable<object>;
if (enumerable2 == null) {
if (!(((object)value) is TimeSpan)) {
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(19, 1);
defaultInterpolatedStringHandler.AppendLiteral("Not supported type ");
defaultInterpolatedStringHandler.AppendFormatted(value.GetType());
throw new NotSupportedException(defaultInterpolatedStringHandler.ToStringAndClear());
}
TimeSpan value10 = value as TimeSpan;
writer.WriteStringValue(value10, "P");
} else {
writer.WriteStartArray();
foreach (object item in enumerable2) {
writer.WriteObjectValue<object>(item);
}
writer.WriteEndArray();
}
} else {
writer.WriteStartObject();
foreach (KeyValuePair<string, object> item2 in enumerable) {
writer.WritePropertyName(item2.Key);
writer.WriteObjectValue<object>(item2.Value);
}
writer.WriteEndObject();
}
}
} else
writer.WriteStringValue(text);
}
} else
(value as JsonElement).WriteTo(writer);
} else
writer.WriteBase64StringValue(BinaryData.op_Implicit(val));
} else
writer.WriteBase64StringValue(array);
} else
utf8JsonSerializable.Write(writer);
} else
writer.WriteNullValue();
}
public static void WriteObjectValue(this Utf8JsonWriter writer, object value)
{
writer.WriteObjectValue<object>(value);
}
}
}