summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs')
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs210
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
}