qmsk.net/socket/addr.pxd
changeset 6 10bd48c9b6ce
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk.net/socket/addr.pxd	Sun Aug 16 18:29:55 2009 +0300
@@ -0,0 +1,95 @@
+"""
+    Socket addresses at various levels:
+
+        sockaddr    - specific network-level address for socket operations
+        addrinfo    - information on a specific sockaddr including its socket parameters
+        endpoint    - human-readable network address, corresponding to multiple sockaddr's
+"""
+
+cimport libc
+
+cdef class sockaddr :
+    """
+        A network-level socket address
+
+        XXX: rename to 'address'
+
+        >>> sockaddr().family
+        0
+        >>> sockaddr().port
+        Traceback (most recent call last):
+          ...
+        NotImplementedError
+        >>> sockaddr().getnameinfo()
+        Traceback (most recent call last):
+          ...
+        NotImplementedError
+    """
+    
+    # address family
+    # XXX: this should be a class constant! It's part of our type safety!
+    cdef readonly libc.sa_family_t family
+
+    cdef void _init_family (self, libc.sa_family_t family = ?)
+
+    # get the sockaddr/socklen
+    # each of these can be NULL to ignore it
+    cdef int _get_sockaddr (self, libc.sockaddr **sa_ptr, libc.socklen_t *sa_len) except -1
+
+    cdef libc.sockaddr* _get_sockaddr_ptr (self) except NULL
+    cdef libc.socklen_t _get_sockaddr_len (self) except -1
+    
+    # set the sockaddr, socklen must match
+    cdef int _set_sockaddr (self, libc.sockaddr *sa, size_t sa_len) except -1
+
+# build a sockaddr from the given sockaddr struct, based on sa_family
+cdef sockaddr build_sockaddr (libc.sockaddr *sa, size_t sa_len)
+
+cdef class addrinfo :
+    """
+        A socket-level endpoint address, which contains the full socket parameters and an bind/connect address
+    """
+
+#    cdef readonly int flags
+    cdef readonly int family, socktype, protocol
+    cdef readonly sockaddr addr
+    cdef readonly object canonname
+
+    cdef _init_addrinfo (self, libc.addrinfo *c_ai)
+
+# build and return a new addrinfo instance
+cdef addrinfo build_addrinfo (libc.addrinfo *c_ai)
+
+cdef class endpoint :
+    """
+        A network-level socket endpoint. This is the level that humans mostly work with, but the tricky bit is that
+        an endpoint can map to more than one sockaddr...
+
+        Hence, endpoints are stored as human-readable hostname/service strings, which are then translated to sockaddrs
+        using getaddrinfo.
+
+        >>> import socket
+        >>> e = endpoint('127.0.0.1', 80)
+        >>> str(e)
+        'hostname=127.0.0.1, service=80'
+        >>> res = e.getaddrinfo(socket.AF_UNSPEC, socket.SOCK_STREAM)
+        >>> len(res)
+        1
+        >>> str(res[0])
+        'family=2, socktype=1, protocol=6, addr=127.0.0.1:80, canonname=None'
+        >>> e = endpoint('2001::5', 80)
+        >>> str(e)
+        'hostname=2001::5, service=80'
+        >>> res = e.getaddrinfo(socket.AF_UNSPEC, socket.SOCK_STREAM)
+        >>> len(res)
+        1
+        >>> str(res[0])
+        'family=10, socktype=1, protocol=6, addr=[2001::5]:80, canonname=None'
+
+    """
+    
+    # our defining attributes, set via __init__
+    cdef object hostname, service
+
+    cpdef getaddrinfo (self, int family, int socktype, int protocol = ?, int flags = ?)
+