Handle relocatable libMonoPosixHelper.so when --libdir= isn't lib/
[mono.git] / mcs / class / referencesource / mscorlib / system / runtime / serialization / formatters / binary / binaryformatter.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*============================================================
7  **
8  ** Class: BinaryFormatter
9  **
10  **
11  ** Purpose: Soap XML Formatter
12  **
13  **
14  ===========================================================*/
15
16 namespace System.Runtime.Serialization.Formatters.Binary {
17
18     using System;
19     using System.IO;
20     using System.Reflection;
21     using System.Globalization;
22     using System.Collections;
23     using System.Collections.Generic;
24     using System.Runtime.Serialization.Formatters;
25 #if FEATURE_REMOTING    
26     using System.Runtime.Remoting.Proxies;
27 #endif
28     using System.Runtime.Remoting;
29     using System.Runtime.Remoting.Messaging;
30
31     using System.Runtime.Serialization;
32     using System.Security.Permissions;
33     using System.Diagnostics.Contracts;
34     
35     [System.Runtime.InteropServices.ComVisible(true)]
36     sealed public class BinaryFormatter :
37 #if !FEATURE_REMOTING
38         IFormatter
39 #else
40         IRemotingFormatter 
41 #endif
42     {
43
44         internal ISurrogateSelector m_surrogates;
45         internal StreamingContext m_context;
46         internal SerializationBinder m_binder;
47         //internal FormatterTypeStyle m_typeFormat = FormatterTypeStyle.TypesWhenNeeded;
48         internal FormatterTypeStyle m_typeFormat = FormatterTypeStyle.TypesAlways; // For version resiliency, always put out types
49         internal FormatterAssemblyStyle m_assemblyFormat = FormatterAssemblyStyle.Simple;
50         internal TypeFilterLevel m_securityLevel = TypeFilterLevel.Full;
51         internal Object[] m_crossAppDomainArray = null;
52         private static Dictionary<Type, TypeInformation> typeNameCache = new Dictionary<Type, TypeInformation>();
53
54         // Property which specifies how types are serialized,
55         // FormatterTypeStyle Enum specifies options
56         public FormatterTypeStyle TypeFormat
57         {
58             get { return m_typeFormat; }
59             set { m_typeFormat = value; }
60         }
61
62         // Property which specifies how types are serialized,
63         // FormatterAssemblyStyle Enum specifies options
64         public FormatterAssemblyStyle AssemblyFormat
65         {
66             get { return m_assemblyFormat; }
67             set { m_assemblyFormat = value; }
68         }
69
70         // Property which specifies the security level of formatter
71         // TypeFilterLevel Enum specifies options
72         public TypeFilterLevel FilterLevel
73         {
74             get { return m_securityLevel; }
75             set { m_securityLevel = value; }
76         }
77
78         public ISurrogateSelector SurrogateSelector {
79             get { return m_surrogates; }
80             set { m_surrogates = value; }
81         }
82
83         public SerializationBinder Binder {
84             get { return m_binder; }
85             set { m_binder = value; }
86         }
87
88         public StreamingContext Context {
89             get { return m_context; }
90             set { m_context = value; }
91         }
92
93         // Constructor
94         public BinaryFormatter()
95         {
96             m_surrogates = null;
97             m_context = new StreamingContext(StreamingContextStates.All);
98         }
99
100         // Constructor
101         public BinaryFormatter(ISurrogateSelector selector, StreamingContext context) {
102             m_surrogates = selector;
103             m_context = context;
104         }
105
106
107
108         // Deserialize the stream into an object graph.
109         public Object Deserialize(Stream serializationStream)
110         {
111             return Deserialize(serializationStream, null);
112         }
113
114         [System.Security.SecurityCritical]  // auto-generated
115         internal Object Deserialize(Stream serializationStream, HeaderHandler handler, bool fCheck)
116         {
117 #if FEATURE_REMOTING        
118             return Deserialize(serializationStream, handler, fCheck, null);
119 #else
120             if (serializationStream == null)
121             {
122                 throw new ArgumentNullException("serializationStream", Environment.GetResourceString("ArgumentNull_WithParamName", serializationStream));
123             }
124             Contract.EndContractBlock();
125
126             if (serializationStream.CanSeek && (serializationStream.Length == 0))
127                 throw new SerializationException(Environment.GetResourceString("Serialization_Stream"));
128
129             SerTrace.Log(this, "Deserialize Entry");
130             InternalFE formatterEnums = new InternalFE();
131             formatterEnums.FEtypeFormat = m_typeFormat;
132             formatterEnums.FEserializerTypeEnum = InternalSerializerTypeE.Binary;
133             formatterEnums.FEassemblyFormat = m_assemblyFormat;
134             formatterEnums.FEsecurityLevel = m_securityLevel;
135
136             ObjectReader sor = new ObjectReader(serializationStream, m_surrogates, m_context, formatterEnums, m_binder);
137             sor.crossAppDomainArray = m_crossAppDomainArray;
138             return sor.Deserialize(handler, new __BinaryParser(serializationStream, sor), fCheck);
139
140 #endif
141
142         }
143
144
145
146         // Deserialize the stream into an object graph.
147         [System.Security.SecuritySafeCritical]  // auto-generated
148         public Object Deserialize(Stream serializationStream, HeaderHandler handler) {
149             return Deserialize(serializationStream, handler, true);
150         }
151
152 #if FEATURE_REMOTING || MOBILE_LEGACY
153         [System.Security.SecuritySafeCritical]  // auto-generated
154         public Object DeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallMessage) {
155             return Deserialize(serializationStream, handler, true, methodCallMessage);
156         }
157 #endif
158         [System.Security.SecurityCritical]  // auto-generated_required
159         [System.Runtime.InteropServices.ComVisible(false)]
160         public Object UnsafeDeserialize(Stream serializationStream, HeaderHandler handler) {
161             return Deserialize(serializationStream, handler, false);
162         }
163
164 #if FEATURE_REMOTING || MOBILE_LEGACY
165         [System.Security.SecurityCritical]  // auto-generated_required
166         [System.Runtime.InteropServices.ComVisible(false)]
167         public Object UnsafeDeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallMessage) {
168             return Deserialize(serializationStream, handler, false, methodCallMessage);
169         }         
170
171         [System.Security.SecurityCritical]  // auto-generated
172         internal Object Deserialize(Stream serializationStream, HeaderHandler handler, bool fCheck, IMethodCallMessage methodCallMessage) {
173             return Deserialize(serializationStream, handler, fCheck, false/*isCrossAppDomain*/, methodCallMessage);
174         }
175
176         // Deserialize the stream into an object graph.
177         [System.Security.SecurityCritical]  // auto-generated
178         internal Object Deserialize(Stream serializationStream, HeaderHandler handler, bool fCheck, bool isCrossAppDomain, IMethodCallMessage methodCallMessage) {
179             if (serializationStream==null)
180             {
181                 throw new ArgumentNullException("serializationStream", Environment.GetResourceString("ArgumentNull_WithParamName",serializationStream));
182             }
183             Contract.EndContractBlock();
184
185             if (serializationStream.CanSeek && (serializationStream.Length == 0))
186                 throw new SerializationException(Environment.GetResourceString("Serialization_Stream"));
187
188             SerTrace.Log(this, "Deserialize Entry");
189             InternalFE formatterEnums = new InternalFE();
190             formatterEnums.FEtypeFormat = m_typeFormat;
191             formatterEnums.FEserializerTypeEnum = InternalSerializerTypeE.Binary;
192             formatterEnums.FEassemblyFormat = m_assemblyFormat;         
193             formatterEnums.FEsecurityLevel = m_securityLevel;            
194
195                ObjectReader sor = new ObjectReader(serializationStream, m_surrogates, m_context, formatterEnums, m_binder);
196             sor.crossAppDomainArray = m_crossAppDomainArray;
197             return sor.Deserialize(handler, new __BinaryParser(serializationStream, sor), fCheck, isCrossAppDomain, methodCallMessage);
198     }
199 #endif // FEATURE_REMOTING
200
201         public void Serialize(Stream serializationStream, Object graph)
202         {
203             Serialize(serializationStream, graph, null);
204         }
205
206         // Commences the process of serializing the entire graph.  All of the data (in the appropriate format
207         // is emitted onto the stream).
208         [System.Security.SecuritySafeCritical]  // auto-generated
209         public void Serialize(Stream serializationStream, Object graph, Header[] headers)
210         {
211             Serialize(serializationStream, graph, headers, true);
212         }
213
214         // Commences the process of serializing the entire graph.  All of the data (in the appropriate format
215         // is emitted onto the stream).
216         [System.Security.SecurityCritical]  // auto-generated
217         internal void Serialize(Stream serializationStream, Object graph, Header[] headers, bool fCheck)
218         {
219             if (serializationStream == null)
220             {
221                 throw new ArgumentNullException("serializationStream", Environment.GetResourceString("ArgumentNull_WithParamName", serializationStream));
222             }
223             Contract.EndContractBlock();
224             SerTrace.Log(this, "Serialize Entry");
225
226             InternalFE formatterEnums = new InternalFE();
227             formatterEnums.FEtypeFormat = m_typeFormat;
228             formatterEnums.FEserializerTypeEnum = InternalSerializerTypeE.Binary;
229             formatterEnums.FEassemblyFormat = m_assemblyFormat;
230
231             ObjectWriter sow = new ObjectWriter(m_surrogates, m_context, formatterEnums, m_binder);
232             __BinaryWriter binaryWriter = new __BinaryWriter(serializationStream, sow, m_typeFormat);
233             sow.Serialize(graph, headers, binaryWriter, fCheck);
234             m_crossAppDomainArray = sow.crossAppDomainArray;
235         }
236
237         internal static TypeInformation GetTypeInformation(Type type)
238         {
239             lock (typeNameCache)
240             {
241                 TypeInformation typeInformation = null;
242                 if (!typeNameCache.TryGetValue(type, out typeInformation))
243                 {
244                     bool hasTypeForwardedFrom;
245                     string assemblyName = FormatterServices.GetClrAssemblyName(type, out hasTypeForwardedFrom);
246                     typeInformation = new TypeInformation(FormatterServices.GetClrTypeFullName(type), assemblyName, hasTypeForwardedFrom);
247                     typeNameCache.Add(type, typeInformation);
248                 }
249                 return typeInformation;
250             }
251         }
252     }
253 }