//
// Author:
// Dick Porter (dick@ximian.com)
+// Lluis Sanchez Gual (lluis@ideary.com)
//
// (C) 2002 Ximian, Inc. http://www.ximian.com
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
namespace System.Runtime.Serialization.Formatters.Binary {
+
public sealed class BinaryFormatter : IRemotingFormatter, IFormatter
{
- private FormatterAssemblyStyle assembly_format;
+ private FormatterAssemblyStyle assembly_format = FormatterAssemblyStyle.Full;
private SerializationBinder binder;
private StreamingContext context;
private ISurrogateSelector surrogate_selector;
- private FormatterTypeStyle type_format;
+ private FormatterTypeStyle type_format; // TODO: Do something with this
+
+#if NET_1_1
+ private TypeFilterLevel filter_level;
+#endif
public BinaryFormatter()
{
}
}
- [MonoTODO]
+#if NET_1_1
+ [System.Runtime.InteropServices.ComVisible (false)]
+ public TypeFilterLevel FilterLevel
+ {
+ get { return filter_level; }
+ set { filter_level = value; }
+ }
+#endif
+
public object Deserialize(Stream serializationStream)
{
- if(serializationStream==null) {
- throw new ArgumentNullException("serializationStream is null");
- }
- if(serializationStream.CanSeek &&
- serializationStream.Length==0) {
- throw new SerializationException("serializationStream supports seeking, but its length is 0");
- }
-
- return(null);
+ return Deserialize (serializationStream, null);
}
- [MonoTODO]
public object Deserialize(Stream serializationStream, HeaderHandler handler)
{
- if(serializationStream==null) {
+ if(serializationStream==null) \r
+ {
throw new ArgumentNullException("serializationStream is null");
}
if(serializationStream.CanSeek &&
- serializationStream.Length==0) {
+ serializationStream.Length==0) \r
+ {
throw new SerializationException("serializationStream supports seeking, but its length is 0");
}
-
- return(null);
+
+ BinaryReader reader = new BinaryReader (serializationStream);
+
+ bool hasHeader;
+ ReadBinaryHeader (reader, out hasHeader);
+
+ // Messages are read using a special static method, which does not use ObjectReader
+ // if it is not needed. This saves time and memory.
+
+ BinaryElement elem = (BinaryElement) reader.PeekChar();
+
+ if (elem == BinaryElement.MethodCall) {
+ return MessageFormatter.ReadMethodCall (reader, hasHeader, handler, this);
+ }
+ else if (elem == BinaryElement.MethodResponse) {
+ return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, null, this);
+ }
+ else {
+ ObjectReader serializer = new ObjectReader (this);
+
+ object result;
+ Header[] headers;
+ serializer.ReadObjectGraph (reader, hasHeader, out result, out headers);
+ if (handler != null) handler(headers);
+ return result;
+ }
}
- [MonoTODO]
public object DeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallmessage)
{
if(serializationStream==null) {
serializationStream.Length==0) {
throw new SerializationException("serializationStream supports seeking, but its length is 0");
}
-
- return(null);
+
+ BinaryReader reader = new BinaryReader (serializationStream);
+
+ bool hasHeader;
+ ReadBinaryHeader (reader, out hasHeader);
+ return MessageFormatter.ReadMethodResponse (reader, hasHeader, handler, methodCallmessage, this);
}
- [MonoTODO]
public void Serialize(Stream serializationStream, object graph)
{
- if(serializationStream==null) {
- throw new ArgumentNullException("serializationStream is null");
- }
-
- ISerializable ser = graph as ISerializable;
-
- StreamingContext context = new StreamingContext (StreamingContextStates.Remoting);
- object [] oa;
-
- if (ser != null) {
- SerializationInfo info = new SerializationInfo (graph.GetType (), new FormatterConverter ());
- ser.GetObjectData (info, context);
- SerializationInfoEnumerator e = info.GetEnumerator ();
- oa = new object [info.MemberCount];
- int i = 0;
- while (e.MoveNext ()) {
- oa [i++] = e.Current;
- }
- Console.WriteLine ("SERIALIZABLE" + info.MemberCount);
- } else {
- MemberInfo [] members = FormatterServices.GetSerializableMembers (graph.GetType (), context);
- oa = FormatterServices.GetObjectData (graph, members);
- Console.WriteLine ("NOT SERIALIZABLE" + oa.Length);
- }
-
- foreach (object o in oa) {
- Console.WriteLine ("OBJ" + o);
- }
-
- throw new NotImplementedException ();
+ Serialize (serializationStream, graph, null);
}
- [MonoTODO]
public void Serialize(Stream serializationStream, object graph, Header[] headers)
{
if(serializationStream==null) {
throw new ArgumentNullException("serializationStream is null");
}
- // fixme: what about headers?
- Serialize (serializationStream, graph);
+ BinaryWriter writer = new BinaryWriter (serializationStream);
+ WriteBinaryHeader (writer, headers!=null);\r
+\r
+ if (graph is IMethodCallMessage) {\r
+ MessageFormatter.WriteMethodCall (writer, graph, headers, surrogate_selector, context, assembly_format);\r
+ }\r
+ else if (graph is IMethodReturnMessage) {\r
+ MessageFormatter.WriteMethodResponse (writer, graph, headers, surrogate_selector, context, assembly_format);\r
+ }\r
+ else {\r
+ ObjectWriter serializer = new ObjectWriter (surrogate_selector, context, assembly_format);
+ serializer.WriteObjectGraph (writer, graph, headers);
+ }
+ writer.Flush();
+ }
+\r
+ [MonoTODO]
+ [System.Runtime.InteropServices.ComVisible (false)]
+ public object UnsafeDeserialize(Stream serializationStream, HeaderHandler handler)
+ {
+ throw new NotImplementedException ();
}
+
+ [MonoTODO]
+ [System.Runtime.InteropServices.ComVisible (false)]
+ public object UnsafeDeserializeMethodResponse(Stream serializationStream, HeaderHandler handler, IMethodCallMessage methodCallmessage)
+ {
+ throw new NotImplementedException ();
+ }
+
+ private void WriteBinaryHeader (BinaryWriter writer, bool hasHeaders)\r
+ {\r
+ writer.Write ((byte)BinaryElement.Header);\r
+ writer.Write ((int)1);\r
+ if (hasHeaders) writer.Write ((int)2);\r
+ else writer.Write ((int)-1);\r
+ writer.Write ((int)1);\r
+ writer.Write ((int)0);\r
+ }\r
+\r
+ private void ReadBinaryHeader (BinaryReader reader, out bool hasHeaders)\r
+ {\r
+ reader.ReadByte();\r
+ reader.ReadInt32();\r
+ int val = reader.ReadInt32();\r
+ hasHeaders = (val==2);\r
+ reader.ReadInt32();\r
+ reader.ReadInt32();\r
+ }\r
}
}