4 // Dick Porter (dick@ximian.com)
5 // Lluis Sanchez Gual (lluis@ideary.com)
7 // (C) 2002 Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Reflection;
31 using System.Collections;
33 using System.Runtime.Remoting.Messaging;
34 using System.Security.Permissions;
36 namespace System.Runtime.Serialization.Formatters.Binary {
38 public sealed class BinaryFormatter : IRemotingFormatter, IFormatter
40 private FormatterAssemblyStyle assembly_format = FormatterAssemblyStyle.Full;
41 private SerializationBinder binder;
42 private StreamingContext context;
43 private ISurrogateSelector surrogate_selector;
44 private FormatterTypeStyle type_format = FormatterTypeStyle.TypesAlways;
47 private TypeFilterLevel filter_level;
50 public BinaryFormatter()
52 surrogate_selector=null;
53 context=new StreamingContext(StreamingContextStates.All);
56 public BinaryFormatter(ISurrogateSelector selector, StreamingContext context)
58 surrogate_selector=selector;
62 public FormatterAssemblyStyle AssemblyFormat
65 return(assembly_format);
68 assembly_format=value;
72 public SerializationBinder Binder
82 public StreamingContext Context
92 public ISurrogateSelector SurrogateSelector
95 return(surrogate_selector);
98 surrogate_selector=value;
102 public FormatterTypeStyle TypeFormat
113 [System.Runtime.InteropServices.ComVisible (false)]
114 public TypeFilterLevel FilterLevel
116 get { return filter_level; }
117 set { filter_level = value; }
121 public object Deserialize(Stream serializationStream)
123 return Deserialize (serializationStream, null);
126 public object Deserialize(Stream serializationStream, HeaderHandler handler)
128 if(serializationStream==null)
\r
130 throw new ArgumentNullException("serializationStream is null");
132 if(serializationStream.CanSeek &&
133 serializationStream.Length==0)
\r
135 throw new SerializationException("serializationStream supports seeking, but its length is 0");
138 BinaryReader reader = new BinaryReader (serializationStream);
141 ReadBinaryHeader (reader, out hasHeader);
143 // Messages are read using a special static method, which does not use ObjectReader
144 // if it is not needed. This saves time and memory.
146 BinaryElement elem = (BinaryElement) reader.PeekChar();
148 if (elem == BinaryElement.MethodCall) {
149 return MessageFormatter.ReadMethodCall (reader, hasHeader, handler, this);
151 else if (elem == BinaryElement.MethodResponse) {
152 return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, null, this);
155 ObjectReader serializer = new ObjectReader (this);
159 serializer.ReadObjectGraph (reader, hasHeader, out result, out headers);
160 if (handler != null) handler(headers);
165 public object DeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallmessage)
167 if(serializationStream==null) {
168 throw new ArgumentNullException("serializationStream is null");
170 if(serializationStream.CanSeek &&
171 serializationStream.Length==0) {
172 throw new SerializationException("serializationStream supports seeking, but its length is 0");
175 BinaryReader reader = new BinaryReader (serializationStream);
178 ReadBinaryHeader (reader, out hasHeader);
179 return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, methodCallmessage, this);
182 public void Serialize(Stream serializationStream, object graph)
184 Serialize (serializationStream, graph, null);
187 [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)]
188 public void Serialize(Stream serializationStream, object graph, Header[] headers)
190 if(serializationStream==null) {
191 throw new ArgumentNullException ("serializationStream");
194 BinaryWriter writer = new BinaryWriter (serializationStream);
195 WriteBinaryHeader (writer, headers!=null);
\r
197 if (graph is IMethodCallMessage) {
\r
198 MessageFormatter.WriteMethodCall (writer, graph, headers, surrogate_selector, context, assembly_format, type_format);
\r
200 else if (graph is IMethodReturnMessage) {
\r
201 MessageFormatter.WriteMethodResponse (writer, graph, headers, surrogate_selector, context, assembly_format, type_format);
\r
204 ObjectWriter serializer = new ObjectWriter (surrogate_selector, context, assembly_format, type_format);
205 serializer.WriteObjectGraph (writer, graph, headers);
211 [System.Runtime.InteropServices.ComVisible (false)]
212 public object UnsafeDeserialize(Stream serializationStream, HeaderHandler handler)
214 throw new NotImplementedException ();
218 [System.Runtime.InteropServices.ComVisible (false)]
219 public object UnsafeDeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallmessage)
221 throw new NotImplementedException ();
224 private void WriteBinaryHeader (BinaryWriter writer, bool hasHeaders)
\r
226 writer.Write ((byte)BinaryElement.Header);
\r
227 writer.Write ((int)1);
\r
228 if (hasHeaders) writer.Write ((int)2);
\r
229 else writer.Write ((int)-1);
\r
230 writer.Write ((int)1);
\r
231 writer.Write ((int)0);
\r
234 private void ReadBinaryHeader (BinaryReader reader, out bool hasHeaders)
\r
237 reader.ReadInt32();
\r
238 int val = reader.ReadInt32();
\r
239 hasHeaders = (val==2);
\r
240 reader.ReadInt32();
\r
241 reader.ReadInt32();
\r