//
// 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)
{
public IMessageSink NextSink
{
get {
- return (IMessageSink) nextInChain;
+ // This is the last sink in the IMessageSink sink chain
+ return null;
}
}
}
}
- [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,
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);
+ }
}
}
}