From e2120257dda4d91b48bb031a96edda810ce30dfb Mon Sep 17 00:00:00 2001 From: deva Date: Tue, 30 Sep 2008 12:49:34 +0000 Subject: Changed SAXParser parse method to take a buffer and a size instead of a c++ string. Made the queryhandler use a read loop, parsing on-the-fly to determine when the entire document has been read. --- server/src/queryhandler.cc | 62 ++++++++++++++++++----------------------- server/src/queryhandler.h | 9 ++---- server/src/queryparser.cc | 15 +--------- server/src/queryparser.h | 5 +--- server/src/saxparser.cc | 39 ++++++++++++++++++++++++++ server/src/saxparser.h | 11 ++++++++ server/src/server.cc | 27 ++++-------------- server/src/transactionparser.cc | 40 -------------------------- server/src/transactionparser.h | 11 -------- 9 files changed, 88 insertions(+), 131 deletions(-) (limited to 'server') diff --git a/server/src/queryhandler.cc b/server/src/queryhandler.cc index 29e8fda..248f1e6 100644 --- a/server/src/queryhandler.cc +++ b/server/src/queryhandler.cc @@ -54,6 +54,8 @@ // For ioctl #include +#include "queryparser.h" + typedef struct { in_addr_t ip; time_t time; @@ -138,12 +140,7 @@ QueryHandler::QueryHandler(TCPSocket *socket, std::string cpr) this->socket = socket; } -void QueryHandler::addQuery(Query &query) -{ - queries.push_back(query); -} - -std::string QueryHandler::exec() +QueryResult QueryHandler::exec(Query &query) { time_t timestamp = time(NULL); std::string uid = getUID("eth0"); @@ -186,56 +183,51 @@ std::string QueryHandler::exec() printf(buf); #endif/*WITH_DEBUG*/ - std::vector< Query >::iterator j = queries.begin(); - while(j != queries.end()) { - Query query = *j; - - sprintf(buf, " \n", - query.attributes["class"].c_str(), - query.attributes["class"].c_str()); - + sprintf(buf, " \n", + query.attributes["class"].c_str(), + query.attributes["class"].c_str()); + #ifndef WITHOUT_PENTOMINOS - socket->write(buf, strlen(buf)); + socket->write(buf, strlen(buf)); #endif/*WITHOUT_PENTOMINOS*/ #ifdef WITH_DEBUG - printf(buf); + printf(buf); #endif/*WITH_DEBUG*/ - j++; - } - - sprintf(buf, "\n"); + sprintf(buf, ""); #ifndef WITHOUT_PENTOMINOS socket->write(buf, strlen(buf)); - // Terminate - char term[] = "\0"; - socket->write(term, 1); #endif/*WITHOUT_PENTOMINOS*/ #ifdef WITH_DEBUG printf(buf); #endif/*WITH_DEBUG*/ - std::string answer; + QueryResult result; #ifndef WITHOUT_PENTOMINOS - // Wait for answer + QueryParser parser; + + int asize; char abuf[64]; - int res; - do { + memset(abuf, 0, sizeof(abuf)); + + // Read until we've got the entire result. + while((asize = socket->read(abuf, sizeof(abuf) - 1)) != -1 && + parser.parse(abuf, asize) == false) { memset(abuf, 0, sizeof(abuf)); - res = socket->read(abuf, sizeof(abuf) - 1); - answer += abuf; - } while(res); + } + + result = parser.result; #endif/*WITHOUT_PENTOMINOS*/ - return answer; + return result; } #ifdef TEST_QUERYHANDLER diff --git a/server/src/queryhandler.h b/server/src/queryhandler.h index 8217f40..bb0be8f 100644 --- a/server/src/queryhandler.h +++ b/server/src/queryhandler.h @@ -29,6 +29,7 @@ #include "tcpsocket.h" #include "template.h" +#include "queryresult.h" #include #include @@ -40,17 +41,13 @@ class QueryHandler { public: QueryHandler(TCPSocket *socket, std::string cpr); - // Add a query to the query queue - void addQuery(Query &query); - // Execute all queries. - std::string exec(); + // std::string exec(); + QueryResult exec(Query &query); private: TCPSocket *socket; std::string cpr; - - std::vector< Query > queries; }; #endif/*__PRACRO_QUERYHANDLER_H__*/ diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc index 0135515..abb41b5 100644 --- a/server/src/queryparser.cc +++ b/server/src/queryparser.cc @@ -26,14 +26,10 @@ */ #include "queryparser.h" -QueryParser::QueryParser(std::string document) +QueryParser::QueryParser() { - this->document = document; this->timestamp = 0; - // Make sure we always contain a valid xml document. - if(this->document == "") this->document = ""; - p = 0; stack.push_back(&result); } @@ -72,15 +68,6 @@ void QueryParser::endTag(std::string name) if(name == "group") stack.pop_back(); } -// FIXME: This is *not* the optimal way to do this. -int QueryParser::readData(char *data, size_t size) -{ - size_t len = document.size() - p < size ? document.size() - p : size; - strncpy(data, document.c_str() + p, len); - p += len; - return len; -} - void QueryParser::parseError(char *buf, size_t len, std::string error, int lineno) { fprintf(stderr, "QueryParser error at line %d: %s\n", lineno, error.c_str()); diff --git a/server/src/queryparser.h b/server/src/queryparser.h index ea952e7..b550a5f 100644 --- a/server/src/queryparser.h +++ b/server/src/queryparser.h @@ -39,7 +39,7 @@ */ class QueryParser : public SAXParser { public: - QueryParser(std::string document); + QueryParser(); void startTag(std::string name, std::map< std::string, std::string> attributes); void endTag(std::string name); @@ -47,9 +47,6 @@ public: QueryResult result; -protected: - int readData(char *data, size_t size); - private: // For read int p; diff --git a/server/src/saxparser.cc b/server/src/saxparser.cc index 43b6ba3..be7a541 100644 --- a/server/src/saxparser.cc +++ b/server/src/saxparser.cc @@ -51,6 +51,8 @@ static void start_hndl(void *p, const char *el, const char **attr) attributes.insert(make_pair(at_name, at_value)); } + if(parser->outertag == "") parser->outertag = name; + parser->startTag(name, attributes); } @@ -58,6 +60,9 @@ static void end_hndl(void *p, const char *el) { SAXParser *parser = (SAXParser*)XML_GetUserData(p); std::string name = el; + + if(name == parser->outertag) parser->done = true; + parser->endTag(name); } @@ -75,6 +80,11 @@ SAXParser::SAXParser() XML_UseParserAsHandlerArg(p); XML_SetElementHandler(p, start_hndl, end_hndl); XML_SetCharacterDataHandler(p, character_hndl); + + bufferbytes = 0; + totalbytes = 0; + done = false; + } SAXParser::~SAXParser() @@ -100,6 +110,30 @@ int SAXParser::parse() return 0; } +bool SAXParser::parse(char *data, size_t size) +{ + bufferbytes = size; + totalbytes += bufferbytes; + + if(! XML_Parse(p, data, size, false) ) { + if(XML_GetErrorCode(p) == XML_ERROR_JUNK_AFTER_DOC_ELEMENT) return true; + parseError(data, size, XML_ErrorString(XML_GetErrorCode(p)), (int)XML_GetCurrentLineNumber(p)); + return false; + } + + if(done) { + if(! XML_Parse(p, data, 0, true) ) { + if(XML_GetErrorCode(p) == XML_ERROR_JUNK_AFTER_DOC_ELEMENT) return true; + parseError(data, 0, XML_ErrorString(XML_GetErrorCode(p)), (int)XML_GetCurrentLineNumber(p)); + return false; + } + } + + printf("Got END_OF_DOCUMENT [%s] at %ld\n", outertag.c_str(), XML_GetCurrentByteIndex(p)); + + return done; +} + void SAXParser::parseError(char *buf, size_t len, std::string error, int lineno) { fprintf(stderr, "SAXParser error at line %d: %s\n", lineno, error.c_str()); @@ -109,6 +143,11 @@ void SAXParser::parseError(char *buf, size_t len, std::string error, int lineno) fflush(stderr); } +unsigned int SAXParser::usedBytes() +{ + return bufferbytes + (XML_GetCurrentByteIndex(p) - totalbytes); +} + #ifdef TEST_SAXPARSER /** diff --git a/server/src/saxparser.h b/server/src/saxparser.h index 67a86b7..da33440 100644 --- a/server/src/saxparser.h +++ b/server/src/saxparser.h @@ -44,10 +44,21 @@ public: virtual void parseError(char *buf, size_t len, std::string error, int lineno); + bool parse(char *buf, size_t size); + + unsigned int usedBytes(); + + // private stuff that needs to be public! + std::string outertag; + bool done; + protected: virtual int readData(char *data, size_t size) { return 0; } XML_Parser p; + + unsigned int bufferbytes; + unsigned int totalbytes; }; #endif/*__PRACRO_SAXPARSER_H__*/ diff --git a/server/src/server.cc b/server/src/server.cc index e4a470e..64ee709 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -173,21 +173,9 @@ static std::string handleTransaction(Transaction &transaction) s.connect(Conf::pentominos_addr, Conf::pentominos_port); #endif/*WITHOUT_PENTOMINOS*/ QueryHandler qh(&s, transaction.cpr); - /////////////////////////////// - - qh.addQuery(*qi); - - std::string result = qh.exec(); - printf("Got result: [%s]\n", result.c_str()); - ///////////////////////// - ///////////////////////// - // Parse the result from the queries to pentominos - QueryParser qp(result); - qp.parse(); - // Map the results - lqm.addQueryResult(qp.result); - //////////////////////// + QueryResult queryresult = qh.exec(*qi); + lqm.addQueryResult(queryresult); qi++; } @@ -269,17 +257,11 @@ static void handleConnection(TCPSocket *socket) } printf("Got %d bytes in read loop\n", size); - size = 0; - if(parser->parse(buf)) { + if(parser->parse(buf, size)) { printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!! Got complete XML document %d bytes used, %d bytes in current buffer.\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", parser->usedBytes(), strlen(buf)); - if(parser->usedBytes() < strlen(buf)) { - size = strlen(buf) - parser->usedBytes(); - strcpy(buf, buf + parser->usedBytes()); - } - socket->write(handleTransaction(*transaction)); delete transaction; @@ -288,6 +270,9 @@ static void handleConnection(TCPSocket *socket) delete parser; parser = NULL; } + + size = size - parser->usedBytes(); + if(size) memcpy(buf, buf + parser->usedBytes(), size); } memset(buf, 0, bufsize); } diff --git a/server/src/transactionparser.cc b/server/src/transactionparser.cc index 2ba4fc4..78c9b21 100644 --- a/server/src/transactionparser.cc +++ b/server/src/transactionparser.cc @@ -71,41 +71,6 @@ void TransactionParser::startTag(std::string name, std::map< std::string, std::s } } -void TransactionParser::endTag(std::string name) -{ - if(name == "pracro") done = true; -} - -int TransactionParser::readData(char *data, size_t size) -{ - printf("readData is not uasble with transaction parser!.\nUse parse(std::string) instead.\n"); - return 0; -} - -bool TransactionParser::parse(std::string data) -{ - bufferbytes = data.length(); - totalbytes += bufferbytes; - - if(! XML_Parse(p, (char*)data.c_str(), data.size(), false) ) { - if(XML_GetErrorCode(p) == XML_ERROR_JUNK_AFTER_DOC_ELEMENT) return true; - parseError((char*)data.c_str(), data.size(), XML_ErrorString(XML_GetErrorCode(p)), (int)XML_GetCurrentLineNumber(p)); - return false; - } - - if(done) { - if(! XML_Parse(p, (char*)data.c_str(), 0, true) ) { - if(XML_GetErrorCode(p) == XML_ERROR_JUNK_AFTER_DOC_ELEMENT) return true; - parseError((char*)data.c_str(), 0, XML_ErrorString(XML_GetErrorCode(p)), (int)XML_GetCurrentLineNumber(p)); - return false; - } - } - - printf("Got END_OF_TEMPLATE at %ld\n", XML_GetCurrentByteIndex(p)); - - return done; -} - void TransactionParser::parseError(char *buf, size_t len, std::string error, int lineno) { fprintf(stderr, "TransactionParser error at line %d: %s\n", lineno, error.c_str()); @@ -114,8 +79,3 @@ void TransactionParser::parseError(char *buf, size_t len, std::string error, int fprintf(stderr, "]\n"); fflush(stderr); } - -unsigned int TransactionParser::usedBytes() -{ - return bufferbytes + (XML_GetCurrentByteIndex(p) - totalbytes); -} diff --git a/server/src/transactionparser.h b/server/src/transactionparser.h index 1f7d23f..5a3beb3 100644 --- a/server/src/transactionparser.h +++ b/server/src/transactionparser.h @@ -37,22 +37,11 @@ public: ~TransactionParser(); void startTag(std::string name, std::map< std::string, std::string> attributes); - void endTag(std::string name); void parseError(char *buf, size_t len, std::string error, int lineno); - bool parse(std::string data); - - unsigned int usedBytes(); - -protected: - int readData(char *data, size_t size); - private: - unsigned int bufferbytes; - unsigned int totalbytes; Transaction *transaction; - bool done; }; #endif/*__PRACRO_TRANSACTIONPARSER_H__*/ -- cgit v1.2.3