68bee7ff617af875de4ed53df45fd0484bb021f6
[platform/upstream/dotnet/runtime.git] /
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information
4
5 namespace System.Runtime.Serialization
6 {
7     using System;
8     using System.Security;
9     using System.Security.Permissions;
10     using System.Runtime.CompilerServices;
11
12     internal sealed class SurrogateDataContract : DataContract
13     {
14         private SurrogateDataContractCriticalHelper _helper;
15
16         internal SurrogateDataContract(Type type, ISerializationSurrogate serializationSurrogate)
17             : base(new SurrogateDataContractCriticalHelper(type, serializationSurrogate))
18         {
19             _helper = base.Helper as SurrogateDataContractCriticalHelper;
20         }
21
22         internal ISerializationSurrogate SerializationSurrogate
23         {
24             get { return _helper.SerializationSurrogate; }
25         }
26
27         public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
28         {
29             SerializationInfo serInfo = new SerializationInfo(UnderlyingType, XmlObjectSerializer.FormatterConverter, !context.UnsafeTypeForwardingEnabled);
30             SerializationSurrogateGetObjectData(obj, serInfo, context.GetStreamingContext());
31             context.WriteSerializationInfo(xmlWriter, UnderlyingType, serInfo);
32         }
33
34         [MethodImpl(MethodImplOptions.NoInlining)]
35         private object SerializationSurrogateSetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
36         {
37             return SerializationSurrogate.SetObjectData(obj, serInfo, context, null);
38         }
39
40         [MethodImpl(MethodImplOptions.NoInlining)]
41         internal static object GetRealObject(IObjectReference obj, StreamingContext context)
42         {
43             return obj.GetRealObject(context);
44         }
45
46         [MethodImpl(MethodImplOptions.NoInlining)]
47         private object GetUninitializedObject(Type objType)
48         {
49             return FormatterServices.GetUninitializedObject(objType);
50         }
51
52         [MethodImpl(MethodImplOptions.NoInlining)]
53         private void SerializationSurrogateGetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
54         {
55             SerializationSurrogate.GetObjectData(obj, serInfo, context);
56         }
57
58         public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
59         {
60             xmlReader.Read();
61             Type objType = UnderlyingType;
62             object obj = objType.IsArray ? Array.CreateInstance(objType.GetElementType(), 0) : GetUninitializedObject(objType);
63             context.AddNewObject(obj);
64             string objectId = context.GetObjectId();
65             SerializationInfo serInfo = context.ReadSerializationInfo(xmlReader, objType);
66             object newObj = SerializationSurrogateSetObjectData(obj, serInfo, context.GetStreamingContext());
67             if (newObj == null)
68                 newObj = obj;
69             if (newObj is IDeserializationCallback)
70                 ((IDeserializationCallback)newObj).OnDeserialization(null);
71             if (newObj is IObjectReference)
72                 newObj = GetRealObject((IObjectReference)newObj, context.GetStreamingContext());
73             context.ReplaceDeserializedObject(objectId, obj, newObj);
74             xmlReader.ReadEndElement();
75             return newObj;
76         }
77
78         private class SurrogateDataContractCriticalHelper : DataContract.DataContractCriticalHelper
79         {
80             ISerializationSurrogate serializationSurrogate;
81
82             internal SurrogateDataContractCriticalHelper(Type type, ISerializationSurrogate serializationSurrogate)
83                 : base(type)
84             {
85                 this.serializationSurrogate = serializationSurrogate;
86                 string name, ns;
87                 DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(type), out name, out ns);
88                 SetDataContractName(CreateQualifiedName(name, ns));
89             }
90
91             internal ISerializationSurrogate SerializationSurrogate
92             {
93                 get { return serializationSurrogate; }
94             }
95         }
96     }
97 }