Files
NetDataContractSerializer/Compat.Private.Serialization/Compat/Runtime/Serialization/SurrogateDataContract.cs
2019-08-29 23:24:07 +03:00

95 lines
3.9 KiB
C#

using System;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace Compat.Runtime.Serialization
{
internal sealed class SurrogateDataContract : DataContract
{
private readonly SurrogateDataContractCriticalHelper _helper;
internal SurrogateDataContract(Type type, ISerializationSurrogate serializationSurrogate)
: base(new SurrogateDataContractCriticalHelper(type, serializationSurrogate))
{
_helper = base.Helper as SurrogateDataContractCriticalHelper;
}
internal ISerializationSurrogate SerializationSurrogate => _helper.SerializationSurrogate;
public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
{
SerializationInfo serInfo = new SerializationInfo(UnderlyingType, XmlObjectSerializer.FormatterConverter, !context.UnsafeTypeForwardingEnabled);
SerializationSurrogateGetObjectData(obj, serInfo, context.GetStreamingContext());
context.WriteSerializationInfo(xmlWriter, UnderlyingType, serInfo);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private object SerializationSurrogateSetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
{
return SerializationSurrogate.SetObjectData(obj, serInfo, context, null);
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static object GetRealObject(IObjectReference obj, StreamingContext context)
{
return obj.GetRealObject(context);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private object GetUninitializedObject(Type objType)
{
return FormatterServices.GetUninitializedObject(objType);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void SerializationSurrogateGetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
{
SerializationSurrogate.GetObjectData(obj, serInfo, context);
}
public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
{
xmlReader.Read();
Type objType = UnderlyingType;
object obj = objType.IsArray ? Array.CreateInstance(objType.GetElementType(), 0) : GetUninitializedObject(objType);
context.AddNewObject(obj);
string objectId = context.GetObjectId();
SerializationInfo serInfo = context.ReadSerializationInfo(xmlReader, objType);
object newObj = SerializationSurrogateSetObjectData(obj, serInfo, context.GetStreamingContext());
if (newObj == null)
{
newObj = obj;
}
if (newObj is IDeserializationCallback)
{
((IDeserializationCallback)newObj).OnDeserialization(null);
}
if (newObj is IObjectReference)
{
newObj = GetRealObject((IObjectReference)newObj, context.GetStreamingContext());
}
context.ReplaceDeserializedObject(objectId, obj, newObj);
xmlReader.ReadEndElement();
return newObj;
}
private class SurrogateDataContractCriticalHelper : DataContract.DataContractCriticalHelper
{
private readonly ISerializationSurrogate _serializationSurrogate;
internal SurrogateDataContractCriticalHelper(Type type, ISerializationSurrogate serializationSurrogate)
: base(type)
{
_serializationSurrogate = serializationSurrogate;
DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(type), out string name, out string ns);
SetDataContractName(CreateQualifiedName(name, ns));
}
internal ISerializationSurrogate SerializationSurrogate => _serializationSurrogate;
}
}
}