* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels / BinaryClientFormatterSink.cs
index a01bb35d14ddc4567cd2e9284749e51ac65ad67a..3e10dd9ef96f5820ade580a9b801565a151a20e9 100644 (file)
@@ -3,13 +3,36 @@
 //
 // Author: Rodrigo Moya (rodrigo@ximian.com)
 //         Dietmar Maurer (dietmar@ximian.com)
+//         Lluis Sanchez Gual (lluis@ideary.com)
 //
 // 2002 (C) Copyright, Ximian, Inc.
 //
 
+//
+// 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.Collections;
 using System.IO;
 using System.Runtime.Remoting.Messaging;
+using System.Runtime.Serialization;
 using System.Runtime.Serialization.Formatters.Binary;
 
 namespace System.Runtime.Remoting.Channels
@@ -17,25 +40,32 @@ namespace System.Runtime.Remoting.Channels
        public class BinaryClientFormatterSink : IClientFormatterSink,
                IMessageSink, IClientChannelSink, IChannelSinkBase
        {
-               IClientChannelSink nextInChain;
-               IRemotingFormatter formatter = new BinaryFormatter ();
-               
+               BinaryCore _binaryCore = BinaryCore.DefaultInstance;
+               IClientChannelSink _nextInChain;
+
                public BinaryClientFormatterSink (IClientChannelSink nextSink)
                {
-                       nextInChain = nextSink;
+                       _nextInChain = nextSink;
+               }
+
+               internal BinaryCore BinaryCore
+               {
+                       get { return _binaryCore; }
+                       set { _binaryCore = value; }
                }
 
                public IClientChannelSink NextChannelSink
                {
                        get {
-                               return nextInChain;
+                               return _nextInChain;
                        }
                }
 
                public IMessageSink NextSink
                {
                        get {
-                               return (IMessageSink) nextInChain;
+                               // This is the last sink in the IMessageSink sink chain
+                               return null;
                        }
                }
 
@@ -46,35 +76,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)_binaryCore.Deserializer.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,
@@ -83,33 +108,62 @@ 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;
+                       transportHeaders["Content-Type"] = "application/octet-stream";
+
+                       Stream stream = _nextInChain.GetRequestStream(msg, transportHeaders);
+                       if (stream == null) stream = new MemoryStream ();
+
+                       _binaryCore.Serializer.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;    
                }
 
-               [MonoTODO]
                public IMessage SyncProcessMessage (IMessage msg)
                {
-                       ITransportHeaders response_headers;
-                       Stream response_stream;
-                       
-                       // fixme: use nextInChain.GetRequestStream() ??
-                       //Stream out_stream = new MemoryStream ();
-                       Stream out_stream = File.Open ("test.bin", FileMode.Create);
-                       
-                       // serialize msg to the stream
-                       formatter.Serialize (out_stream, msg, null);
-                       //formatter.Serialize (out_stream, new Exception ("TEST"), null);
-                       
-                       out_stream.Close ();
-                       throw new NotImplementedException ();
-                       
-                       ProcessMessage (msg, null, out_stream, out response_headers, out response_stream);
-
-                       // deserialize response_stream
-                       IMessage result = (IMessage) formatter.Deserialize (response_stream, null);
-
-                       return null;
+                       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
+
+                               _binaryCore.Serializer.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) _binaryCore.Deserializer.DeserializeMethodResponse (response_stream, null, (IMethodCallMessage)msg);
+                               
+                       } catch (Exception e) {
+                                return new ReturnMessage (e, (IMethodCallMessage)msg);
+                       }
                }
        }
 }