* TcpClientChannel.cs: Fixed constructor.
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels / BinaryClientFormatterSink.cs
index 88e096b5eef6442e646a61e3aedc72c1209e4b22..94e3845c260a721bdbc6fe3e893111a265c0fa19 100644 (file)
@@ -2,6 +2,8 @@
 // System.Runtime.Remoting.Channels.BinaryClientFormatterSink.cs
 //
 // Author: Rodrigo Moya (rodrigo@ximian.com)
+//         Dietmar Maurer (dietmar@ximian.com)
+//         Lluis Sanchez Gual (lluis@ideary.com)
 //
 // 2002 (C) Copyright, Ximian, Inc.
 //
 using System.Collections;
 using System.IO;
 using System.Runtime.Remoting.Messaging;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 
 namespace System.Runtime.Remoting.Channels
 {
        public class BinaryClientFormatterSink : IClientFormatterSink,
                IMessageSink, IClientChannelSink, IChannelSinkBase
        {
-               private IClientChannelSink nextInChain;
+               static BinaryFormatter _serializationFormatter;
+               static BinaryFormatter _deserializationFormatter;
+
+               IClientChannelSink nextInChain;
+
+               static BinaryClientFormatterSink ()
+               {
+                       RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector ();
+                       StreamingContext context = new StreamingContext(StreamingContextStates.Remoting, null);
+
+                       _serializationFormatter = new BinaryFormatter (surrogateSelector, context);
+                       _deserializationFormatter = new BinaryFormatter (null, context);
+               }
+
                
                public BinaryClientFormatterSink (IClientChannelSink nextSink)
                {
@@ -31,62 +48,106 @@ namespace System.Runtime.Remoting.Channels
 
                public IMessageSink NextSink
                {
-                       [MonoTODO]
-                               get { throw new NotImplementedException (); }
+                       get {
+                               // This is the last sink in the IMessageSink sink chain
+                               return null;
+                       }
                }
 
                public IDictionary Properties
                {
-                       [MonoTODO]
-                               get { throw new NotImplementedException (); }
-               }
-
-               [MonoTODO]
-               public IMessageCtrl AsyncProcessMessage (IMessage msg,
-                                                        IMessageSink replySink)
-               {
-                       throw new NotImplementedException ();
+                       get {
+                               return null;
+                       }
                }
 
-               [MonoTODO]
                public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
                                                 IMessage msg,
                                                 ITransportHeaders headers,
                                                 Stream stream)
                {
-                       throw new NotImplementedException ();
+                       // never called because the formatter sink is
+                       // always the first in the chain
+                       throw new NotSupportedException("BinaryClientFormatterSink must be the first sink in the IClientChannelSink chain");
                }
 
-               [MonoTODO]
                public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
                                                  object state,
                                                  ITransportHeaders headers,
                                                  Stream stream)
                {
-                       throw new NotImplementedException ();
+                       IMessage replyMessage = (IMessage)_deserializationFormatter.DeserializeMethodResponse (stream, null, (IMethodCallMessage)state);
+                       sinkStack.DispatchReplyMessage (replyMessage);
                }
 
-               [MonoTODO]
                public Stream GetRequestStream (IMessage msg,
                                                ITransportHeaders headers)
                {
-                       throw new NotImplementedException ();
+                       // never called
+                       throw new NotSupportedException ();
                }
 
-               [MonoTODO]
                public void ProcessMessage (IMessage msg,
                                            ITransportHeaders requestHeaders,
                                            Stream requestStream,
                                            out ITransportHeaders responseHeaders,
                                            out Stream responseStream)
                {
-                       throw new NotImplementedException ();
+                       // never called because the formatter sink is
+                       // always the first in the chain
+                       throw new NotSupportedException ();
+               }
+
+               public IMessageCtrl AsyncProcessMessage (IMessage msg,
+                       IMessageSink replySink)
+               {
+                       ITransportHeaders transportHeaders = new TransportHeaders();
+                       transportHeaders[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
+
+                       Stream stream = nextInChain.GetRequestStream(msg, transportHeaders);
+                       if (stream == null) stream = new MemoryStream ();
+
+                       _serializationFormatter.Serialize (stream, msg, null);
+                       if (stream is MemoryStream) stream.Position = 0;
+
+                       ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);
+                       stack.Push (this, msg);
+
+                       nextInChain.AsyncProcessRequest (stack, msg, transportHeaders, stream);
+
+                       // FIXME: No idea about how to implement IMessageCtrl
+                       return null;    \r
                }
 
-               [MonoTODO]
                public IMessage SyncProcessMessage (IMessage msg)
                {
-                       throw new NotImplementedException ();
+                       try {
+
+                               ITransportHeaders call_headers = new TransportHeaders();
+                               call_headers[CommonTransportKeys.RequestUri] = ((IMethodCallMessage)msg).Uri;
+                               call_headers["Content-Type"] = "application/octet-stream";
+
+                               Stream call_stream = nextInChain.GetRequestStream(msg, call_headers);
+                               if (call_stream == null) call_stream = new MemoryStream ();
+
+                               // Serialize msg to the stream
+
+                               _serializationFormatter.Serialize (call_stream, msg, null);
+                               if (call_stream is MemoryStream) call_stream.Position = 0;
+
+                               Stream response_stream;
+                               ITransportHeaders response_headers;
+
+                               nextInChain.ProcessMessage (msg, call_headers, call_stream, out response_headers,
+                                                           out response_stream);
+
+                               // Deserialize response_stream
+
+                               return (IMessage) _deserializationFormatter.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg);
+                               
+                       } catch (Exception e) {
+                                return new ReturnMessage (e, (IMethodCallMessage)msg);
+                       }
                }
        }
 }