SerializationRecordExtensions
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Formats.Nrbf;
using System.IO;
using System.Private.Windows.BinaryFormat;
using System.Private.Windows.Core.Resources;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.Serialization;
using System.Text.Json;
namespace System.Private.Windows.Nrbf
{
[NullableContext(1)]
[Nullable(0)]
internal static class SerializationRecordExtensions
{
[NullableContext(0)]
internal delegate bool TryGetDelegate (SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value);
internal static SerializationRecord DecodeNrbf(this Stream stream)
{
IReadOnlyDictionary<SerializationRecordId, SerializationRecord> recordMap;
return stream.DecodeNrbf(out recordMap);
}
internal static SerializationRecord DecodeNrbf(this Stream stream, out IReadOnlyDictionary<SerializationRecordId, SerializationRecord> recordMap)
{
try {
return NrbfDecoder.Decode(stream, ref recordMap, null, true);
} catch (Exception ex) when (((ex is ArgumentException || ex is InvalidCastException || ex is ArithmeticException || ex is IOException || ex is TargetInvocationException) ? 1 : 0) != 0) {
throw ex.ConvertToSerializationException();
}
}
[RequiresUnreferencedCode("Ultimately calls resolver for type names in the data.")]
[return: Nullable(2)]
public static object Deserialize(this SerializationRecord rootRecord, IReadOnlyDictionary<SerializationRecordId, SerializationRecord> recordMap, ITypeResolver typeResolver)
{
DeserializationOptions options = new DeserializationOptions {
TypeResolver = typeResolver
};
try {
return Deserializer.Deserialize(rootRecord.get_Id(), recordMap, options);
} catch (SerializationException ex) {
throw ExceptionDispatchInfo.SetRemoteStackTrace(new NotSupportedException(ex.Message, ex), ex.StackTrace ?? string.Empty);
}
}
internal static bool TryGet(TryGetDelegate get, SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
try {
return get(record, out value);
} catch (Exception ex) when (((ex is KeyNotFoundException || ex is InvalidCastException) ? 1 : 0) != 0) {
value = null;
return false;
}
}
public static bool TryGetPoint(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(Point)) || !val.HasMember("x") || !val.HasMember("y"))
return false;
value = new Point(val.GetInt32("x"), val.GetInt32("y"));
return true;
}, record, out value);
}
public static bool TryGetSize(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(Size)) || !val.HasMember("height") || !val.HasMember("width"))
return false;
value = new Size(val.GetInt32("width"), val.GetInt32("height"));
return true;
}, record, out value);
}
public static bool TryGetRectangle(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(Rectangle)) || !val.HasMember("x") || !val.HasMember("y") || !val.HasMember("width") || !val.HasMember("height"))
return false;
value = new Rectangle(val.GetInt32("x"), val.GetInt32("y"), val.GetInt32("width"), val.GetInt32("height"));
return true;
}, record, out value);
}
public static bool TryGetPointF(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(PointF)) || !val.HasMember("x") || !val.HasMember("y"))
return false;
value = new PointF(val.GetSingle("x"), val.GetSingle("y"));
return true;
}, record, out value);
}
public static bool TryGetSizeF(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(SizeF)) || !val.HasMember("height") || !val.HasMember("width"))
return false;
value = new SizeF(val.GetSingle("width"), val.GetSingle("height"));
return true;
}, record, out value);
}
public static bool TryGetRectangleF(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(RectangleF)) || !val.HasMember("x") || !val.HasMember("y") || !val.HasMember("width") || !val.HasMember("height"))
return false;
value = new RectangleF(val.GetSingle("x"), val.GetSingle("y"), val.GetSingle("width"), val.GetSingle("height"));
return true;
}, record, out value);
}
public static bool TryGetColor(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(Color)) || !val.HasMember("name") || !val.HasMember("value") || !val.HasMember("knownColor") || !val.HasMember("state"))
return false;
ConstructorInfo constructor = typeof(Color).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, new Type[4] {
typeof(long),
typeof(short),
typeof(string),
typeof(KnownColor)
});
if ((object)constructor == null)
return false;
value = constructor.Invoke(new object[4] {
val.GetInt64("value"),
val.GetInt16("state"),
val.GetString("name"),
(KnownColor)Convert.ToInt32(val.GetInt16("knownColor"))
});
return true;
}, record, out value);
}
public static bool TryGetPrimitiveType(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
if ((int)record.get_RecordType() == 6) {
value = record.get_Value();
return true;
}
if ((int)record.get_RecordType() == 8) {
value = record.GetMemberPrimitiveTypedValue();
return true;
}
value = null;
return false;
}, record, out value);
}
internal static object GetMemberPrimitiveTypedValue(this SerializationRecord record)
{
return record.get_Value();
}
public static bool TryGetPrimitiveList(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object list)
{
return TryGet(delegate(SerializationRecord record, out object list) {
list = null;
ClassRecord val = record as ClassRecord;
if (val != null && val.HasMember("_items") && val.HasMember("_size")) {
object rawValue = val.GetRawValue("_size");
if (rawValue is int) {
int count = (int)rawValue;
if (val.get_TypeName().IsConstructedGenericType && !(val.get_TypeName().GetGenericTypeDefinition().Name != typeof(List<>).Name) && val.get_TypeName().GetGenericArguments().Length == 1) {
ArrayRecord val2 = val.GetRawValue("_items") as ArrayRecord;
if (val2 != null && IsPrimitiveArrayRecord(val2)) {
SZArrayRecord<string> val3 = val2 as SZArrayRecord<string>;
if (val3 == null) {
SZArrayRecord<bool> val4 = val2 as SZArrayRecord<bool>;
if (val4 == null) {
SZArrayRecord<byte> val5 = val2 as SZArrayRecord<byte>;
if (val5 == null) {
SZArrayRecord<sbyte> val6 = val2 as SZArrayRecord<sbyte>;
if (val6 == null) {
SZArrayRecord<char> val7 = val2 as SZArrayRecord<char>;
if (val7 == null) {
SZArrayRecord<short> val8 = val2 as SZArrayRecord<short>;
if (val8 == null) {
SZArrayRecord<ushort> val9 = val2 as SZArrayRecord<ushort>;
if (val9 == null) {
SZArrayRecord<int> val10 = val2 as SZArrayRecord<int>;
if (val10 == null) {
SZArrayRecord<uint> val11 = val2 as SZArrayRecord<uint>;
if (val11 == null) {
SZArrayRecord<long> val12 = val2 as SZArrayRecord<long>;
if (val12 == null) {
SZArrayRecord<ulong> val13 = val2 as SZArrayRecord<ulong>;
if (val13 == null) {
SZArrayRecord<float> val14 = val2 as SZArrayRecord<float>;
if (val14 == null) {
SZArrayRecord<double> val15 = val2 as SZArrayRecord<double>;
if (val15 == null) {
SZArrayRecord<decimal> val16 = val2 as SZArrayRecord<decimal>;
if (val16 == null) {
SZArrayRecord<TimeSpan> val17 = val2 as SZArrayRecord<TimeSpan>;
if (val17 == null) {
SZArrayRecord<DateTime> val18 = val2 as SZArrayRecord<DateTime>;
if (val18 == null)
throw new InvalidOperationException();
rawValue = val18.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val17.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val16.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val15.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val14.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val13.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val12.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val11.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val10.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val9.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val8.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val7.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val6.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val5.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val4.GetArray(true).CreateTrimmedList(count);
} else
rawValue = val3.GetArray(true).CreateTrimmedList(count);
list = rawValue;
return true;
}
}
}
}
return false;
}, record, out list);
}
public static bool TryGetPrimitiveArrayList(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
value = null;
ClassRecord val = record as ClassRecord;
if (val != null && val.TypeNameMatches(typeof(ArrayList)) && val.HasMember("_items") && val.HasMember("_size")) {
object rawValue = val.GetRawValue("_size");
if (rawValue is int) {
int num = (int)rawValue;
SZArrayRecord<SerializationRecord> val2 = val.GetRawValue("_items") as SZArrayRecord<SerializationRecord>;
if (val2 != null && num <= val2.get_Length()) {
ArrayList arrayList = new ArrayList(num);
SerializationRecord[] array = val2.GetArray(true);
for (int i = 0; i < num; i++) {
SerializationRecord val3 = array[i];
if (val3 == null)
arrayList.Add(null);
else {
PrimitiveTypeRecord val4 = val3 as PrimitiveTypeRecord;
if (val4 == null)
return false;
arrayList.Add(val4.get_Value());
}
}
value = arrayList;
return true;
}
}
}
return false;
}, record, out value);
}
public static bool TryGetPrimitiveArray(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
return TryGet(delegate(SerializationRecord record, out object value) {
if (!IsPrimitiveArrayRecord(record)) {
value = null;
return false;
}
SZArrayRecord<string> val = record as SZArrayRecord<string>;
object array;
if (val == null) {
SZArrayRecord<bool> val2 = record as SZArrayRecord<bool>;
if (val2 == null) {
SZArrayRecord<byte> val3 = record as SZArrayRecord<byte>;
if (val3 == null) {
SZArrayRecord<sbyte> val4 = record as SZArrayRecord<sbyte>;
if (val4 == null) {
SZArrayRecord<char> val5 = record as SZArrayRecord<char>;
if (val5 == null) {
SZArrayRecord<short> val6 = record as SZArrayRecord<short>;
if (val6 == null) {
SZArrayRecord<ushort> val7 = record as SZArrayRecord<ushort>;
if (val7 == null) {
SZArrayRecord<int> val8 = record as SZArrayRecord<int>;
if (val8 == null) {
SZArrayRecord<uint> val9 = record as SZArrayRecord<uint>;
if (val9 == null) {
SZArrayRecord<long> val10 = record as SZArrayRecord<long>;
if (val10 == null) {
SZArrayRecord<ulong> val11 = record as SZArrayRecord<ulong>;
if (val11 == null) {
SZArrayRecord<float> val12 = record as SZArrayRecord<float>;
if (val12 == null) {
SZArrayRecord<double> val13 = record as SZArrayRecord<double>;
if (val13 == null) {
SZArrayRecord<decimal> val14 = record as SZArrayRecord<decimal>;
if (val14 == null) {
SZArrayRecord<TimeSpan> val15 = record as SZArrayRecord<TimeSpan>;
if (val15 == null) {
SZArrayRecord<DateTime> val16 = record as SZArrayRecord<DateTime>;
if (val16 == null)
throw new InvalidOperationException();
array = val16.GetArray(true);
} else
array = val15.GetArray(true);
} else
array = val14.GetArray(true);
} else
array = val13.GetArray(true);
} else
array = val12.GetArray(true);
} else
array = val11.GetArray(true);
} else
array = val10.GetArray(true);
} else
array = val9.GetArray(true);
} else
array = val8.GetArray(true);
} else
array = val7.GetArray(true);
} else
array = val6.GetArray(true);
} else
array = val5.GetArray(true);
} else
array = val4.GetArray(true);
} else
array = val3.GetArray(true);
} else
array = val2.GetArray(true);
} else
array = val.GetArray(true);
value = array;
return value != null;
}, record, out value);
}
public static bool TryGetPrimitiveHashtable(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out Hashtable hashtable)
{
object hashtable2;
bool result = record.TryGetPrimitiveHashtable(out hashtable2);
hashtable = (Hashtable)hashtable2;
return result;
}
public static bool TryGetPrimitiveHashtable(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object hashtable)
{
return TryGet(delegate(SerializationRecord record, out object hashtable) {
hashtable = null;
if ((int)record.get_RecordType() == 4) {
ClassRecord val = record as ClassRecord;
if (val != null && val.TypeNameMatches(typeof(Hashtable)) && val.HasMember("Keys") && val.HasMember("Values") && (int)val.GetSerializationRecord("Comparer") == 0) {
SZArrayRecord<SerializationRecord> val2 = val.GetSerializationRecord("Keys") as SZArrayRecord<SerializationRecord>;
if (val2 != null) {
SZArrayRecord<SerializationRecord> val3 = val.GetSerializationRecord("Values") as SZArrayRecord<SerializationRecord>;
if (val3 != null && val2.get_Length() == val3.get_Length()) {
Hashtable hashtable2 = new Hashtable(val2.get_Length());
SerializationRecord[] array = val2.GetArray(true);
SerializationRecord[] array2 = val3.GetArray(true);
int num = 0;
while (num < array.Length) {
SerializationRecord val4 = array[num];
SerializationRecord val5 = array2[num];
if (val4 != null) {
PrimitiveTypeRecord val6 = val4 as PrimitiveTypeRecord;
if (val6 != null) {
if (val5 == null)
hashtable2[val6.get_Value()] = null;
else {
PrimitiveTypeRecord val7 = val5 as PrimitiveTypeRecord;
if (val7 == null)
return false;
hashtable2[val6.get_Value()] = val7.get_Value();
}
num++;
continue;
}
}
return false;
}
hashtable = hashtable2;
return true;
}
}
}
}
return false;
}, record, out hashtable);
}
public static bool TryGetNotSupportedException(this SerializationRecord record, [Nullable(2)] out object exception)
{
return TryGet(delegate(SerializationRecord record, out object exception) {
exception = null;
ClassRecord val = record as ClassRecord;
if (val == null || !val.TypeNameMatches(typeof(NotSupportedException)))
return false;
exception = new NotSupportedException(val.GetString("Message"));
return true;
}, record, out exception);
}
public static bool TryGetFrameworkObject(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
if (!record.TryGetPrimitiveType(out value) && !record.TryGetPrimitiveList(out value) && !record.TryGetPrimitiveArray(out value) && !record.TryGetPrimitiveArrayList(out value) && !record.TryGetPrimitiveHashtable(out value) && !record.TryGetRectangleF(out value) && !record.TryGetPointF(out value))
return record.TryGetNotSupportedException(out value);
return true;
}
public static bool TryGetDrawingPrimitivesObject(this SerializationRecord record, [Nullable(2)] [NotNullWhen(true)] out object value)
{
if (!record.TryGetPoint(out value) && !record.TryGetSize(out value) && !record.TryGetSizeF(out value) && !record.TryGetRectangle(out value))
return record.TryGetColor(out value);
return true;
}
private static bool IsPrimitiveArrayRecord(SerializationRecord serializationRecord)
{
SerializationRecordType recordType = serializationRecord.get_RecordType();
if ((int)recordType != 15 && (int)recordType != 17)
return false;
return true;
}
[return: Nullable(0)]
internal static (bool isJsonData, bool isValidType) TryGetObjectFromJson<[Nullable(2)] T>(this SerializationRecord record, ITypeResolver resolver, [Nullable(2)] out T object)
{
object = default(T);
if (record.get_TypeName().AssemblyName?.FullName != "System.Private.Windows.VirtualJson")
return (false, false);
ClassRecord val = record as ClassRecord;
if (val != null) {
SZArrayRecord<byte> val2 = val.GetRawValue("<JsonBytes>k__BackingField") as SZArrayRecord<byte>;
if (val2 != null) {
string text = val.GetRawValue("<InnerTypeAssemblyQualifiedName>k__BackingField") as string;
if (text != null && TypeName.TryParse(text.AsSpan(), out TypeName result, null)) {
Type type = resolver.BindToType(result);
if (!type.IsAssignableTo(typeof(T)))
return (true, false);
if (type == typeof(object)) {
type = Type.GetType(text, false);
if ((object)type == null)
type = Type.GetType(result.FullName, true);
}
if ((object)type != null) {
Utf8JsonReader reader = new Utf8JsonReader(val2.GetArray(true), default(JsonReaderOptions));
object = (T)JsonSerializer.Deserialize(ref reader, type, (JsonSerializerOptions)null);
}
return (true, object != null);
}
}
}
throw new SerializationException(System.Private.Windows.Core.Resources.SR.ClipboardOrDragDrop_JsonDeserializationFailed);
}
}
}