BinaryFormatUtilities<TNrbfSerializer>
using System.Diagnostics.CodeAnalysis;
using System.Formats.Nrbf;
using System.IO;
using System.Private.Windows.BinaryFormat;
using System.Private.Windows.Core.Resources;
using System.Private.Windows.Nrbf;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
namespace System.Private.Windows.Ole
{
internal static class BinaryFormatUtilities<TNrbfSerializer> where TNrbfSerializer : INrbfSerializer
{
[NullableContext(1)]
internal static void WriteObjectToStream(MemoryStream stream, object data, string format)
{
long position = stream.Position;
try {
if (((INrbfSerializer)).TryWriteObject((Stream)stream, data))
return;
} catch (Exception ex) when (!ex.IsCriticalException()) {
}
if (!FeatureSwitches.EnableUnsafeBinaryFormatterSerialization)
throw new NotSupportedException(System.Private.Windows.Core.Resources.SR.BinaryFormatterNotSupported);
if (!CoreAppContextSwitches.ClipboardDragDropEnableUnsafeBinaryFormatterSerialization)
throw new NotSupportedException(System.Private.Windows.Core.Resources.SR.BinaryFormatter_NotSupported_InClipboardOrDragDrop);
if (DataFormatNames.IsPredefinedFormat(format))
throw new RestrictedTypeDeserializationException(System.Private.Windows.Core.Resources.SR.UnexpectedClipboardType);
stream.Position = position;
new BinaryFormatter().Serialize(stream, data);
}
[NullableContext(2)]
internal static bool TryReadObjectFromStream<T>([Nullable(1)] MemoryStream stream, [In] [RequiresLocation] ref DataRequest request, [NotNullWhen(true)] out T object)
{
object = default(T);
if (typeof(T) == typeof(MemoryStream)) {
object = (T)(object)stream;
return true;
}
long position = stream.Position;
SerializationRecord val = null;
try {
val = stream.DecodeNrbf();
if (typeof(T) == typeof(SerializationRecord)) {
object = (T)(object)val;
return true;
}
} catch (NotSupportedException) {
} finally {
stream.Position = position;
}
TypeBinder<TNrbfSerializer> typeBinder = new TypeBinder<TNrbfSerializer>(typeof(T), ref request);
object value;
if (val != null) {
TypeName typeName = val.get_TypeName();
if (((INrbfSerializer)).TryBindToType(typeName, out Type type)) {
if (request.TypedRequest && !(type == typeof(T)) && !typeBinder.BindToType(val.get_TypeName()).IsAssignableTo(typeof(T)))
return false;
if (((INrbfSerializer)).TryGetObject(val, out value)) {
object = (T)value;
return true;
}
Type type2 = type;
if (((INrbfSerializer)).IsFullySupportedType(type2))
return false;
}
if ((object)type == null) {
(bool isJsonData, bool isValidType) valueTuple = SerializationRecordExtensions.TryGetObjectFromJson<T>(val, (ITypeResolver)typeBinder, out object);
bool item = valueTuple.isJsonData;
bool item2 = valueTuple.isValidType;
if (item)
return item2;
}
if (request.TypedRequest && !TypeExtensions.Matches(typeof(T), val.get_TypeName(), TypeNameComparison.AllButAssemblyVersion) && !typeBinder.BindToType(val.get_TypeName()).IsAssignableTo(typeof(T)))
return false;
}
if (request.TypedRequest && request.Resolver == null)
throw new NotSupportedException(string.Format(System.Private.Windows.Core.Resources.SR.ClipboardOrDragDrop_UseTypedAPI, typeof(T).FullName));
if (!FeatureSwitches.EnableUnsafeBinaryFormatterSerialization)
throw new NotSupportedException(System.Private.Windows.Core.Resources.SR.BinaryFormatterNotSupported);
if (!CoreAppContextSwitches.ClipboardDragDropEnableUnsafeBinaryFormatterSerialization)
throw new NotSupportedException(System.Private.Windows.Core.Resources.SR.BinaryFormatter_NotSupported_InClipboardOrDragDrop);
if (DataFormatNames.IsPredefinedFormat(request.Format))
throw new RestrictedTypeDeserializationException(System.Private.Windows.Core.Resources.SR.UnexpectedClipboardType);
if (typeBinder == null)
typeBinder = new TypeBinder<TNrbfSerializer>(typeof(T), ref request);
try {
value = new BinaryFormatter {
Binder = typeBinder,
AssemblyFormat = FormatterAssemblyStyle.Simple
}.Deserialize(stream);
} catch (SerializationException ex2) when () {
NotSupportedException ex3;
throw ex3;
} finally {
stream.Position = position;
}
if (value is T) {
T val2 = object = (T)value;
return true;
}
return false;
}
}
}