Author: ArcRiley Date: 2009-02-26 02:14:05 -0500 (Thu, 26 Feb 2009) New Revision: 1523
Added: trunk/concordance/src/services/Service.c Modified: trunk/concordance/include/concordance.h trunk/concordance/include/concordance.services.h trunk/concordance/setup.py trunk/concordance/src/services/__init__.c trunk/concordance/src/sockets/Client.c trunk/concordance/src/sockets/Socket.c trunk/concordance/src/sockets/__init__.c Log: added concordance.services.Service, now has basic domain lookup/response mech Modified: trunk/concordance/include/concordance.h =================================================================== --- trunk/concordance/include/concordance.h 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/include/concordance.h 2009-02-26 07:14:05 UTC (rev 1523) @@ -52,4 +52,5 @@ guint major; guint minor; } concordVersion; + #endif Modified: trunk/concordance/include/concordance.services.h =================================================================== --- trunk/concordance/include/concordance.services.h 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/include/concordance.services.h 2009-02-26 07:14:05 UTC (rev 1523) @@ -24,4 +24,17 @@ #include "concordance.h" +/* concordance.services.Service definition */ +typedef struct { + PyTypeObject base; +} servicesService_TypeObject; +extern servicesService_TypeObject servicesService_Type; +extern servicesService_TypeObject* servicesService_TypeP; +typedef struct { + PyObject_HEAD + PyObject* module; /* reference to our own module */ + gchar* domain; /* actual domain name */ +} servicesService_Object; +#define servicesService_Check(v) (Py_TYPE(v) == &servicesService_Type) + #endif Modified: trunk/concordance/setup.py =================================================================== --- trunk/concordance/setup.py 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/setup.py 2009-02-26 07:14:05 UTC (rev 1523) @@ -98,6 +98,7 @@ Extension( name = 'services', sources = ['src/services/__init__.c', + 'src/services/Service.c', 'src/utils.c', ], include_dirs = include_dirs, Added: trunk/concordance/src/services/Service.c =================================================================== --- trunk/concordance/src/services/Service.c (rev 0) +++ trunk/concordance/src/services/Service.c 2009-02-26 07:14:05 UTC (rev 1523) @@ -0,0 +1,174 @@ +/* +# Concordance XMPP Service Framework +# +# Copyright (C) 2009 Copyleft Games Group +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, see http://www.gnu.org/licenses +# +# $Id$ +*/ + +#include "concordance.services.h" + /*\ +cdef class Service : \*/ + static char servicesService_Doc[] = "Test"; + + static int + _init(PyObject* s, PyObject* args, PyObject* kwds) { /*\ + cdef : \*/ + servicesService_Object* self = (servicesService_Object*) s; + gchar* domain; + int ret; + static char* kwlist[] = {"domain", 0}; + + /* parse arguments and keywords + + From http://docs.python.org/3.0/c-api/arg.html : + s Convert a Python string or Unicode object to a C pointer to a + character string. You must not provide storage for the string + itself; a pointer to an existing string is stored into the + character pointer variable whose address you pass. The C string is + NUL-terminated. The Python string must not contain embedded NUL + bytes; if it does, a TypeError exception is raised. Unicode + objects are converted to C strings using the default encoding. If + this conversion fails, a UnicodeError is raised. + : The list of format units ends here; the string after the colon is + used as the function name in error messages (the “associated + value” of the exception that PyArg_ParseTuple raises). + */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:Service", kwlist, + &domain)) + return -1; + + /* copy domain string to self */ + self->domain = g_strdup(domain); + + return 0; + } + + + 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); + } + + /* + # + ########################################################################### + # + # object constructor - deconstructor + # */ + + static PyObject* + _new(PyTypeObject* type, PyObject* args, PyObject* kwds) { /*\ + cdef : \*/ + servicesService_Object* self; + + /* this is lowest level, just alloc */ + self = (servicesService_Object*) type->tp_alloc(type, 0); + if (!self) + return NULL; + + /* 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.services"); + + self->domain = NULL; + + /* return self */ + return (PyObject*) self; + } + + + static void + _dealloc(PyObject* s) { /*\ + cdef : \*/ + servicesService_Object* self = (servicesService_Object*) s; + + /* decref our module handle*/ + if (self->module) + Py_DECREF(self->module); + + if (self->domain) + g_free(self->domain); + + /* lastly delete the object */ + PyObject_Del(self); + } + + /* + # + ########################################################################### + # + # global structs + # */ + + static PyMethodDef servicesService_Methods[] = { + { NULL, NULL }, /* sentinel */ + }; + + servicesService_TypeObject servicesService_Type = { { + PyVarObject_HEAD_INIT(NULL, 0) + "concordance.services.Service", /*tp_name*/ + sizeof(servicesService_Object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + _dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + _getattro, /*tp_getattro*/ + _setattro, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + servicesService_Doc, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + servicesService_Methods, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + _init, /*tp_init*/ + 0, /*tp_alloc*/ + _new, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + }, + /* c methods */ + }; Modified: trunk/concordance/src/services/__init__.c =================================================================== --- trunk/concordance/src/services/__init__.c 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/src/services/__init__.c 2009-02-26 07:14:05 UTC (rev 1523) @@ -21,6 +21,8 @@ #include "concordance.services.h" +servicesService_TypeObject* servicesService_TypeP = &servicesService_Type; + static PyMethodDef services_Methods[] = { { NULL, NULL } }; @@ -29,7 +31,7 @@ PyModuleDef_HEAD_INIT, "services", /*m_name*/ "Test Help", /*m_doc*/ - -1, /*m_size*/ + 0, /*m_size*/ services_Methods, /*m_methods*/ NULL, /*m_reload*/ NULL, /*m_traverse*/ @@ -37,11 +39,27 @@ NULL /*m_free*/ }; + PyMODINIT_FUNC PyInit_services(void) { /*\ cdef : \*/ - PyObject* module; + PyObject* module; + /* Initialize Glib threading support + + gboolean g_thread_supported (); + This function returns TRUE if the thread system is initialized, and + FALSE if it is not. + + void g_thread_init (GThreadFunctions *vtable); + If you use GLib from more than one thread, you must initialize the + thread system by calling g_thread_init(). Most of the time you will + only have to call g_thread_init (NULL). + */ + if (!g_thread_supported()) g_thread_init(NULL); + + /* set pointers + /* Initialize all types prior to module creation int PyType_Ready(PyTypeObject*) @@ -50,25 +68,23 @@ inherited slots from a type’s base class. Return 0 on success, or return -1 and sets an exception on error. */ - //if (PyType_Ready(&concordCore_Type) < 0) - // return NULL; - + if (PyType_Ready((PyTypeObject*) servicesService_TypeP) < 0) + return NULL; - /* Create concordance.services module object + /* Create services module object PyObject* PyModule_Create(struct PyModuleDef*) */ module = PyModule_Create(&services_Module); - /* incref each extension type */ - //Py_INCREF(&concordCore_Type); + Py_INCREF(servicesService_TypeP); /* Add classes to the concordance module object int PyModule_AddObject(PyObject*, const char*, PyObject*); */ - //PyModule_AddObject(module, "Core", (PyObject*) &concordCore_Type); + PyModule_AddObject(module, "Service", (PyObject*) servicesService_TypeP); /* return the module object to Python */ return module; Modified: trunk/concordance/src/sockets/Client.c =================================================================== --- trunk/concordance/src/sockets/Client.c 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/src/sockets/Client.c 2009-02-26 07:14:05 UTC (rev 1523) @@ -20,6 +20,7 @@ */ #include "concordance.sockets.h" +#include "concordance.services.h" static void _xmlStart (gpointer, const XML_Char*, const XML_Char**); static void _xmlEnd (gpointer, const XML_Char*); @@ -343,16 +344,34 @@ static void _reply_stream(socketsClient_Data* session, gchar* to, gchar* version) { /*\ cdef : \*/ - socketsClient_Object* self = session->self; - GString* buff; - gchar* from; - guint major, minor; - gchar** versions; - gchar* error = NULL; + socketsClient_Object* self = session->self; + GString* buff; + servicesService_Object* service; + gchar* from; + guint major, minor; + gchar** versions; + gchar* error = NULL; /* generate random session key */ concordRandKey(session->skey); + /* lookup domain mapping */ + if (to) { + service = (servicesService_Object*) + g_hash_table_lookup(self->domains, (gconstpointer) to); + if (service) { + from = service->domain; + } + else { + from = to; + error = "host-unknown"; + } + } + else { + from = ""; + error = "host-unknown"; + } + /* initialize response buffer GString* g_string_new (const gchar *init); @@ -370,7 +389,7 @@ "<stream:stream xmlns='jabber:client'" " xmlns:stream='http://etherx.jabber.org/streams'" " from='%s' id='%s'", - "selket.apogean.org", session->skey); + from, session->skey); /* Parse version: * NULL is passed, meaning the version attribute was not found, so: Modified: trunk/concordance/src/sockets/Socket.c =================================================================== --- trunk/concordance/src/sockets/Socket.c 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/src/sockets/Socket.c 2009-02-26 07:14:05 UTC (rev 1523) @@ -20,7 +20,7 @@ */ #include "concordance.sockets.h" - +#include "concordance.services.h" /*\ cdef class Socket : \*/ static char socketsSocket_Doc[] = "Test"; @@ -385,18 +385,29 @@ PyErr_SetString(PyExc_TypeError, "key must be a string"); return -1; } - /* test value */ /* get the UTF8 key */ key = concordPyUnicodeToUTF8(k); if (val) { + /* ensure value is a concordance service + + int PyObject_IsInstance (PyObject *inst, + PyObject *cls); + */ + if (PyObject_IsInstance(val, (PyObject*) servicesService_TypeP) != 1) { + g_free(key); + PyErr_SetString(PyExc_ValueError, + "domain is not a concordance services instance"); + return -1; + } /* insert key:value into table, freeing existing value if needed void g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value); */ + Py_INCREF(val); g_hash_table_insert(self->domains, (gpointer) key, (gpointer) val); } else { Modified: trunk/concordance/src/sockets/__init__.c =================================================================== --- trunk/concordance/src/sockets/__init__.c 2009-02-26 07:13:59 UTC (rev 1522) +++ trunk/concordance/src/sockets/__init__.c 2009-02-26 07:14:05 UTC (rev 1523) @@ -20,7 +20,10 @@ */ #include "concordance.sockets.h" +#include "concordance.services.h" +/* types from other extensions */ +servicesService_TypeObject* servicesService_TypeP = NULL; static PyMethodDef sockets_Methods[] = { { NULL, NULL } @@ -44,8 +47,9 @@ cdef : \*/ PyObject* module; sockets_State* state; + Gsasl* saslCntx; PyObject* _core; - Gsasl* saslCntx; + PyObject* services; /* Initialize Glib threading support @@ -83,13 +87,21 @@ return NULL; } - /* Get a handle to _core or fail + /* Get a handle to linked extensions or fail PyObject* PyImport_ImportModule (const char *name); */ if (!(_core = PyImport_ImportModule("concordance._core"))) return NULL; + if (!(services = PyImport_ImportModule("concordance.services"))) + return NULL; + /* Copy pointer to external types + + */ + servicesService_TypeP = (servicesService_TypeObject*) + PyObject_GetAttrString(services, "Service"); + /* Create concordance module object PyObject* PyModule_Create(struct PyModuleDef*) _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn