* TcpClientChannel.cs: Fixed constructor.
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels / BinaryClientFormatterSink.cs
index c669198f6b8212f6c8d26f595fac269c62c71088..94e3845c260a721bdbc6fe3e893111a265c0fa19 100644 (file)
@@ -3,6 +3,7 @@
 //
 // 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)
                {
@@ -33,7 +49,8 @@ namespace System.Runtime.Remoting.Channels
                public IMessageSink NextSink
                {
                        get {
-                               return (IMessageSink) nextInChain;
+                               // This is the last sink in the IMessageSink sink chain
+                               return null;
                        }
                }
 
@@ -44,35 +61,30 @@ namespace System.Runtime.Remoting.Channels
                        }
                }
 
-               [MonoTODO]
-               public IMessageCtrl AsyncProcessMessage (IMessage msg,
-                                                        IMessageSink replySink)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [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);
                }
 
                public Stream GetRequestStream (IMessage msg,
                                                ITransportHeaders headers)
                {
-                       return null;
+                       // never called
+                       throw new NotSupportedException ();
                }
 
                public void ProcessMessage (IMessage msg,
@@ -81,27 +93,61 @@ namespace System.Runtime.Remoting.Channels
                                            out ITransportHeaders responseHeaders,
                                            out Stream responseStream)
                {
-                       nextInChain.ProcessMessage (msg, requestHeaders, requestStream,
-                                                   out responseHeaders, out responseStream);
+                       // 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)
                {
-                       ITransportHeaders response_headers;
-                       Stream response_stream;
-                       
-                       // fixme: use nextInChain.GetRequestStream() ??
-                       Stream out_stream = new MemoryStream ();
+                       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 ();
 
-                       // fixme: serialize msg to the stream
+                               // Serialize msg to the stream
 
-                       ProcessMessage (msg, null, out_stream, out response_headers, out response_stream);
+                               _serializationFormatter.Serialize (call_stream, msg, null);
+                               if (call_stream is MemoryStream) call_stream.Position = 0;
 
-                       // fixme: deserialize response_stream
-                       IMessage result = null;
+                               Stream response_stream;
+                               ITransportHeaders response_headers;
 
-                       return null;
+                               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);
+                       }
                }
        }
 }