2008-01-25 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.Tcp / TcpChannel.cs
index 1b169d5125025833a80baf315a277ae0d5760d9d..2974071b1d039884751dd6a1f19a3bf802240a98 100644 (file)
@@ -2,11 +2,32 @@
 // System.Runtime.Remoting.Channels.Tcp.TcpChannel.cs
 //
 // Author: Rodrigo Moya (rodrigo@ximian.com)
-//         Lluis Sanchez Gual (lsg@ctv.es)
+//         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.Runtime.Remoting.Messaging;
 using System.Text.RegularExpressions;
@@ -15,34 +36,39 @@ namespace System.Runtime.Remoting.Channels.Tcp
 {
        public class TcpChannel : IChannelReceiver, IChannel, IChannelSender
        {
-               private TcpClientChannel _clientChannel;\r
-               private TcpServerChannel _serverChannel = null;\r
-               private string _name;\r
+               private TcpClientChannel _clientChannel;
+               private TcpServerChannel _serverChannel = null;
+               private string _name = "tcp";
+               private int _priority = 1;
        
-               public TcpChannel (): this (0)
+               public TcpChannel ()
         {
+                       Init (new Hashtable(), null, null);
                }
 
                public TcpChannel (int port)
                {
-                       Hashtable ht = new Hashtable();\r
-                       ht["port"] = port.ToString();\r
-                       Init(ht, null, null);\r
+                       Hashtable ht = new Hashtable();
+                       ht["port"] = port.ToString();
+                       Init(ht, null, null);
+               }
+
+               void Init (IDictionary properties, IClientChannelSinkProvider clientSink, IServerChannelSinkProvider serverSink)
+               {
+                       _clientChannel = new TcpClientChannel (properties,clientSink);
+
+                       if (properties != null) {
+                               if(properties["port"] != null)
+                                       _serverChannel = new TcpServerChannel(properties, serverSink);
+
+                               object val = properties ["name"];
+                               if (val != null) _name = val as string;
+                       
+                               val = properties ["priority"];
+                               if (val != null) _priority = Convert.ToInt32 (val);
+                       }
                }
 
-               public void Init(IDictionary properties, IClientChannelSinkProvider clientSink, IServerChannelSinkProvider serverSink)\r
-               {\r
-                       _clientChannel = new TcpClientChannel(properties,clientSink);\r
-\r
-                       string port = properties["port"] as string;\r
-                       if (port != null && port != string.Empty)\r
-                       {\r
-                               _serverChannel = new TcpServerChannel(properties, serverSink);\r
-                       }\r
-\r
-                       _name = properties["name"] as string;\r
-               }\r
-\r
 
                public TcpChannel (IDictionary properties,
                                   IClientChannelSinkProvider clientSinkProvider,
@@ -51,45 +77,46 @@ namespace System.Runtime.Remoting.Channels.Tcp
                        Init (properties, clientSinkProvider, serverSinkProvider);
                }
 
-               public IMessageSink CreateMessageSink(string url, object remoteChannelData, out string objectURI)\r
-               {\r
-                       return _clientChannel.CreateMessageSink(url, remoteChannelData, out objectURI);\r
-               }\r
-\r
-               public string ChannelName\r
-               {\r
-                       get { return _name; }\r
-               }\r
-\r
-               public int ChannelPriority\r
-               {\r
-                       get { return 1; }\r
-               }\r
-\r
-               public void StartListening (object data)\r
-               {\r
-                       if (_serverChannel != null) _serverChannel.StartListening(data);\r
-               }\r
-               \r
-               public void StopListening (object data)\r
-               {\r
-                       if (_serverChannel != null) _serverChannel.StopListening(data);\r
-               }\r
-\r
-               public string[] GetUrlsForUri (string uri)\r
-               {\r
-                       if (_serverChannel != null) return _serverChannel.GetUrlsForUri(uri);\r
-                       else return null;\r
-               }\r
-\r
-               public object ChannelData\r
-               {\r
-                       get \r
-                       {\r
-                               if (_serverChannel != null) return _serverChannel.ChannelData;\r
-                               else return null;\r
-                       }\r
-               }\r
+               public IMessageSink CreateMessageSink(string url, object remoteChannelData, out string objectURI)
+               {
+                       return _clientChannel.CreateMessageSink(url, remoteChannelData, out objectURI);
+               }
+
+               public string ChannelName
+               {
+                       get { return _name; }
+               }
+
+               public int ChannelPriority
+               {
+                       get { return _priority; }
+               }
+
+               public void StartListening (object data)
+               {
+                       if (_serverChannel != null) _serverChannel.StartListening (data);
+               }
+               
+               public void StopListening (object data)
+               {
+                       if (_serverChannel != null) _serverChannel.StopListening(data);
+                       TcpConnectionPool.Shutdown ();
+               }
+
+               public string[] GetUrlsForUri (string uri)
+               {
+                       if (_serverChannel != null) return _serverChannel.GetUrlsForUri(uri);
+                       else return null;
+               }
+
+               public object ChannelData
+               {
+                       get 
+                       {
+                               if (_serverChannel != null) return _serverChannel.ChannelData;
+                               else return null;
+                       }
+               }
 
                public string Parse (string url, out string objectURI)
                {
@@ -98,6 +125,8 @@ namespace System.Runtime.Remoting.Channels.Tcp
 
                internal static string ParseChannelUrl (string url, out string objectURI)
                {
+                       if (url == null) throw new ArgumentNullException ("url");
+                       
                        int port;
                        
                        string host = ParseTcpURL (url, out objectURI, out port);
@@ -114,15 +143,26 @@ namespace System.Runtime.Remoting.Channels.Tcp
                        objectURI = null;
                        port = 0;
                        
-                       Match m = Regex.Match (url, "tcp://([^:]+):([0-9]+)[/](.*)");
+                       if (!url.StartsWith ("tcp://")) return null;
+                       int colon = url.IndexOf (':', 6);
+                       if (colon == -1) return null;
+                       string host = url.Substring (6, colon - 6);
 
-                       if (!m.Success)
-                               return null;
+                       int slash = url.IndexOf ('/', colon + 1);
+                       if (slash == -1) slash = url.Length;
+                       string port_str = url.Substring (colon + 1, slash - colon - 1);
                        
-                       string host = m.Groups[1].Value;
-                       string port_str = m.Groups[2].Value;
-                       objectURI = m.Groups[3].Value;
-                       port = Convert.ToInt32 (port_str);
+                       if (slash < url.Length)
+                               objectURI = url.Substring (slash + 1);
+
+                       try {
+                               port = Convert.ToInt32 (port_str);
+                       } catch {
+                               return null;
+                       }
+
+                       if (objectURI == string.Empty)
+                               objectURI = null;
                                
                        return host;
                }