summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2008-09-30 12:49:34 +0000
committerdeva <deva>2008-09-30 12:49:34 +0000
commite2120257dda4d91b48bb031a96edda810ce30dfb (patch)
treef83eadbbb6d84fd0d6fb7d7a4d3e342535854795
parenta01f655935558e0f71253907fd8e4c57b0d2f64c (diff)
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.
-rw-r--r--server/src/queryhandler.cc62
-rw-r--r--server/src/queryhandler.h9
-rw-r--r--server/src/queryparser.cc15
-rw-r--r--server/src/queryparser.h5
-rw-r--r--server/src/saxparser.cc39
-rw-r--r--server/src/saxparser.h11
-rw-r--r--server/src/server.cc27
-rw-r--r--server/src/transactionparser.cc40
-rw-r--r--server/src/transactionparser.h11
9 files changed, 88 insertions, 131 deletions
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 <sys/ioctl.h>
+#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, " <pentominos:query format=\"pracroxml\"\n"
- " device_id=\"%s\"\n"
- " device_type=\"%s\"\n"
- " filter=\"latest\"\n"
- " location=\"all\"/>\n",
- query.attributes["class"].c_str(),
- query.attributes["class"].c_str());
-
+ sprintf(buf, " <pentominos:query format=\"pracroxml\"\n"
+ " device_id=\"%s\"\n"
+ " device_type=\"%s\"\n"
+ " filter=\"latest\"\n"
+ " location=\"all\"/>\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, "</artefact>\n");
+ sprintf(buf, "</artefact>");
#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 <vector>
#include <string>
@@ -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 = "<xml></xml>";
-
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__*/