Author: ArcRiley
Date: 2009-02-21 12:31:52 -0500 (Sat, 21 Feb 2009)
New Revision: 1514

Modified:
   trunk/concordance/include/concordance.sockets.h
   trunk/concordance/src/sockets/Client.c
   trunk/concordance/src/sockets/Socket.c
   trunk/concordance/src/sockets/__init__.c
Log:
polished type inheritance

Modified: trunk/concordance/include/concordance.sockets.h
===================================================================
--- trunk/concordance/include/concordance.sockets.h     2009-02-12 19:42:06 UTC 
(rev 1513)
+++ trunk/concordance/include/concordance.sockets.h     2009-02-21 17:31:52 UTC 
(rev 1514)
@@ -26,10 +26,12 @@
 
 
 /* concordance.sockets.Socket definition */
-PyTypeObject  socketsSocket_Type;
-PyObject*     socketsSocket_new        (PyTypeObject*, PyObject*, PyObject*);
-void          socketsSocket_dealloc    (PyObject*);
 typedef struct {
+  PyTypeObject          base;
+  gboolean           (* _listenNew ) (GIOChannel*, GIOCondition, gpointer);
+} socketsSocket_TypeObject;
+extern socketsSocket_TypeObject socketsSocket_Type;
+typedef struct {
   PyObject_HEAD
   PyObject*             module;        /* reference to our own module */
   GMainContext*         context;       /* Concordance's Glib context */
@@ -41,10 +43,12 @@
 
 
 /* concordance.sockets.Client definition */
-PyTypeObject  socketsClient_Type;
-PyObject*     socketsClient_new        (PyTypeObject*, PyObject*, PyObject*);
-void          socketsClient_dealloc    (PyObject*);
 typedef struct {
+  PyTypeObject          base;
+  gboolean           (* _listenNew ) (GIOChannel*, GIOCondition, gpointer);
+} socketsClient_TypeObject;
+extern socketsClient_TypeObject  socketsClient_Type;
+typedef struct {
   PyObject_HEAD
   PyObject*             module;        /* reference to our own module */
   GMainContext*         context;       /* Concordance's Glib context */

Modified: trunk/concordance/src/sockets/Client.c
===================================================================
--- trunk/concordance/src/sockets/Client.c      2009-02-12 19:42:06 UTC (rev 
1513)
+++ trunk/concordance/src/sockets/Client.c      2009-02-21 17:31:52 UTC (rev 
1514)
@@ -25,14 +25,45 @@
 cdef class Socket :                                                       \*/
   static char socketsClient_Doc[] = "Test";
 
+  static gboolean
+  _listenNew(GIOChannel* channel, GIOCondition condition, gpointer s) {   /*\
+    cdef :                                                                \*/
+      socketsSocket_Object*      self = (socketsSocket_Object*) s;
+      gint                       socket;
+      struct sockaddr            addr;
+      guint                      addrlen = sizeof(addr);
 
-  PyObject*
-  socketsClient_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\
+    /* accept new connection, return if we fail to connect
+
+       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+    */
+    if ((socket = accept(g_io_channel_unix_get_fd(channel),
+                         &addr, &addrlen))<0) {
+      /* return true so GMainLoop will continue watching this channel */
+      return TRUE;
+    }
+
+    /* this is a generic Socket object, just close incoming connections */
+    close(socket);
+        
+    /* return true so GMainLoop will continue watching this channel */
+    return TRUE;
+  }
+
+  /*
+  #
+  ###########################################################################
+  #
+  # object constructor - deconstructor
+  #                                                                        */
+
+  static PyObject*
+  _new(PyTypeObject* type, PyObject* args, PyObject* kwds) {              /*\
     cdef :                                                                \*/
       socketsClient_Object* self;
 
     /* first inherit base type */
-    self = (socketsClient_Object*) socketsSocket_new(type, args, kwds);
+    self = (socketsClient_Object*) type->tp_base->tp_new(type, args, kwds);
     if (!self)
       return NULL;
 
@@ -60,38 +91,15 @@
   }
 
 
-  static int
-  socketsClient_init(PyObject* s, PyObject* args, PyObject* kwds) {       /*\
+  static void
+  _dealloc(PyObject* s) {                                                 /*\
     cdef :                                                                \*/
       socketsClient_Object*      self = (socketsClient_Object*) s;
-    
-    return 0;
-  }
 
-
-  void
-  socketsClient_dealloc(PyObject* s) {                                    /*\
-    cdef :                                                                \*/
-      socketsClient_Object*      self = (socketsClient_Object*) s;
-
     /* lastly dealloc base type */
-    socketsSocket_dealloc(s);
+    s->ob_type->tp_base->tp_dealloc(s);
   }
 
-
-  static PyObject*
-  socketsClient_getattro(socketsClient_Object* self, PyObject* key) {
-    return PyObject_GenericGetAttr((PyObject*) self, key);
-  }
-
-
-  static int
-  socketsClient_setattro(socketsClient_Object* self, PyObject* key,
-                         PyObject* value) {
-    return PyObject_GenericSetAttr((PyObject*) self, key, value);
-  }
-  
-  
   /*
   #
   ###########################################################################
@@ -104,15 +112,15 @@
   };
 
 
-  PyTypeObject socketsClient_Type = {
+  socketsClient_TypeObject socketsClient_Type = { {
     PyVarObject_HEAD_INIT(NULL, 0)
     "concordance.sockets.Client",                /*tp_name*/
     sizeof(socketsClient_Object),                /*tp_basicsize*/
     0,                                           /*tp_itemsize*/
-    (destructor) socketsClient_dealloc,          /*tp_dealloc*/
+    (destructor) _dealloc,                       /*tp_dealloc*/
     0,                                           /*tp_print*/
-    (getattrfunc) 0,                             /*tp_getattr*/
-    (setattrfunc) 0,                             /*tp_setattr*/
+    0,                                           /*tp_getattr*/
+    0,                                           /*tp_setattr*/
     0,                                           /*tp_compare*/
     0,                                           /*tp_repr*/
     0,                                           /*tp_as_number*/
@@ -121,8 +129,8 @@
     0,                                           /*tp_hash*/
     0,                                           /*tp_call*/
     0,                                           /*tp_str*/
-    (getattrofunc) socketsClient_getattro,       /*tp_getattro*/
-    (setattrofunc) socketsClient_setattro,       /*tp_setattro*/
+    0,                                           /*tp_getattro*/
+    0,                                           /*tp_setattro*/
     0,                                           /*tp_as_buffer*/
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,    /*tp_flags*/
     socketsClient_Doc,                           /*tp_doc*/
@@ -135,14 +143,17 @@
     socketsClient_Methods,                       /*tp_methods*/
     0,                                           /*tp_members*/
     0,                                           /*tp_getset*/
-    &socketsSocket_Type,                         /*tp_base*/
+    (struct _typeobject*) &socketsSocket_Type,   /*tp_base*/
     0,                                           /*tp_dict*/
     0,                                           /*tp_descr_get*/
     0,                                           /*tp_descr_set*/
     0,                                           /*tp_dictoffset*/
-    socketsClient_init,                          /*tp_init*/
+    0,                                           /*tp_init*/
     0,                                           /*tp_alloc*/
-    socketsClient_new,                           /*tp_new*/
+    _new,                                        /*tp_new*/
     0,                                           /*tp_free*/
     0,                                           /*tp_is_gc*/
+    },
+    /* cdef classes */
+    _listenNew,
   };

Modified: trunk/concordance/src/sockets/Socket.c
===================================================================
--- trunk/concordance/src/sockets/Socket.c      2009-02-12 19:42:06 UTC (rev 
1513)
+++ trunk/concordance/src/sockets/Socket.c      2009-02-21 17:31:52 UTC (rev 
1514)
@@ -25,59 +25,14 @@
 cdef class Socket :                                                       \*/
   static char socketsSocket_Doc[] = "Test";
 
-
-  PyObject*
-  socketsSocket_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\
-    cdef :                                                                \*/
-      socketsSocket_Object*      self;
-  
-    /* first inherit base type */
-    self = (socketsSocket_Object*) PyType_GenericNew(type, args, kwds);
-    if (!self)
-      return NULL;
-
-    /* set addr, port, and sock to default values
-    
-       0.0.0.0 = listen to every available interface
-       port is overridden by child class
-    */
-    self->addr = "0.0.0.0";
-    self->port =  0;
-    self->sock = -1;
-
-    /* Get a reference to our local module
-    
-       This is to keep our module alive as long as this instance.
-       
-       PyObject*        PyImport_ImportModule    (const char *name);
-    */
-    self->module = PyImport_ImportModule("concordance.sockets");
-    
-    /* Get context from global state
-
-       I'm sorry for this.  Here's the natural language for this block:
-         1) get the state of sockets module - a PyObject** to concordance._core
-         2) dereference the PyObject** to PyObject*
-         3) get the state of _core - a concordGlobals**
-         4) dereference concordGlobals** to concordGlobals*
-         5) copy the GMainContext* context from the struct to self->context
-
-       void*            PyModule_GetState        (PyObject*);
-    */
-    self->context = (*(concordGlobals**) PyModule_GetState(
-                     *(PyObject**) PyModule_GetState(self->module)))->context;
-
-    /* return self */
-    return (PyObject*) self;
-  }
-
-
   static int
-  socketsSocket_init(PyObject* s, PyObject* args, PyObject* kwds) {       /*\
+  _init(PyObject* s, PyObject* args, PyObject* kwds) {                    /*\
     cdef :                                                                \*/
       socketsSocket_Object*      self = (socketsSocket_Object*) s;
       int                        ret;
       struct addrinfo*           resinfo = NULL;
+      GSource*                   source;
+      static char*               kwlist[] = {"bind", 0};
 
     /* parse arguments and keywords
 
@@ -101,7 +56,7 @@
             used as the function name in error messages (the “associated
             value” of the exception that PyArg_ParseTuple raises).
     */
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sH:Socket", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|(sH):Socket", kwlist,
                                      &self->addr, &self->port))
       return -1;
 
@@ -188,17 +143,38 @@
       if (bind(self->sock, resinfo->ai_addr, resinfo->ai_addrlen) == 0 &&
           listen(self->sock, 16) == 0 ) {
 
-        /* create channel and add it to our context watchlist
+        /* create a new channel using an OS-dependent function
 
-           GIOChannel*  concordAddSocket         (gint fd,
-                                                  GIOCondition condition,
-                                                  GSourceFunc callback,
-                                                  gpointer data,
-                                                  GMainContext* context);
+           GIOChannel*  g_io_channel_win32_new_fd     (gint fd);
+           GIOChannel*  g_io_channel_unix_new         (gint fd);
         */
-        self->chan = concordAddSocket(self->sock, G_IO_IN,
-                                      (GSourceFunc) concordCore_listenNew,
-                                      (gpointer) self, self->context);
+        #ifdef MS_WINDOWS
+          self->chan = g_io_channel_win32_new_socket(self->sock);
+        #else
+          self->chan = g_io_channel_unix_new(self->sock);
+        #endif
+
+        /* add a channel to our context watch
+
+           Note that this function is a replacement for g_io_add_watch() which
+           uses our own context rather than the default context.
+
+           GSource*     g_io_create_watch        (GIOChannel *channel,
+                                            GIOCondition condition);
+           void         g_source_set_callback    (GSource *source,
+                                            GSourceFunc func,
+                                            gpointer data,
+                                            GDestroyNotify notify);
+           guint        g_source_attach          (GSource *source,
+                                            GMainContext *context);
+        */
+        source = g_io_create_watch(self->chan, G_IO_IN);
+        g_source_set_callback(source, (GSourceFunc)
+                              ((socketsSocket_TypeObject*) s->ob_type)->
+                              _listenNew,
+                              (gpointer) self, NULL);
+        g_source_attach(source, self->context);
+        g_source_unref(source);
         ret = 0;
       }
       else {
@@ -222,37 +198,113 @@
   }
 
 
-  void
-  socketsSocket_dealloc(PyObject* s) {                                    /*\
+  static PyObject*
+  _getattro(PyObject* self, PyObject* key) {
+    return PyObject_GenericGetAttr((PyObject*) self, key);
+  }
+
+
+  static int
+  _setattro(PyObject* self, PyObject* key, PyObject* value) {
+    return PyObject_GenericSetAttr((PyObject*) self, key, value);
+  }
+
+  static gboolean
+  _listenNew(GIOChannel* channel, GIOCondition condition, gpointer s) {   /*\
     cdef :                                                                \*/
       socketsSocket_Object*      self = (socketsSocket_Object*) s;
+      gint                       socket;
+      struct sockaddr            addr;
+      guint                      addrlen = sizeof(addr);
 
-    /* close the socket if open */
-    if (self->sock > -1)
-      close(self->sock);
+    /* accept new connection, return if we fail to connect
 
-    /* decref our module handle, which may in-turn decref _core */
-    if (self->module)
-      Py_DECREF(self->module);
+       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+    */
+    if ((socket = accept(g_io_channel_unix_get_fd(channel),
+                         &addr, &addrlen))<0) {
+      /* return true so GMainLoop will continue watching this channel */
+      return TRUE;
+    }
 
-    /* lastly dealloc base type */   
-    PyObject_Del(s);
+    /* this is a generic Socket object, just close incoming connections */
+    close(socket);
+        
+    /* return true so GMainLoop will continue watching this channel */
+    return TRUE;
   }
 
 
+  /*
+  #
+  ###########################################################################
+  #
+  # object constructor - deconstructor
+  #                                                                        */
+
   static PyObject*
-  socketsSocket_getattro(socketsSocket_Object* self, PyObject* key) {
-    return PyObject_GenericGetAttr((PyObject*) self, key);
+  _new(PyTypeObject* type, PyObject* args, PyObject* kwds) {              /*\
+    cdef :                                                                \*/
+      socketsSocket_Object*      self;
+  
+    /* first inherit base type */
+    self = (socketsSocket_Object*) type->tp_base->tp_new(type, args, kwds);
+    if (!self)
+      return NULL;
+
+    /* set addr, port, and sock to default values
+    
+       0.0.0.0 = listen to every available interface
+       port is overridden by child class
+    */
+    self->addr = "0.0.0.0";
+    self->port =  0;
+    self->sock = -1;
+
+    /* Get a reference to our local module
+    
+       This is to keep our module alive as long as this instance.
+       
+       PyObject*        PyImport_ImportModule    (const char *name);
+    */
+    self->module = PyImport_ImportModule("concordance.sockets");
+    
+    /* Get context from global state
+
+       I'm sorry for this.  Here's the natural language for this block:
+         1) get the state of sockets module - a PyObject** to concordance._core
+         2) dereference the PyObject** to PyObject*
+         3) get the state of _core - a concordGlobals**
+         4) dereference concordGlobals** to concordGlobals*
+         5) copy the GMainContext* context from the struct to self->context
+
+       void*            PyModule_GetState        (PyObject*);
+    */
+    self->context = (*(concordGlobals**) PyModule_GetState(
+                     *(PyObject**) PyModule_GetState(self->module)))->context;
+
+    /* return self */
+    return (PyObject*) self;
   }
 
 
-  static int
-  socketsSocket_setattro(socketsSocket_Object* self, PyObject* key,
-                         PyObject* value) {
-    return PyObject_GenericSetAttr((PyObject*) self, key, value);
-  }
+  static void
+  _dealloc(PyObject* s) {                                                 /*\
+    cdef :                                                                \*/
+      socketsSocket_Object*      self = (socketsSocket_Object*) s;
+
+    /* close the socket if open */
+    if (self->sock > -1)
+      close(self->sock);
+
+    /* decref our module handle, which may in-turn decref _core */
+    if (self->module)
+      Py_DECREF(self->module);
+
+    /* lastly dealloc base type */  
+    s->ob_type->tp_base->tp_dealloc(s);
+  }  
   
-  
   /*
   #
   ###########################################################################
@@ -264,13 +316,12 @@
     { NULL, NULL },                              /* sentinel */
   };
 
-
-  PyTypeObject socketsSocket_Type = {
+  socketsSocket_TypeObject socketsSocket_Type = { {
     PyVarObject_HEAD_INIT(NULL, 0)
     "concordance.sockets.Socket",                /*tp_name*/
     sizeof(socketsSocket_Object),                /*tp_basicsize*/
     0,                                           /*tp_itemsize*/
-    (destructor) socketsSocket_dealloc,          /*tp_dealloc*/
+    (destructor) _dealloc,                       /*tp_dealloc*/
     0,                                           /*tp_print*/
     (getattrfunc) 0,                             /*tp_getattr*/
     (setattrfunc) 0,                             /*tp_setattr*/
@@ -282,8 +333,8 @@
     0,                                           /*tp_hash*/
     0,                                           /*tp_call*/
     0,                                           /*tp_str*/
-    (getattrofunc) socketsSocket_getattro,       /*tp_getattro*/
-    (setattrofunc) socketsSocket_setattro,       /*tp_setattro*/
+    _getattro,                                   /*tp_getattro*/
+    _setattro,                                   /*tp_setattro*/
     0,                                           /*tp_as_buffer*/
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,    /*tp_flags*/
     socketsSocket_Doc,                           /*tp_doc*/
@@ -301,9 +352,14 @@
     0,                                           /*tp_descr_get*/
     0,                                           /*tp_descr_set*/
     0,                                           /*tp_dictoffset*/
-    socketsSocket_init,                          /*tp_init*/
+    _init,                                       /*tp_init*/
     0,                                           /*tp_alloc*/
-    (newfunc) PyType_GenericNew,                 /*tp_new*/
+    _new,                                        /*tp_new*/
     0,                                           /*tp_free*/
     0,                                           /*tp_is_gc*/
+    },
+    /* cdef classes */
+    _listenNew,
   };
+  
+  

Modified: trunk/concordance/src/sockets/__init__.c
===================================================================
--- trunk/concordance/src/sockets/__init__.c    2009-02-12 19:42:06 UTC (rev 
1513)
+++ trunk/concordance/src/sockets/__init__.c    2009-02-21 17:31:52 UTC (rev 
1514)
@@ -65,9 +65,9 @@
        inherited slots from a type’s base class.
        Return 0 on success, or return -1 and sets an exception on error.
   */
-  if (PyType_Ready(&socketsSocket_Type) < 0)
+  if (PyType_Ready((PyTypeObject*) &socketsSocket_Type) < 0)
     return NULL;
-  if (PyType_Ready(&socketsClient_Type) < 0)
+  if (PyType_Ready((PyTypeObject*) &socketsClient_Type) < 0)
     return NULL;
 
   /* Get a handle to _core or fail

_______________________________________________
PySoy-SVN mailing list
PySoy-SVN@pysoy.org
http://www.pysoy.org/mailman/listinfo/pysoy-svn

Reply via email to