<PackageReference Include="System.Drawing.Common" Version="10.0.0-preview.3.25173.2" />

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); } } }