channel example implementation
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 30 Aug 2002 14:01:21 +0000 (14:01 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 30 Aug 2002 14:01:21 +0000 (14:01 -0000)
svn path=/trunk/mcs/; revision=7151

23 files changed:
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/README [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleChannel.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientChannel.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientFormatterSink.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientFormatterSinkProvider.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientTransportSink.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientTransportSinkProvider.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleMessageFormat.cs [new file with mode: 0755]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerChannel.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerFormatterSink.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerFormatterSinkProvider.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerTransportSink.cs [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleWireFormat.cs [new file with mode: 0755]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Tcp/TcpServerChannel.cs
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.build
mcs/class/corlib/System.Runtime.Remoting.Channels/ChannelServices.cs
mcs/class/corlib/System.Runtime.Remoting.Channels/ServerDispatchSink.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.Remoting.Channels/ServerDispatchSinkProvider.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.Remoting.Channels/TransportHeaders.cs
mcs/class/corlib/System.Runtime.Remoting.Messaging/MonoMethodMessage.cs
mcs/class/corlib/System.Runtime.Remoting/ObjRef.cs
mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
mcs/class/corlib/System/MarshalByRefObject.cs

diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/README b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/README
new file mode 100644 (file)
index 0000000..88f05ea
--- /dev/null
@@ -0,0 +1,32 @@
+Example Channel Implementation:
+===============================
+
+This Channel is just used as example to show people how to implement remoting
+Channels for mono. I tried to keep it as simple as possible, so it is not
+feature complete.
+
+Overview
+========
+
+SimpleMessageFormat.cs: Contains routines to read/write messages transfered on
+the network (low level message format)
+
+SimpleWireFormat.cs: This is the data formatter.
+
+SimpleClientChannel.cs: The client side of the channel.
+
+       SimpleClientFormatterSink.cs: client side formatter sink
+       SimpleClientFormatterSinkProvider.cs: and the formatter sink provider
+       
+       SimpleClientTransportSink.cs: client side transport sink  
+       SimpleClientTransportSinkProvider.cs: and the transport sink provider
+
+SimpleServerChannel.cs: The server side of the channel.
+
+       SimpleServerFormatterSink.cs: server side formatter sink
+       SimpleServerFormatterSinkProvider.cs: and the formatter sink provider
+
+       SimpleServerTransportSink.cs: server side transport sink.
+
+SimpleChannel.cs: combines SimpleClientChannel with SimpleServerChannel.
+
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleChannel.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleChannel.cs
new file mode 100644 (file)
index 0000000..3e4eed4
--- /dev/null
@@ -0,0 +1,117 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleChannel.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.Runtime.Remoting.Messaging;
+using System.Text.RegularExpressions;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleChannel : IChannelReceiver, IChannel,
+               IChannelSender
+       {
+               private int tcp_port;
+               
+               public SimpleChannel ()
+               {
+                       tcp_port = 0;
+               }
+
+               public SimpleChannel (int port)
+               {
+                       tcp_port = port;
+               }
+
+               [MonoTODO]
+               public SimpleChannel (IDictionary properties,
+                                     IClientChannelSinkProvider clientSinkProvider,
+                                     IServerChannelSinkProvider serverSinkProvider)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public object ChannelData
+               {
+                       [MonoTODO]
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public string ChannelName
+               {
+                       [MonoTODO]
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public int ChannelPriority
+               {
+                       [MonoTODO]
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               [MonoTODO]
+               public IMessageSink CreateMessageSink (string url,
+                                                      object remoteChannelData,
+                                                      out string objectURI)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public string[] GetUrlsForUri (string objectURI)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public string Parse (string url, out string objectURI)
+               {
+                       int port;
+                       
+                       string host = ParseSimpleURL (url, out objectURI, out port);
+
+                       return "tcp://" + host + ":" + port;
+               }
+
+               [MonoTODO]
+               public void StartListening (object data)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public void StopListening (object data)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               internal static string ParseSimpleURL (string url, out string objectURI, out int port)
+               {
+                       // format: "simple://host:port/path/to/object"
+                       
+                       objectURI = null;
+                       port = 0;
+                       
+                       Match m = Regex.Match (url, "simple://([^:]+):([0-9]+)(/.*)");
+
+                       if (!m.Success)
+                               return null;
+                       
+                       string host = m.Groups[1].Value;
+                       string port_str = m.Groups[2].Value;
+                       objectURI = m.Groups[3].Value;
+                       port = Convert.ToInt32 (port_str);
+                               
+                       return host;
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientChannel.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientChannel.cs
new file mode 100644 (file)
index 0000000..fb76ad3
--- /dev/null
@@ -0,0 +1,91 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleClientChannel.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.IO;
+using System.Net.Sockets;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Channels;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleClientChannel : IChannelSender, IChannel
+       {
+               int priority = 1;                                       
+               string name = "tcp";
+               IClientChannelSinkProvider sink_provider;
+               
+               public SimpleClientChannel ()
+               {
+                       sink_provider = new SimpleClientFormatterSinkProvider ();
+                       sink_provider.Next = new SimpleClientTransportSinkProvider ();
+               }
+
+               public SimpleClientChannel (IDictionary properties, IClientChannelSinkProvider sinkProvider)
+               {
+                       priority = 1;
+                       sink_provider = sinkProvider;
+
+                       // add the tcp provider at the end of the chain
+                       IClientChannelSinkProvider prov = sinkProvider;
+                       while (prov.Next != null) prov = prov.Next;
+                       prov.Next = new SimpleClientTransportSinkProvider ();
+               }
+
+               public SimpleClientChannel (string name, IClientChannelSinkProvider sinkProvider)
+               {
+                       priority = 1;           
+                       this.name = name;
+                       sink_provider = sinkProvider;
+
+                       // add the tcp provider at the end of the chain
+                       IClientChannelSinkProvider prov = sinkProvider;
+                       while (prov.Next != null) prov = prov.Next;
+                       prov.Next = new SimpleClientTransportSinkProvider ();
+               }
+               
+               public string ChannelName
+               {
+                       get {
+                               return name;
+                       }
+               }
+
+               public int ChannelPriority
+               {
+                       get {
+                               return priority;
+                       }
+               }
+
+               public IMessageSink CreateMessageSink (string url,
+                                                      object remoteChannelData,
+                                                      out string objectURI)
+               {
+                       if (url == null && remoteChannelData != null) {
+                               IChannelDataStore ds = remoteChannelData as IChannelDataStore;
+                               if (ds != null)
+                                       url = ds.ChannelUris [0];
+                       }
+                       
+                       if (Parse (url, out objectURI) == null)
+                               return null;
+
+                       return (IMessageSink) sink_provider.CreateSink (this, url, remoteChannelData);
+               }
+
+               public string Parse (string url, out string objectURI)
+               {
+                       int port;
+                       
+                       string host = SimpleChannel.ParseSimpleURL (url, out objectURI, out port);
+
+                       return "tcp://" + host + ":" + port;
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientFormatterSink.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientFormatterSink.cs
new file mode 100644 (file)
index 0000000..c0571c5
--- /dev/null
@@ -0,0 +1,126 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleClientFormatterSink.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.IO;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Channels;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleClientFormatterSink : IClientFormatterSink,
+               IMessageSink, IClientChannelSink, IChannelSinkBase
+       {
+               IClientChannelSink nextInChain;
+               SimpleWireFormat format = new SimpleWireFormat ();
+               
+               public SimpleClientFormatterSink (IClientChannelSink nextSink)
+               {
+                       nextInChain = nextSink;
+               }
+
+               public IClientChannelSink NextChannelSink
+               {
+                       get {
+                               return nextInChain;
+                       }
+               }
+
+               public IMessageSink NextSink
+               {
+                       get {
+                               return (IMessageSink) nextInChain;
+                       }
+               }
+
+               public IDictionary Properties
+               {
+                       get {
+                               return null;
+                       }
+               }
+
+               public IMessageCtrl AsyncProcessMessage (IMessage msg,
+                                                        IMessageSink replySink)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
+                                                IMessage msg,
+                                                ITransportHeaders headers,
+                                                Stream stream)
+               {
+                       // never called because the formatter sink is
+                       // always the first in the chain
+                       throw new NotSupportedException ();
+               }
+
+               [MonoTODO]
+               public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
+                                                 object state,
+                                                 ITransportHeaders headers,
+                                                 Stream stream)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public Stream GetRequestStream (IMessage msg,
+                                               ITransportHeaders headers)
+               {
+                       // never called
+                       throw new NotSupportedException ();
+               }
+
+               public void ProcessMessage (IMessage msg,
+                                           ITransportHeaders requestHeaders,
+                                           Stream requestStream,
+                                           out ITransportHeaders responseHeaders,
+                                           out Stream responseStream)
+               {
+                       // never called because the formatter sink is
+                       // always the first in the chain
+                       throw new NotSupportedException ();
+               }
+
+               public IMessage SyncProcessMessage (IMessage msg)
+               {
+                       IMethodCallMessage call = (IMethodCallMessage)msg;
+                       
+                       // we catch all exceptions to return them as message
+                       try {
+                               // create a new header
+                               TransportHeaders req_headers = new TransportHeaders ();
+
+                               //fixme: set some header values
+
+                               Stream out_stream = new MemoryStream ();
+                       
+                               // serialize msg to the stream
+                               format.SerializeRequest (out_stream, msg);
+
+                               // call the next sink
+                               ITransportHeaders resp_headers;
+                               Stream resp_stream;
+                               nextInChain.ProcessMessage (msg, req_headers, out_stream, out resp_headers,
+                                                           out resp_stream);
+
+                               // deserialize resp_stream
+                               IMessage result = (IMessage) format.DeserializeResponse (resp_stream, call);
+
+                               // it's save to close the stream now
+                               resp_stream.Close ();
+
+                               return result;
+                               
+                       } catch (Exception e) {
+                                return new ReturnMessage (e, call);
+                       }
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientFormatterSinkProvider.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientFormatterSinkProvider.cs
new file mode 100644 (file)
index 0000000..da8541e
--- /dev/null
@@ -0,0 +1,61 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleClientFormatterSinkProvider.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleClientFormatterSinkProvider :
+               IClientFormatterSinkProvider, IClientChannelSinkProvider
+       {
+               IClientChannelSinkProvider next = null;
+
+               // add any sink properties here (private fields)
+               
+               public SimpleClientFormatterSinkProvider ()
+               {
+                       // nothing to do
+               }
+
+               public SimpleClientFormatterSinkProvider (IDictionary properties,
+                                                         ICollection providerData)
+               {
+                       // copy the contained properties to private fields
+                       
+                       // add a check that there is no providerData 
+               }
+
+               public IClientChannelSinkProvider Next
+               {
+                       get {
+                               return next;
+                       }
+                       
+                       set {
+                               next = value;
+                       }
+               }
+
+               public IClientChannelSink CreateSink (IChannelSender channel,
+                                                     string url,
+                                                     object remoteChannelData)
+               {
+                       IClientChannelSink next_sink = null;
+                       SimpleClientFormatterSink result;
+                       
+                       if (next != null)
+                               next_sink = next.CreateSink (channel, url, remoteChannelData);
+                       
+                       result = new SimpleClientFormatterSink (next_sink);
+
+                       // set properties on the newly creates sink
+
+                       return result;
+               }               
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientTransportSink.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientTransportSink.cs
new file mode 100644 (file)
index 0000000..4a38b22
--- /dev/null
@@ -0,0 +1,105 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleClientTransportSink.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.IO;
+using System.Net.Sockets;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Channels;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+
+       internal class SimpleClientTransportSink : IClientChannelSink
+       {
+               string host;
+               string object_uri;
+               int port;
+               
+               TcpClient tcpclient;
+               
+               public SimpleClientTransportSink (string url)
+               {
+                       host = SimpleChannel.ParseSimpleURL (url, out object_uri, out port);
+                       tcpclient = new TcpClient ();
+               }
+
+               public IDictionary Properties
+               {
+                       get {
+                               return null;
+                       }
+               }
+
+               public IClientChannelSink NextChannelSink
+               {
+                       get {
+                               // we are the last one
+                               return null;
+                       }
+               }
+
+               public void AsyncProcessRequest (IClientChannelSinkStack sinkStack, IMessage msg,
+                                                ITransportHeaders headers, Stream stream)
+               {
+                       throw new NotImplementedException ();                   
+               }
+
+               public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
+                                                 object state, ITransportHeaders headers,
+                                                 Stream stream)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public Stream GetRequestStream (IMessage msg, ITransportHeaders headers)
+               {
+                       // no direct access to the stream
+                       return null;
+               }
+               
+               public void ProcessMessage (IMessage msg,
+                                           ITransportHeaders requestHeaders,
+                                           Stream requestStream,
+                                           out ITransportHeaders responseHeaders,
+                                           out Stream responseStream)
+               {
+                       // get a network stream
+                       tcpclient.Connect (host, port);
+                       Stream network_stream = tcpclient.GetStream ();
+
+                       // send the message
+                       SimpleMessageFormat.SendMessageStream (network_stream, (MemoryStream)requestStream,
+                                                              SimpleMessageFormat.MessageType.Request,
+                                                              object_uri);
+                       
+                       Console.WriteLine ("Client  ProcessMessage");
+
+                       // read the response fro the network an copy it to a memory stream
+                       SimpleMessageFormat.MessageType msg_type;
+                       string uri;
+                       MemoryStream mem_stream = SimpleMessageFormat.ReceiveMessageStream (network_stream, out msg_type, out uri);
+
+                       // close the stream
+                       tcpclient.Close ();
+
+                       switch (msg_type) {
+                       case SimpleMessageFormat.MessageType.Response:
+                               //fixme: read response message
+                               responseHeaders = null;
+                       
+                               responseStream = mem_stream;
+               
+                               break;
+                       default:
+                               throw new Exception ("unknown response mesage header");
+                       }
+               }
+                       
+       }
+}      
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientTransportSinkProvider.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleClientTransportSinkProvider.cs
new file mode 100644 (file)
index 0000000..ead7472
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleClientTransportSinkProvider.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.IO;
+using System.Net.Sockets;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Channels;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleClientTransportSinkProvider : IClientChannelSinkProvider
+       {
+               public SimpleClientTransportSinkProvider ()
+               {
+                       // what should we do here ?
+               }
+
+               public IClientChannelSinkProvider Next
+               {
+                       get {
+                               return null;
+                       }
+
+                       set {
+                               // ignore, we are always the last in the chain 
+                       }
+               }
+
+               public IClientChannelSink CreateSink (IChannelSender channel, string url,
+                                                     object remoteChannelData)
+               {
+                       return new SimpleClientTransportSink (url);
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleMessageFormat.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleMessageFormat.cs
new file mode 100755 (executable)
index 0000000..c25194f
--- /dev/null
@@ -0,0 +1,149 @@
+// System.Runtime.Remoting.Channels.Simple.SimpleMessageFormat.cs
+//
+// Author:
+//     DietmarMaurer (dietmar@ximian.com)
+//
+// (C) 2002 Ximian, Inc.  http://www.ximian.com
+
+using System.Runtime.Serialization.Formatters;
+using System.Runtime.Serialization;
+using System.Reflection;
+using System.Collections;
+using System.IO;
+using System.Runtime.Remoting.Messaging;
+
+namespace System.Runtime.Remoting.Channels.Simple {
+
+       public sealed class SimpleMessageFormat 
+       {
+               public enum MessageType : byte {
+                       Request = 0,
+                       Response = 1,
+                       Exception = 2,
+                       Unknown = 3
+               }
+               
+               public SimpleMessageFormat ()
+               {
+               }
+               
+               public static void SendExceptionMessage (Stream network_stream, string message)
+               {
+                       // we use the uri field to encode the message text
+                       SendMessageStream (network_stream, null, MessageType.Exception, message);
+               }
+               
+               public static void SendMessageStream (Stream network_stream, MemoryStream data, 
+                                                     MessageType msg_type, string uri)
+               {
+                       int data_len = 0;
+                       
+                       if (data != null)
+                               data_len = (int)data.Length;
+
+                       int uri_len = 0;
+
+                       if (uri != null)
+                               uri_len = uri.Length;
+
+                       int header_len = 12 + uri_len * 2;
+                       int msg_len = data_len + header_len;
+                       
+                       byte [] buffer = new byte [msg_len];
+
+                       // magic header signature
+                       buffer [0] = 255;
+                       buffer [1] = 0;
+                       buffer [2] = 255;
+                       buffer [3] = (byte) msg_type;
+
+                       // data length
+                       buffer [4] = (byte) data_len;
+                       buffer [5] = (byte) (data_len >> 8);
+                       buffer [6] = (byte) (data_len >> 16);
+                       buffer [7] = (byte) (data_len >> 24);
+
+                       // uri length
+                       buffer [8] = (byte) uri_len;
+                       buffer [9] = (byte) (uri_len >> 8);
+                       buffer [10] = (byte) (uri_len >> 16);
+                       buffer [11] = (byte) (uri_len >> 24);
+
+                       // uri
+                       for (int i = 0; i < uri_len; i++) {
+                               buffer [12 + i*2] = (byte) uri [i];
+                               buffer [13 + i*2] = (byte) (uri [i] >> 8);
+                       }
+
+                       if (data_len > 0) {
+                               byte [] data_buffer = data.GetBuffer ();
+                               for (int i = 0; i < data_len; i++)
+                                       buffer [i + header_len] = data_buffer [i];
+                       }
+                       
+                       network_stream.Write (buffer, 0, msg_len);
+               }
+               
+               public static MemoryStream ReceiveMessageStream (Stream network_stream,
+                                                                out MessageType msg_type,
+                                                                out string uri)
+               {
+                       int data_len = 0;
+                       int uri_len = 0;
+                       msg_type = MessageType.Unknown;
+                       uri = null;
+                       
+                       // search for message header (255, 0, 255, msg_type, msg_len)
+                       while (true) {
+                               while (true) {
+                                       int x = network_stream.ReadByte ();
+                                       if (x != 255)
+                                               continue;
+                                       x = network_stream.ReadByte ();
+                                       if (x != 0)
+                                               continue;
+                                       x = network_stream.ReadByte ();
+                                       if (x != 255)
+                                               continue;
+                                       break;
+                               }
+
+                               msg_type = (MessageType)network_stream.ReadByte ();
+                               
+                               byte [] buffer = new byte [8];
+                               
+                               int bytes_read = network_stream.Read (buffer, 0, 8);
+                               if (bytes_read != 8)
+                                       continue;
+                               
+                               data_len = (buffer [0] | (buffer [1] << 8) |
+                                           (buffer [2] << 16) | (buffer [3] << 24));
+                               
+                               uri_len = (buffer [4] | (buffer [5] << 8) |
+                                          (buffer [6] << 16) | (buffer [7] << 24));
+                               
+                               if (uri_len > 0) {
+                                       byte [] uri_buffer = new byte [uri_len * 2];
+                                       bytes_read = network_stream.Read (uri_buffer, 0, uri_len * 2);
+                                       if (bytes_read != (uri_len * 2))
+                                               continue;
+                                       char [] uri_array = new char [uri_len];
+                                       for (int i = 0; i < uri_len; i++) {
+                                               uri_array [i] = (char) (uri_buffer [i * 2] | (uri_buffer [(i * 2) + 1] << 8));
+                                       }
+                                       uri = new string (uri_array);
+                               }
+                               break;
+                       }
+
+                       if (msg_type == MessageType.Exception)
+                               throw new RemotingException ("\n" + uri + "\n" + "Rethrown at:\n");
+                       
+                       byte [] stream_buffer = new byte [data_len];
+                       if ((network_stream.Read (stream_buffer, 0, data_len)) != data_len)
+                               throw new Exception ("packet size error");
+                       
+                       return new MemoryStream (stream_buffer, false);
+               }               
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerChannel.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerChannel.cs
new file mode 100644 (file)
index 0000000..ed96aa4
--- /dev/null
@@ -0,0 +1,164 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleServerChannel.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.Runtime.Remoting.Messaging;
+using System.Text.RegularExpressions;
+using System.Net.Sockets;
+using System.Net;
+using System.Threading;
+using System.IO;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleServerChannel : IChannelReceiver, IChannel
+       {
+               int port = 0;
+               string name = "tcp";
+               string host;
+               int priority = 1;
+               Thread server_thread = null;
+               TcpListener listener;
+               SimpleServerTransportSink sink;
+               ChannelDataStore channel_data;
+               
+               void Init (IServerChannelSinkProvider provider) {
+                       if (provider == null) {
+                               provider = new SimpleServerFormatterSinkProvider ();
+                       }
+                       
+                       IServerChannelSink next_sink = ChannelServices.CreateServerChannelSinkChain (provider, this);
+
+                       host = Dns.GetHostByName(Dns.GetHostName()).HostName;
+                       
+                       string [] uris = null;
+                       
+                       if (port != 0) {
+                               uris = new String [1];
+                               uris [0] = GetChannelUri ();
+                       }
+                       
+                       channel_data = new ChannelDataStore (uris);;
+
+                       sink = new SimpleServerTransportSink (next_sink);
+                       
+                       listener = new TcpListener (port);
+                       StartListening (null);
+               }
+               
+               public SimpleServerChannel (int port)
+               {
+                       this.port = port;
+                       Init (null);
+               }
+
+               public SimpleServerChannel (IDictionary properties,
+                                        IServerChannelSinkProvider serverSinkProvider)
+               {
+                       port = (int)properties ["port"];
+                       Init (serverSinkProvider);
+               }
+
+               public SimpleServerChannel (string name, int port,
+                                           IServerChannelSinkProvider serverSinkProvider)
+               {
+                       name = name;
+                       this.port = port;
+                       Init (serverSinkProvider);
+               }
+               
+               public SimpleServerChannel (string name, int port)
+               {
+                       name = name;
+                       this.port = port;
+                       Init (null);
+               }
+               
+               public object ChannelData
+               {
+                       get {
+                               return channel_data;
+                       }
+               }
+
+               public string ChannelName
+               {
+                       get {
+                               return name;
+                       }
+               }
+
+               public int ChannelPriority
+               {
+                       get {
+                               return priority;
+                       }
+               }
+
+               public string GetChannelUri ()
+               {
+                       return "tcp://" + host + ":" + port;
+               }
+               
+               public string[] GetUrlsForUri (string uri)
+               {
+                       string [] result = new String [1];
+
+                       if (uri.IndexOf ('/') != 0)
+                               result [0] = GetChannelUri () + "/" + uri;
+                       else
+                               result [0] = GetChannelUri () + uri;
+
+                       return result;
+               }
+
+               public string Parse (string url, out string objectURI)
+               {
+                       int port;
+                       
+                       string host = SimpleChannel.ParseSimpleURL (url, out objectURI, out port);
+
+                       return "tcp://" + host + ":" + port;
+               }
+
+               void WaitForConnections ()
+               {
+                       while (true) {
+                               TcpClient client = listener.AcceptTcpClient ();
+
+                               sink.InternalProcessMessage (client.GetStream ());
+
+                               client.Close ();
+                       }
+               }
+               
+               public void StartListening (object data)
+               {
+                       if (server_thread == null) {
+                               listener.Start ();
+                               if (port == 0) {
+                                       port = ((IPEndPoint)listener.LocalEndpoint).Port;
+                                       channel_data.ChannelUris = new String [1];
+                                       channel_data.ChannelUris [0] = GetChannelUri ();
+                               }
+
+                               server_thread = new Thread (new ThreadStart (WaitForConnections));
+                               server_thread.Start ();
+                       }
+               }
+
+               public void StopListening (object data)
+               {
+                       if (server_thread != null) {
+                               server_thread.Abort ();
+                               server_thread = null;
+                               listener.Stop ();
+                       }
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerFormatterSink.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerFormatterSink.cs
new file mode 100644 (file)
index 0000000..78c1701
--- /dev/null
@@ -0,0 +1,81 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleServerFormatterSink.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.IO;
+using System.Runtime.Remoting.Messaging;
+
+namespace System.Runtime.Remoting.Channels.Simple {
+
+       public class SimpleServerFormatterSink : IServerChannelSink, IChannelSinkBase
+       {
+               IServerChannelSink next_sink;
+               SimpleWireFormat format = new SimpleWireFormat ();
+       
+               public SimpleServerFormatterSink (IServerChannelSink nextSink)
+               {
+                       next_sink = nextSink;
+               }
+
+               public IServerChannelSink NextChannelSink {
+                       get {
+                               return next_sink;
+                       }
+               }
+
+               public IDictionary Properties {
+                       get {
+                               return null;
+                       }
+               }
+
+               [MonoTODO]
+               public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
+                                                 IMessage msg, ITransportHeaders headers, Stream stream)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
+                                                IMessage msg, ITransportHeaders headers)
+               {
+                       // never called 
+                       throw new NotSupportedException ();
+               }
+               
+               public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
+                                                       IMessage requestMsg,
+                                                       ITransportHeaders requestHeaders,
+                                                       Stream requestStream,
+                                                       out IMessage responseMsg,
+                                                       out ITransportHeaders responseHeaders,
+                                                       out Stream responseStream)
+               {
+                       IMessage call;
+                       
+                       string uri = (string)requestHeaders ["_requestUri"];
+
+                       if (requestMsg == null) {
+                               call = (IMessage)format.DeserializeRequest (requestStream, uri);
+                       } else { 
+                               call = requestMsg;
+                       }
+
+                       next_sink.ProcessMessage (sinkStack, call, requestHeaders, null,
+                                                 out responseMsg, out responseHeaders, out responseStream);
+                                               
+                       responseStream = new MemoryStream ();
+
+                       format.SerializeResponse (responseStream, responseMsg);
+                       
+                       responseStream.Position = 0;
+                       
+                       return ServerProcessing.Complete;
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerFormatterSinkProvider.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerFormatterSinkProvider.cs
new file mode 100644 (file)
index 0000000..2b1bf0b
--- /dev/null
@@ -0,0 +1,60 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleServerFormatterSinkProvider.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       public class SimpleServerFormatterSinkProvider :
+               IServerFormatterSinkProvider, IServerChannelSinkProvider
+       {
+               IServerChannelSinkProvider next = null;
+
+               public SimpleServerFormatterSinkProvider ()
+               {
+               }
+
+               [MonoTODO]
+               public SimpleServerFormatterSinkProvider (IDictionary properties,
+                                                         ICollection providerData)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public IServerChannelSinkProvider Next
+               {
+                       get {
+                               return next;
+                       }
+
+                       set {
+                               next = value;
+                       }
+               }
+
+               public IServerChannelSink CreateSink (IChannelReceiver channel)
+               {
+                       IServerChannelSink next_sink = null;
+                       SimpleServerFormatterSink result;
+                       
+                       if (next != null)
+                               next_sink = next.CreateSink (channel);
+                       
+                       result = new SimpleServerFormatterSink (next_sink);
+
+                       // set properties on result
+                       
+                       return result;
+               }
+
+               public void GetChannelData (IChannelDataStore channelData)
+               {
+                       // no idea why we need this
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerTransportSink.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleServerTransportSink.cs
new file mode 100644 (file)
index 0000000..88c2613
--- /dev/null
@@ -0,0 +1,110 @@
+//
+// System.Runtime.Remoting.Channels.Simple.SimpleServerTransportSink.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.Runtime.Remoting.Messaging;
+using System.Text.RegularExpressions;
+using System.Net.Sockets;
+using System.Net;
+using System.Threading;
+using System.IO;
+
+namespace System.Runtime.Remoting.Channels.Simple
+{
+       internal class SimpleServerTransportSink : IServerChannelSink, IChannelSinkBase
+       {
+               IServerChannelSink next_sink;
+               
+               public SimpleServerTransportSink (IServerChannelSink next)
+               {
+                       next_sink = next;
+               }
+               
+               public IServerChannelSink NextChannelSink {
+                       get {
+                               return next_sink;
+                       }
+               }
+
+               [MonoTODO]
+               public IDictionary Properties {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               [MonoTODO]
+               public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
+                                                 IMessage msg, ITransportHeaders headers, Stream stream)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
+                                               IMessage msg, ITransportHeaders headers)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
+                                                       IMessage requestMsg,
+                                                       ITransportHeaders requestHeaders,
+                                                       Stream requestStream,
+                                                       out IMessage responseMsg,
+                                                       out ITransportHeaders responseHeaders,
+                                                       out Stream responseStream)
+               {
+                       // this is the first sink, and SimpleServerChannel does not call it.
+                       throw new NotSupportedException ();
+               }
+
+               internal void InternalProcessMessage (Stream network_stream)
+               {
+                       try {
+                               string uri;
+                               SimpleMessageFormat.MessageType msg_type;
+                               MemoryStream msg_stream;
+
+                               msg_stream = SimpleMessageFormat.ReceiveMessageStream (network_stream,
+                                                                                      out msg_type, out uri);
+                               if (msg_type != SimpleMessageFormat.MessageType.Request)
+                                       throw new RemotingException ("received wrong message type");
+                               
+                               TransportHeaders headers = new TransportHeaders ();
+                               headers ["_requestUri"] = uri;
+                               
+                               Console.WriteLine ("ProcessMessageInternal " + uri);
+
+                               IMessage resp_message;
+                               ITransportHeaders resp_headers;
+                               Stream resp_stream;
+                               ServerProcessing res = next_sink.ProcessMessage (null, null, headers, msg_stream,
+                                                                                out resp_message, out resp_headers,
+                                                                                out resp_stream);
+
+                               switch (res) {
+                               case ServerProcessing.Complete:
+                                       // send the response
+                                       SimpleMessageFormat.SendMessageStream (network_stream,
+                                                                              (MemoryStream)resp_stream, 
+                                                                              SimpleMessageFormat.MessageType.Response,
+                                                                              null);
+                                       
+                                       break;
+                               case ServerProcessing.Async:
+                               case ServerProcessing.OneWay:
+                                       throw new NotImplementedException ();                                   
+                               }
+                               
+                       } catch (Exception e) {
+                               SimpleMessageFormat.SendExceptionMessage (network_stream, e.ToString ());
+                       }
+               }
+       }
+}
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleWireFormat.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Simple/SimpleWireFormat.cs
new file mode 100755 (executable)
index 0000000..397b9e6
--- /dev/null
@@ -0,0 +1,201 @@
+// System.Runtime.Remoting.Channels.Simple.SimpleWireFormat.cs
+//
+// Author:
+//     DietmarMaurer (dietmar@ximian.com)
+//
+// (C) 2002 Ximian, Inc.  http://www.ximian.com
+
+using System.Runtime.Serialization.Formatters;
+using System.Runtime.Serialization;
+using System.Reflection;
+using System.Collections;
+using System.IO;
+using System.Runtime.Remoting.Messaging;
+
+namespace System.Runtime.Remoting.Channels.Simple {
+
+       public sealed class SimpleWireFormat 
+       {
+               enum TypeId : byte {
+                       Boolean,
+                       Byte,
+                       Char,
+                       Decimal,
+                       Double,
+                       Int16,
+                       Int32,
+                       Int64,
+                       SByte,
+                       String,
+                       Single,
+                       UInt16,
+                       UInt32,
+                       UInt64,
+                       Exception,
+                       NULL
+               }
+
+               public SimpleWireFormat ()
+               {
+               }
+               
+
+               void SerializeObject (BinaryWriter writer, object obj)
+               {
+                       Type type = obj.GetType ();
+
+                       if (obj == null) {
+                               writer.Write ((byte)TypeId.NULL);
+                               return;
+                       }
+                       
+                       if (type == typeof (String)) {
+                               writer.Write ((byte)TypeId.String);
+                               writer.Write ((String)obj);
+                               return;
+                       }
+                       
+                       if (type == typeof (int)) {
+                               writer.Write ((byte)TypeId.Int32);
+                               writer.Write ((int)obj);
+                               return;
+                       }               
+
+                       if (type == typeof (bool)) {
+                               writer.Write ((byte)TypeId.Boolean);
+                               writer.Write ((bool)obj);
+                               return;
+                       }               
+
+                       Exception e = obj as Exception;
+                       if (e != null) {
+                               writer.Write ((byte)TypeId.Exception);
+                               writer.Write (e.Message);
+                               return;
+                       }               
+
+                       throw new NotSupportedException (); 
+               }
+
+               object DeserializeObject (BinaryReader reader)
+               {
+                       TypeId tid = (TypeId)reader.ReadByte ();
+
+                       if (tid == TypeId.NULL)
+                               return null;
+
+                       if (tid == TypeId.String) {
+                               return reader.ReadString ();
+                       }
+                       
+                       if (tid == TypeId.Int32) {
+                               return reader.ReadInt32 ();
+                       }
+                       
+                       if (tid == TypeId.Boolean) {
+                               return reader.ReadBoolean ();
+                       }
+                       
+                       if (tid == TypeId.Exception) {
+                               return new RemotingException (reader.ReadString ());
+                       }
+                       
+                       throw new NotSupportedException (); 
+               }
+               
+               public IMethodCallMessage DeserializeRequest (Stream serializationStream, string uri)
+               {
+                       if (serializationStream == null) {
+                               throw new ArgumentNullException ("serializationStream is null");
+                       }
+
+                       Type svr_type = RemotingServices.GetServerTypeForUri (uri);
+                       if (svr_type == null)
+                               throw new RemotingException ("no registered server for uri " + uri); 
+
+                       BinaryReader reader = new BinaryReader (serializationStream);
+                       
+                       string method_name = reader.ReadString ();
+                       int arg_count = reader.ReadInt32 ();
+
+                       object [] args = new object [arg_count];
+                       for (int i = 0; i < arg_count; i++) {
+                               args [i] = DeserializeObject (reader);
+                       }
+                       
+                       MonoMethodMessage msg = new MonoMethodMessage (svr_type, method_name, args);
+                       
+                       Console.WriteLine ("Deserialize " + msg);
+                       
+                       return msg;
+               }
+
+               public IMethodReturnMessage DeserializeResponse (Stream serializationStream,
+                                                                IMethodCallMessage request) 
+               {
+
+                       BinaryReader reader = new BinaryReader (serializationStream);
+                       
+                     
+                       object return_value = DeserializeObject (reader);
+                       Exception e = return_value as Exception;
+                       if (e != null) 
+                               return new ReturnMessage (e, request);
+                       
+                       int arg_count = reader.ReadInt32 ();
+                       object [] out_args = new object [arg_count];
+                       for (int i = 0; i < arg_count; i++)
+                               out_args [i] = DeserializeObject (reader);
+                       
+                       return new ReturnMessage (return_value, out_args, arg_count, null, request);
+               }
+               
+               public void SerializeRequest (Stream serializationStream, object graph)
+               {
+                       if (serializationStream == null) {
+                               throw new ArgumentNullException ("serializationStream is null");
+                       }
+
+                       BinaryWriter writer = new BinaryWriter (serializationStream);
+
+                       IMethodCallMessage msg = graph as IMethodCallMessage;
+                       if (msg != null) {                      
+                               writer.Write (msg.MethodName);
+                               writer.Write ((int)msg.InArgCount);
+                               for (int i = 0; i < msg.InArgCount; i++)
+                                       SerializeObject (writer, msg.GetInArg (i));
+                               return;
+                       }
+
+                       throw new NotSupportedException ();
+               }
+
+               public void SerializeResponse (Stream serializationStream, object graph)
+               {
+                       if (serializationStream == null) {
+                               throw new ArgumentNullException ("serializationStream is null");
+                       }
+
+                       BinaryWriter writer = new BinaryWriter (serializationStream);
+
+                       IMethodReturnMessage res = graph as IMethodReturnMessage;
+                       if (res != null) {
+
+                               if (res.Exception != null) {
+                                       SerializeObject (writer, res.Exception);
+                                       return;
+                               }
+                               
+                               SerializeObject (writer, res.ReturnValue);
+                               writer.Write (res.OutArgCount);
+                       
+                               for (int i = 0; i < res.OutArgCount; i++)
+                                       SerializeObject (writer, res.GetOutArg (i));
+
+                               return;
+                       }
+
+                       throw new NotSupportedException ();
+               }
+       }
+}
index 41814adaadcadcb5026282a8602091e44411b808..2f3a0ee7598439dba10566ccd031c74e95f7b578 100644 (file)
@@ -1,5 +1,5 @@
 //
-// System.Runtime.Remoting.Channels.Tcp.TcpChannel.cs
+// System.Runtime.Remoting.Channels.Tcp.TcpServerChannel.cs
 //
 // Author: Rodrigo Moya (rodrigo@ximian.com)
 //
index b794acf7f3d788187ad167c7be9ff6d5751adec5..101cd0fdab07ccb0bd56d2ba2bbd95a8162baaad 100644 (file)
@@ -9,14 +9,14 @@
                <csc target="library" output="../lib/System.Runtime.Remoting.dll" debug="${debug}">
                        <arg value="/nowarn:1595"/>
                        <arg value="/unsafe"/>
+                       <arg value="/noconfig"/>        <!-- don't reference ms assemblies -->
+                       <arg value="/lib:../lib/"/>
+                       <arg value="/r:corlib.dll"/>
+                       <arg value="/r:System.dll"/>
                        <sources>
                                <includes name="**/*.cs"/> 
                                <excludes name="Test/**"/> 
                        </sources>
-                       <references>
-                               <includes name="../lib/corlib.dll"/>
-                               <includes name="../lib/System.dll"/>
-                       </references>
                </csc>
        </target>
        <target name="clean">
index b261b5e760eedff2e243525a6879b94f75c618ac..bcadd38727a49c68b61d88a6242f40d5a3fd0141 100644 (file)
@@ -38,12 +38,15 @@ namespace System.Runtime.Remoting.Channels
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public static IServerChannelSink CreateServerChannelSinkChain (
                        IServerChannelSinkProvider provider,
                        IChannelReceiver channel)
                {
-                       throw new NotImplementedException ();
+                       IServerChannelSinkProvider tmp = provider;
+                       while (tmp.Next != null) tmp = tmp.Next;
+                       tmp.Next = new ServerDispatchSinkProvider ();
+
+                       return  provider.CreateSink (channel);
                }
 
                [MonoTODO]
diff --git a/mcs/class/corlib/System.Runtime.Remoting.Channels/ServerDispatchSink.cs b/mcs/class/corlib/System.Runtime.Remoting.Channels/ServerDispatchSink.cs
new file mode 100644 (file)
index 0000000..db1e58b
--- /dev/null
@@ -0,0 +1,70 @@
+//
+// System.Runtime.Remoting.Channels/ServerDispatchSink.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+using System.IO;
+using System.Runtime.Remoting.Messaging;
+
+namespace System.Runtime.Remoting.Channels {
+
+       internal class ServerDispatchSink : IServerChannelSink, IChannelSinkBase
+       {
+               public ServerDispatchSink ()
+               {
+               }
+
+               public IServerChannelSink NextChannelSink {
+                       get {
+                               return null;
+                       }
+               }
+
+               public IDictionary Properties {
+                       get {
+                               return null;
+                       }
+               }
+
+               [MonoTODO]
+               public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
+                                                 IMessage msg, ITransportHeaders headers, Stream stream)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
+                                                IMessage msg, ITransportHeaders headers)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
+                                                       IMessage requestMsg,
+                                                       ITransportHeaders requestHeaders,
+                                                       Stream requestStream,
+                                                       out IMessage responseMsg,
+                                                       out ITransportHeaders responseHeaders,
+                                                       out Stream responseStream)
+               {
+                       IMethodCallMessage call = (IMethodCallMessage)requestMsg;
+                       
+                       string uri = (string)requestHeaders ["_requestUri"];
+                       
+                       MarshalByRefObject svr = RemotingServices.GetServerForUri (uri);
+                       if (svr == null)
+                               throw new RemotingException ("no registered server for uri " + uri); 
+
+                       responseMsg = RemotingServices.ExecuteMessage (svr, call);
+                       responseHeaders = null;                 
+                       responseStream = null;
+                       
+                       return ServerProcessing.Complete;
+               }
+       }
+}
diff --git a/mcs/class/corlib/System.Runtime.Remoting.Channels/ServerDispatchSinkProvider.cs b/mcs/class/corlib/System.Runtime.Remoting.Channels/ServerDispatchSinkProvider.cs
new file mode 100644 (file)
index 0000000..57ccdb4
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// System.Runtime.Remoting.Channels.ServerDispatchSinkProvider.cs
+//
+// Author: Dietmar Maurer (dietmar@ximian.com)
+//
+// 2002 (C) Copyright, Ximian, Inc.
+//
+
+using System.Collections;
+
+namespace System.Runtime.Remoting.Channels
+{
+       internal class ServerDispatchSinkProvider :
+               IServerFormatterSinkProvider, IServerChannelSinkProvider
+       {
+               public ServerDispatchSinkProvider ()
+               {
+               }
+
+               [MonoTODO]
+               public ServerDispatchSinkProvider (IDictionary properties,
+                                                  ICollection providerData)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public IServerChannelSinkProvider Next
+               {
+                       get {
+                               return null;
+                       }
+
+                       set {
+                               throw new NotSupportedException ();
+                       }
+               }
+
+               public IServerChannelSink CreateSink (IChannelReceiver channel)
+               {
+                       return new ServerDispatchSink ();
+               }
+
+               public void GetChannelData (IChannelDataStore channelData)
+               {
+                       // no idea why we need this
+               }
+       }
+}
index acfecbf5dbcacb931047133049efd17e2b3a7b76..09f1c24c8d5a34b390baa707834ecc90f1410e11 100644 (file)
@@ -2,6 +2,7 @@
 // System.Runtime.Remoting.Channels.TransportHeaders.cs
 //
 // Author: Rodrigo Moya (rodrigo@ximian.com)
+//         Dietmar Maurer (dietmar@ximian.com)
 //
 // 2002 (C) Copyright, Ximian, Inc.
 //
@@ -12,29 +13,27 @@ namespace System.Runtime.Remoting.Channels
 {
        public class TransportHeaders : ITransportHeaders
        {
-               [MonoTODO]
+               Hashtable hash_table;
+               
                public TransportHeaders ()
                {
-                       throw new NotImplementedException ();
+                       hash_table = new Hashtable ();
                }
 
-               public object this[object key]
+               public object this [object key]
                {
-                       [MonoTODO]
                        get {
-                               throw new NotImplementedException ();
+                               return  hash_table [key];
                        }
                        
-                       [MonoTODO]
                        set {
-                               throw new NotImplementedException ();
+                               hash_table [key] = value;
                        }
                }
 
-               [MonoTODO]
                public IEnumerator GetEnumerator ()
                {
-                       throw new NotImplementedException ();
+                       return  hash_table.GetEnumerator ();
                }
        }
 }
index 5f496b8faf48dcdc56cc1d55bef7c4b1f4f9d3cb..ad9dddc6c72b0d81108536c079acd0f2e8f1e4c0 100644 (file)
@@ -14,7 +14,7 @@ using System.Runtime.CompilerServices;
 
 namespace System.Runtime.Remoting.Messaging {
        
-       internal class MonoMethodMessage : IMethodCallMessage, IMethodReturnMessage {
+       public class MonoMethodMessage : IMethodCallMessage, IMethodReturnMessage {
 
                MonoMethod method;
 
@@ -33,9 +33,22 @@ namespace System.Runtime.Remoting.Messaging {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal extern void InitMessage (MonoMethod method, object [] out_args);
 
-               public MonoMethodMessage (MonoMethod method, object [] out_args)
+               public MonoMethodMessage (MethodBase method, object [] out_args)
                {
-                       InitMessage (method, out_args);                 
+                       InitMessage ((MonoMethod)method, out_args);                     
+               }
+
+               public MonoMethodMessage (Type type, string method_name, object [] in_args)
+               {
+                       // fixme: consider arg types
+                       MethodInfo minfo = type.GetMethod (method_name);
+                       
+                       InitMessage ((MonoMethod)minfo, null);
+
+                       int len = in_args.Length;
+                       for (int i = 0; i < len; i++) {
+                               args [i] = in_args [i];
+                       }
                }
                
                public IDictionary Properties {
index 6f56487896955dd4011d40e13213ab4ddd4b294b..210f34e8dfcab3ce8d8937056db88777afffc6cd 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Miguel de Icaza (miguel@ximian.com)
+//   Dietmar Maurer (dietmar@ximian.com)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
 //
@@ -19,6 +20,7 @@ namespace System.Runtime.Remoting {
        public class ObjRef : IObjectReference, ISerializable {
                MarshalByRefObject mbr;
                SerializationInfo si;
+               string uri;
                Type type;
                
                public ObjRef ()
@@ -39,6 +41,45 @@ namespace System.Runtime.Remoting {
                        // This encarnates the object from serialized data.
                }
 
+               [MonoTODO]
+               public virtual IChannelInfo ChannelInfo {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+               
+               [MonoTODO]
+               public virtual IEnvoyInfo EnvoyInfo {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+               
+               [MonoTODO]
+               public virtual IRemotingTypeInfo TypeInfo {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+                       set {
+                               throw new NotImplementedException ();
+                       }
+               }
+               
+               public virtual string URI {
+                       get {
+                               return uri;
+                       }
+                       set {
+                               uri = value;
+                       }
+               }
+
                [MonoTODO]
                public virtual void GetObjectData (SerializationInfo si, StreamingContext sc)
                {
index a7f3a88795952bf9af994c69748735f299a8b409..0fa1f84eeabf8f0ef0fd02ffb0942df34a34dab6 100644 (file)
@@ -9,6 +9,8 @@
 
 using System;
 using System.Reflection;
+using System.Threading;
+using System.Collections;
 using System.Runtime.Remoting.Messaging;
 using System.Runtime.Remoting.Proxies;
 using System.Runtime.Remoting.Channels;
@@ -74,5 +76,75 @@ namespace System.Runtime.Remoting
 
                        return real_proxy.GetTransparentProxy ();
                }
+
+               public static Type GetServerTypeForUri (string uri)
+               {
+                       object svr = GetServerForUri (uri);
+
+                       if (svr == null)
+                               return null;
+                       
+                       return svr.GetType ();
+               }
+
+               static Hashtable uri_hash = new Hashtable ();
+               
+               private static void RegisterServerForUri (MarshalByRefObject obj, string uri)
+               {
+                       uri_hash [uri] = obj;
+               }
+
+               public static object Unmarshal (ObjRef objref)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               internal static MarshalByRefObject GetServerForUri (string uri)
+               {
+                       return (MarshalByRefObject)uri_hash [uri];
+               }
+               
+               static Mutex mtx = new Mutex ();
+               
+               public static ObjRef Marshal (MarshalByRefObject obj, string uri)
+               {
+                       return Marshal (obj, uri, null);
+               }
+               
+               public static ObjRef Marshal (MarshalByRefObject obj, string uri, Type requested_type)
+               {
+                       if (RemotingServices.IsTransparentProxy (obj))
+                               throw new RemotingException ("its not possible marshal proxy objects");
+                       
+                       // fixme: handle requested_type
+                       
+                       Type type = obj.GetType ();
+
+                       ObjRef res = null;
+
+                       try {
+                               mtx.WaitOne ();
+                       
+                               object svr = GetServerForUri (uri);
+
+                               if (svr != null) {
+                                       if (obj != svr)
+                                               throw new RemotingException ("uri already in use, " + uri);
+
+                                       // already registered
+                               } else {
+                                       RegisterServerForUri (obj, uri);
+                               }
+                       
+                               res = obj.CreateObjRef (requested_type);
+                               res.URI = uri;
+                               
+                       } finally {
+                               mtx.ReleaseMutex ();
+                       }
+                  
+                       return res;
+               }
        }
+
 }
index 53051ceba32fe1f6594f32c016886c91207f1baa..0a5506c5f7063392151421a73cbe771c2c239255 100644 (file)
@@ -16,7 +16,7 @@ namespace System {
 
                public virtual ObjRef CreateObjRef (Type type)
                {
-                       return null;
+                       return new ObjRef (this, type);
                }
 
                public object GetLifetimeService ()