Author: ArcRiley Date: 2009-01-06 00:46:26 -0500 (Tue, 06 Jan 2009) New Revision: 1427
Modified: trunk/concordance/src/Core.c trunk/concordance/src/Core.h Log: very basic XML steam processing now using expat Modified: trunk/concordance/src/Core.c =================================================================== --- trunk/concordance/src/Core.c 2009-01-06 05:45:53 UTC (rev 1426) +++ trunk/concordance/src/Core.c 2009-01-06 05:46:26 UTC (rev 1427) @@ -19,32 +19,16 @@ # $Id$ */ -#include "Python.h" -#include "glib.h" - -#ifdef MS_WINDOWS - -#include <ws2tcpip.h> -#include <Winsock2.h> -//#define wsa_get_ready() if( !wsa_is_ready ) {WSADATA wd; WSAStartup( MAKEWORD(2,2), &wd ); wsa_is_ready = 1; } -WSADATA wsaData; - - -#else - -#include <sys/socket.h> -#include <netdb.h> - -#endif - #include "Core.h" #include "utils.h" - static gpointer conCore_loop (gpointer); static int conCore_listenChannel (conCoreObject*, conChannel*); static gboolean conCore_listenNew (GIOChannel*, GIOCondition, gpointer); static gboolean conCore_sessionData (GIOChannel*, GIOCondition, gpointer); +static void conCore_xmlStart (gpointer, const XML_Char*, + const XML_Char**); +static void conCore_xmlEnd (gpointer, const XML_Char *name); /*\ cdef class Core : \*/ @@ -334,7 +318,6 @@ gint fd; struct sockaddr addr; guint addrlen = sizeof(addr); - GIOChannel* newChannel; conSession* newSession; /* accept new connection, return if we fail to connect @@ -345,6 +328,7 @@ &addr, &addrlen))<0) return TRUE; + if (sourceChannel == self->c2s.chan) { /* create new session @@ -352,6 +336,12 @@ */ newSession = g_malloc(sizeof(conSession)); + + /* add self (Core object) to session */ + Py_INCREF(self); + newSession->core = self; + + /* lookup hostname int getnameinfo(const struct sockaddr *sa, socklen_t salen, @@ -360,6 +350,7 @@ */ ret = getnameinfo(&addr, addrlen, newSession->host, 255, NULL, 0, 0); + /* create channel and add it to our context watchlist GIOChannel* conAddSocket (gint fd, @@ -367,21 +358,41 @@ GSourceFunc callback, gpointer data, GMainContext* context); + GIOStatus g_io_channel_set_encoding(GIOChannel *channel, + const gchar *encoding, + GError **error); + void g_io_channel_set_buffered(GIOChannel *channel, + gboolean buffered); */ newSession->chan = conAddSocket(fd, G_IO_IN | G_IO_HUP, (GSourceFunc)conCore_sessionData, (gpointer) self, self->context); - g_io_channel_set_encoding(newSession->chan, NULL, NULL); g_io_channel_set_buffered(newSession->chan, FALSE); + + /* create the XML parser for this session + + XML_Parser XML_ParserCreate (const XML_Char *encoding); + void XML_SetUserData (XML_Parser parser, + void *userData); + void XML_SetElementHandler (XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + */ + newSession->pars = XML_ParserCreate(NULL); + XML_SetUserData(newSession->pars, newSession); + XML_SetElementHandler(newSession->pars, conCore_xmlStart, conCore_xmlEnd); + + /* add new channel to the channels hashtable void g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value); */ - g_hash_table_insert(self->channels, newChannel, newSession); + g_hash_table_insert(self->channels, newSession->chan, newSession); + newSession->depth = 0; /*temporary*/ printf("new client: %s\n", newSession->host); } else @@ -398,29 +409,39 @@ cdef : \*/ conCoreObject* self = (conCoreObject*) s; GIOStatus status; - gchar buff[1025]; + gchar buff[4096]; guint buff_len = 0; + conSession* session; + /* get session from hashtable + + gpointer g_hash_table_lookup (GHashTable *hash_table, + gconstpointer key); + */ + session = g_hash_table_lookup(self->channels, channel); + if (condition == G_IO_IN) { - /* read channel to buffer + /* read channel to parser GIOStatus g_io_channel_read_chars (GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read, GError **error); + XML_Status XML_Parse (XML_Parser parser, + const char *s, + int len, + int isFinal); */ - status = g_io_channel_read_chars(channel, buff, 1024, &buff_len, NULL); + status = g_io_channel_read_chars(channel, buff, 4096, &buff_len, NULL); if (status == G_IO_STATUS_NORMAL && buff_len > 0) { - buff[buff_len] = '\0'; - printf("%s\n", buff); - - /* return true so GMainLoop will continue watching this channel */ - return TRUE; + if (XML_Parse(session->pars, buff, buff_len, FALSE)) + /* return true so GMainLoop will continue watching this channel */ + return TRUE; } } - printf("end client\n"); + printf("Shutting down\n"); /* G_IO_EOF, read EOF, or an unknown channel error has occured GIOStatus g_io_channel_shutdown (GIOChannel *channel, @@ -429,11 +450,47 @@ */ g_io_channel_shutdown(channel, FALSE, NULL); + + /* close out parser cleanly + + void XML_ParserFree (XML_Parser parser); + */ + XML_Parse(session->pars, NULL, 0, TRUE); + XML_ParserFree(session->pars); + + /* return false so GMainLoop will stop watching this channel */ return FALSE; } + static void + conCore_xmlStart(gpointer s, const XML_Char* name, + const XML_Char** atts) { /*\ + cdef : \*/ + conSession* session = (conSession*) s; + conCoreObject* self = session->core; + gint i; /* temporary*/ + + /* this from http://www.xml.com/pub/a/1999/09/expat/index.html?page=2 */ + for (i = 0; i < session->depth; i++) + printf(" "); + printf("%s", name); + for (i = 0; atts[i]; i += 2) + printf(" %s='%s'", atts[i], atts[i + 1]); + printf("\n"); + session->depth++; + } + + + static void + conCore_xmlEnd(gpointer s, const XML_Char* name) { /*\ + cdef : \*/ + conSession* session = (conSession*) s; + conCoreObject* self = session->core; + session->depth--; + } + static PyMethodDef conCore_methods[] = { { NULL, NULL }, }; Modified: trunk/concordance/src/Core.h =================================================================== --- trunk/concordance/src/Core.h 2009-01-06 05:45:53 UTC (rev 1426) +++ trunk/concordance/src/Core.h 2009-01-06 05:46:26 UTC (rev 1427) @@ -22,6 +22,20 @@ #ifndef CONCORE_H #define CONCORE_H +#include "Python.h" +#include "glib.h" +#include "expat.h" +#ifdef MS_WINDOWS +#include <ws2tcpip.h> +#include <Winsock2.h> +//#define wsa_get_ready() if( !wsa_is_ready ) {WSADATA wd; WSAStartup( MAKEWORD(2,2), &wd ); wsa_is_ready = 1; } +WSADATA wsaData; +#else +#include <sys/socket.h> +#include <netdb.h> +#endif + + typedef struct { GIOChannel* chan; const gchar* addr; @@ -30,21 +44,24 @@ } conChannel; typedef struct { - PyObject* self; - GIOChannel* chan; - gchar host[256]; -} conSession; - -typedef struct { PyObject_HEAD - conChannel c2s; - conChannel s2s; - GHashTable* channels; - GMainContext* context; - GMainLoop* mainloop; - GThread* thread; + conChannel c2s; /* xmpp-client listening port */ + conChannel s2s; /* xmpp-server listening port */ + GHashTable* channels; /* channels to sessions hash table */ + GMainContext* context; /* each Core has it's own Glib context */ + GMainLoop* mainloop; /* handle to this core's Glim mainloop */ + GThread* thread; /* thread ID for mainloop thread */ } conCoreObject; +typedef struct { + PyObject* self; /* Session object for this or NULL */ + conCoreObject* core; /* Core this session belongs to */ + GIOChannel* chan; /* Glib IO channel for this session */ + XML_Parser pars; /* expat parser for this session */ + gchar host[256]; /* verified hostname or NULL */ + gint depth; /* temporary */ +} conSession; + PyTypeObject conCore_Type; #define conCoreObject_Check(v) (Py_TYPE(v) == &conCore_Type) _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn