[Ironruby-core] Inheritance question

Peter Bacon Darwin bacondarwin at googlemail.com
Thu Dec 20 11:38:26 EST 2007


Alternatively, you may prefer not to wrap the .NET type and to extend
System.Net.Sockets.Socket into the DLR directly.  This is inline with the
extension of other .NET classes such as Int32 to Fixnum and MutableString to
MutableString.
The following code demonstrates how you could do this...

using System;
using System.Collections.Generic;
using System.Text;
using Ruby.Runtime;
using System.Net.Sockets;
using Ruby.Builtins;
using Microsoft.Scripting;
using System.Net;

namespace Ruby.BuiltIns {

    [RubyClass("IPSocket", Extends=typeof(Socket))]
    public static class IPSocketOps {
        [RubyMethod("getaddress", RubyMethodAttributes.PublicSingleton)]
        public static string GetAddress(RubyClass klass, MutableString
hostName) {
            return
System.Net.Dns.GetHostEntry(hostName).AddressList[0].ToString();
        }

 
       [RubyMethod("addr", RubyMethodAttributes.PublicInstance)]
        public static object GetAddress(Socket self) {
            return GetAddressFromEndPoint(self.LocalEndPoint);
        }

        [RubyMethod("peeraddr", RubyMethodAttributes.PublicInstance)]
        public static object GetPeerAddress(Socket self) {
            return GetAddressFromEndPoint(self.RemoteEndPoint);
        }

        public static object GetAddressFromEndPoint(EndPoint endPoint) {
            RubyArray result = ArrayOps.CreateArray();
            IPEndPoint ep = (IPEndPoint)endPoint;
            MutableString addressFamily = null;
            switch (ep.AddressFamily) {
                // Surely this already exists somewhere in System.Net?
Couldn't find it though...
                case AddressFamily.InterNetwork:
                    addressFamily = new MutableString("AF_INET");
                    break;
                default:
                    throw new NotImplementedException();
            }

            result.Add(addressFamily);
            result.Add(ep.Port);
            result.Add(new
MutableString(System.Net.Dns.GetHostEntry(ep.Address).HostName));
            result.Add(new MutableString(ep.Address.ToString()));
            return result;
        }
    }

    [RubyClass("TCPSocket", Inherits=typeof(IPSocketOps))]
    public static class TCPSocket : Object{

        [RubyMethod("gethostbyname", RubyMethodAttributes.PublicSingleton)]
        public static object GetHostByName(object self, MutableString
hostName) {
            RubyArray result = ArrayOps.CreateArray();
            System.Net.IPHostEntry hostEntry =
System.Net.Dns.GetHostEntry(hostName);
            result.Add(hostName);
            result.Add(ArrayOps.CreateArray(hostEntry.Aliases.Length));
            foreach (string alias in hostEntry.Aliases) {
                ((RubyArray)result[1]).Add(new MutableString(alias));
            }
            result.Add((int)hostEntry.AddressList[0].AddressFamily);
            result.Add(new
MutableString(hostEntry.AddressList[0].ToString()));
            return result;
        }

        [RubyMethod("new", RubyMethodAttributes.PublicSingleton)]
        public static Socket/*!*/ CreateSocket(CodeContext/*!*/ context,
object self, BlockParam/*!*/ startRoutine, [NotNull]params object[]/*!*/
args) {
            object hostname = args[0];
            object port = args[1];
            Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);

            int portNumber = 0;

            if (port is int) {
                portNumber = (int)port;
            } else if (port is MutableString) {
                switch ((MutableString)port) {
                    case "ftp":
                        portNumber = 21;
                        break;
                    case "http":
                        portNumber = 80;
                        break;
                    default:
                        throw new NotImplementedException();
                }
            }

            socket.Connect((MutableString)hostname, portNumber);
            return socket;
        }

        [RubyMethod("open", RubyMethodAttributes.PublicSingleton)]
        public static Socket/*!*/ CreateSocketAlias_Open(CodeContext/*!*/
context, object self, BlockParam/*!*/ startRoutine, [NotNull]params
object[]/*!*/ args) {
            return CreateSocket(context, self, startRoutine, args);
        }

    }
}



More information about the Ironruby-core mailing list