﻿// Decompiled with JetBrains decompiler
// Type: System.Runtime.Remoting.Messaging.RemotingSurrogateSelector
// Assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 255ABCDF-D9D6-4E3D-BAD4-F74D4CE3D7A8
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll

using System;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;

namespace System.Runtime.Remoting.Messaging
{
  /// <summary>
  /// Selects the remoting surrogate that can be used to serialize an object that derives from a <see cref="T:System.MarshalByRefObject"/>.
  /// </summary>
  [SecurityCritical]
  [ComVisible(true)]
  [SecurityPermission(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
  public class RemotingSurrogateSelector : ISurrogateSelector
  {
    private static Type s_IMethodCallMessageType = typeof (IMethodCallMessage);
    private static Type s_IMethodReturnMessageType = typeof (IMethodReturnMessage);
    private static Type s_ObjRefType = typeof (ObjRef);
    private RemotingSurrogate _remotingSurrogate = new RemotingSurrogate();
    private ObjRefSurrogate _objRefSurrogate = new ObjRefSurrogate();
    private object _rootObj;
    private ISurrogateSelector _next;
    private ISerializationSurrogate _messageSurrogate;
    private MessageSurrogateFilter _filter;

    /// <summary>
    /// Gets or sets the <see cref="T:System.Runtime.Remoting.Messaging.MessageSurrogateFilter"/> delegate for the current instance of the <see cref="T:System.Runtime.Remoting.Messaging.RemotingSurrogateSelector"/>.
    /// </summary>
    /// 
    /// <returns>
    /// The <see cref="T:System.Runtime.Remoting.Messaging.MessageSurrogateFilter"/> delegate for the current instance of the <see cref="T:System.Runtime.Remoting.Messaging.RemotingSurrogateSelector"/>.
    /// </returns>
    /// <PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Infrastructure"/></PermissionSet>
    public MessageSurrogateFilter Filter
    {
      [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
      {
        return this._filter;
      }
      [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] set
      {
        this._filter = value;
      }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Runtime.Remoting.Messaging.RemotingSurrogateSelector"/> class.
    /// </summary>
    public RemotingSurrogateSelector()
    {
      this._messageSurrogate = (ISerializationSurrogate) new MessageSurrogate(this);
    }

    /// <summary>
    /// Sets the object at the root of the object graph.
    /// </summary>
    /// <param name="obj">The object at the root of the object graph. </param><exception cref="T:System.ArgumentNullException">The <paramref name="obj"/> parameter is null. </exception><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Infrastructure"/></PermissionSet>
    public void SetRootObject(object obj)
    {
      if (obj == null)
        throw new ArgumentNullException("obj");
      this._rootObj = obj;
      SoapMessageSurrogate messageSurrogate = this._messageSurrogate as SoapMessageSurrogate;
      if (messageSurrogate == null)
        return;
      messageSurrogate.SetRootObject(this._rootObj);
    }

    /// <summary>
    /// Returns the object at the root of the object graph.
    /// </summary>
    /// 
    /// <returns>
    /// The object at the root of the object graph.
    /// </returns>
    /// <PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Infrastructure"/></PermissionSet>
    public object GetRootObject()
    {
      return this._rootObj;
    }

    /// <summary>
    /// Adds the specified <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> to the surrogate selector chain.
    /// </summary>
    /// <param name="selector">The next <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> to examine. </param>
    [SecurityCritical]
    public virtual void ChainSelector(ISurrogateSelector selector)
    {
      this._next = selector;
    }

    /// <summary>
    /// Returns the appropriate surrogate for the given type in the given context.
    /// </summary>
    /// 
    /// <returns>
    /// The appropriate surrogate for the given type in the given context.
    /// </returns>
    /// <param name="type">The <see cref="T:System.Type"/> for which the surrogate is requested. </param><param name="context">The source or destination of serialization. </param><param name="ssout">When this method returns, contains an <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> that is appropriate for the specified object type. This parameter is passed uninitialized. </param><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter, Infrastructure"/></PermissionSet>
    [SecurityCritical]
    public virtual ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector ssout)
    {
      if (type == (Type) null)
        throw new ArgumentNullException("type");
      if (type.IsMarshalByRef)
      {
        ssout = (ISurrogateSelector) this;
        return (ISerializationSurrogate) this._remotingSurrogate;
      }
      if (RemotingSurrogateSelector.s_IMethodCallMessageType.IsAssignableFrom(type) || RemotingSurrogateSelector.s_IMethodReturnMessageType.IsAssignableFrom(type))
      {
        ssout = (ISurrogateSelector) this;
        return this._messageSurrogate;
      }
      if (RemotingSurrogateSelector.s_ObjRefType.IsAssignableFrom(type))
      {
        ssout = (ISurrogateSelector) this;
        return (ISerializationSurrogate) this._objRefSurrogate;
      }
      if (this._next != null)
        return this._next.GetSurrogate(type, context, out ssout);
      ssout = (ISurrogateSelector) null;
      return (ISerializationSurrogate) null;
    }

    /// <summary>
    /// Returns the next <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> in the chain of surrogate selectors.
    /// </summary>
    /// 
    /// <returns>
    /// The next <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> in the chain of surrogate selectors.
    /// </returns>
    [SecurityCritical]
    public virtual ISurrogateSelector GetNextSelector()
    {
      return this._next;
    }

    /// <summary>
    /// Sets up the current surrogate selector to use the SOAP format.
    /// </summary>
    /// <PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Infrastructure"/></PermissionSet>
    public virtual void UseSoapFormat()
    {
      this._messageSurrogate = (ISerializationSurrogate) new SoapMessageSurrogate(this);
      ((SoapMessageSurrogate) this._messageSurrogate).SetRootObject(this._rootObj);
    }
  }
}
