diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2017-02-10 20:35:12 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2017-02-10 20:35:12 +0900 |
commit | 4b11dc566a5bbfa1378d6266525c281b028abcc8 (patch) | |
tree | b48831a898906734f8884d08b6e18f1144ee2b82 /src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs | |
parent | db20f3f1bb8595633a7e16c8900fd401a453a6b5 (diff) | |
download | coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.gz coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.tar.bz2 coreclr-4b11dc566a5bbfa1378d6266525c281b028abcc8.zip |
Imported Upstream version 1.0.0.9910upstream/1.0.0.9910
Diffstat (limited to 'src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs')
-rw-r--r-- | src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs | 210 |
1 files changed, 2 insertions, 208 deletions
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs index 585d367605..260e873bc7 100644 --- a/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs +++ b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; @@ -211,10 +211,7 @@ namespace System.Runtime.Serialization private StreamingContext m_streamingContext; private List<object> m_serializedStates = new List<object>(); - internal SafeSerializationEventArgs(StreamingContext streamingContext) - { - m_streamingContext = streamingContext; - } + internal SafeSerializationEventArgs() {} public void AddSerializedState(ISafeSerializationData serializedState) { @@ -226,11 +223,6 @@ namespace System.Runtime.Serialization m_serializedStates.Add(serializedState); } - internal IList<object> SerializedStates - { - get { return m_serializedStates; } - } - public StreamingContext StreamingContext { get { return m_streamingContext; } @@ -245,202 +237,4 @@ namespace System.Runtime.Serialization // this object. void CompleteDeserialization(object deserialized); } -#if FEATURE_SERIALIZATION - // Helper class to implement safe serialization. Concrete ISerializable types which want to allow - // transparent subclasses code to participate in serialization should contain an instance of - // SafeSerializationManager and wire up to it as described in code:#SafeSerialization. - [Serializable] - internal sealed class SafeSerializationManager : IObjectReference, ISerializable - { - // Saved states to store in the serialization stream. This is typed as object rather than - // ISafeSerializationData because ISafeSerializationData can't be marked serializable. - private IList<object> m_serializedStates; - - // This is the SerializationInfo that is used when the SafeSerializationManager type has replaced - // itself as the target of serialziation. It is not used directly by the safe serialization code, - // but just held onto so that the real object being deserialzed can use it later. - private SerializationInfo m_savedSerializationInfo; - - // Real object that we've deserialized - this is stored when we complete construction and calling - // the deserialization .ctors on it and is used when we need to notify the stored safe - // deserialization data that they should populate the object with their fields. - private object m_realObject; - - // Real type that should be deserialized - private RuntimeType m_realType; - - // Event fired when we need to collect state to serialize into the parent object - internal event EventHandler<SafeSerializationEventArgs> SerializeObjectState; - - // Name that is used to store the real type being deserialized in the main SerializationInfo - private const string RealTypeSerializationName = "CLR_SafeSerializationManager_RealType"; - - internal SafeSerializationManager() - { - } - - private SafeSerializationManager(SerializationInfo info, StreamingContext context) - { - // We need to determine if we're being called to really deserialize a SafeSerializationManager, - // or if we're being called because we've intercepted the deserialization callback for the real - // object being deserialized. We use the presence of the RealTypeSerializationName field in the - // serialization info to indicate that this is the interception callback and we just need to - // safe the info. If that field is not present, then we should be in a real deserialization - // construction. - RuntimeType realType = info.GetValueNoThrow(RealTypeSerializationName, typeof(RuntimeType)) as RuntimeType; - - if (realType == null) - { - m_serializedStates = info.GetValue("m_serializedStates", typeof(List<object>)) as List<object>; - } - else - { - m_realType = realType; - m_savedSerializationInfo = info; - } - } - - // Determine if the serialization manager is in an active state - that is if any code is hooked up - // to use it for serialization - internal bool IsActive - { - get { return SerializeObjectState != null; } - } - - // CompleteSerialization is called by the base ISerializable in its GetObjectData method. It is - // responsible for gathering up the serialized object state of any delegates that wish to add their - // own state to the serialized object. - internal void CompleteSerialization(object serializedObject, - SerializationInfo info, - StreamingContext context) - { - Contract.Requires(serializedObject != null); - Contract.Requires(info != null); - Contract.Requires(typeof(ISerializable).IsAssignableFrom(serializedObject.GetType())); - Contract.Requires(serializedObject.GetType().IsAssignableFrom(info.ObjectType)); - - // Clear out any stale state - m_serializedStates = null; - - // We only want to kick in our special serialization sauce if someone wants to participate in - // it, otherwise if we have no delegates registered there's no reason for us to get in the way - // of the regular serialization machinery. - EventHandler<SafeSerializationEventArgs> serializeObjectStateEvent = SerializeObjectState; - if (serializeObjectStateEvent != null) - { - // Get any extra data to add to our serialization state now - SafeSerializationEventArgs eventArgs = new SafeSerializationEventArgs(context); - serializeObjectStateEvent(serializedObject, eventArgs); - m_serializedStates = eventArgs.SerializedStates; - - // Replace the type to be deserialized by the standard serialization code paths with - // ourselves, which allows us to control the deserialization process. - info.AddValue(RealTypeSerializationName, serializedObject.GetType(), typeof(RuntimeType)); - info.SetType(typeof(SafeSerializationManager)); - } - } - - // CompleteDeserialization is called by the base ISerializable object's OnDeserialized handler to - // finish the deserialization of the object by notifying the saved states that they should - // re-populate their portions of the deserialized object. - internal void CompleteDeserialization(object deserializedObject) - { - Contract.Requires(deserializedObject != null); - - if (m_serializedStates != null) - { - foreach (ISafeSerializationData serializedState in m_serializedStates) - { - serializedState.CompleteDeserialization(deserializedObject); - } - } - } - - void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("m_serializedStates", m_serializedStates, typeof(List<IDeserializationCallback>)); - } - - // GetRealObject intercepts the deserialization process in order to allow deserializing part of the - // object's inheritance heirarchy using standard ISerializable constructors, and the remaining - // portion using the saved serialization states. - object IObjectReference.GetRealObject(StreamingContext context) - { - // If we've already deserialized the real object, use that rather than deserializing it again - if (m_realObject != null) - { - return m_realObject; - } - - // If we don't have a real type to deserialize, then this is really a SafeSerializationManager - // and we don't need to rebuild the object that we're standing in for. - if (m_realType == null) - { - return this; - } - - // Look for the last type in GetRealType's inheritance hierarchy which implements a critical - // deserialization constructor. This will be the object that we use as the deserialization - // construction type to initialize via standard ISerializable semantics - - // First build up the chain starting at the type below Object and working to the real type we - // serialized. - Stack inheritanceChain = new Stack(); - RuntimeType currentType = m_realType; - do - { - inheritanceChain.Push(currentType); - currentType = currentType.BaseType as RuntimeType; - } - while (currentType != typeof(object)); - - // Now look for the first type that does not implement the ISerializable .ctor. When we find - // that, previousType will point at the last type that did implement the .ctor. We require that - // the .ctor we invoke also be non-transparent - RuntimeConstructorInfo serializationCtor = null; - RuntimeType previousType = null; - do - { - previousType = currentType; - currentType = inheritanceChain.Pop() as RuntimeType; - serializationCtor = currentType.GetSerializationCtor(); - } - while (serializationCtor != null && serializationCtor.IsSecurityCritical); - - // previousType is the last type that did implement the deserialization .ctor before the first - // type that did not, so we'll grab it's .ctor to use for deserialization. - BCLDebug.Assert(previousType != null, "We should have at least one inheritance from the base type"); - serializationCtor = ObjectManager.GetConstructor(previousType); - - // Allocate an instance of the final type and run the selected .ctor on that instance to get the - // standard ISerializable initialization done. - object deserialized = FormatterServices.GetUninitializedObject(m_realType); - serializationCtor.SerializationInvoke(deserialized, m_savedSerializationInfo, context); - m_savedSerializationInfo = null; - m_realType = null; - - // Save away the real object that was deserialized so that we can fill it in later, and return - // it back as the object that should result from the final deserialization. - m_realObject = deserialized; - return deserialized; - } - - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - // We only need to complete deserialization if we were hooking the deserialization process. If - // we have not deserialized an object in the GetRealObject call, then there's nothing more for - // us to do here. - if (m_realObject != null) - { - // Fire the real object's OnDeserialized method if they registered one. Since we replaced - // ourselves as the target of the deserialization, OnDeserialized on the target won't - // automatically get triggered unless we do it manually. - SerializationEvents cache = SerializationEventsCache.GetSerializationEventsForType(m_realObject.GetType()); - cache.InvokeOnDeserialized(m_realObject, context); - m_realObject = null; - } - } - } -#endif } |