diff options
| -rw-r--r-- | server/src/Makefile.am | 2 | ||||
| -rw-r--r-- | server/src/macro_parser.cc | 145 | ||||
| -rw-r--r-- | server/src/macro_parser.h | 20 | ||||
| -rw-r--r-- | server/src/sax_parser.cc | 125 | ||||
| -rw-r--r-- | server/src/sax_parser.h | 50 | ||||
| -rw-r--r-- | server/src/server.cc | 9 | ||||
| -rw-r--r-- | server/src/xmlparser.cc | 79 | ||||
| -rw-r--r-- | server/src/xmlparser.h | 17 | 
8 files changed, 271 insertions, 176 deletions
| diff --git a/server/src/Makefile.am b/server/src/Makefile.am index f145250..f06cbb9 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -15,6 +15,7 @@ pracrod_SOURCES = \  	log.cc \  	macro_parser.cc \  	resumeparser.cc \ +	sax_parser.cc \  	server.cc \  	tcpsocket.cc \  	tostring.cc \ @@ -32,6 +33,7 @@ EXTRA_DIST = \  	macro.h \  	macro_parser.h \  	resumeparser.h \ +	sax_parser.h \  	server.h \  	tcpsocket.h \  	tostring.h \ diff --git a/server/src/macro_parser.cc b/server/src/macro_parser.cc index aba7fda..84572d3 100644 --- a/server/src/macro_parser.cc +++ b/server/src/macro_parser.cc @@ -37,47 +37,41 @@  #include <stdio.h>  #include <string.h> -#include <expat.h> -#include <string> -#include <map> - -class MacroParser { -public: -  Macro *macro; -  std::vector< Widget* > stack; -  bool done; -}; - -static void start_hndl(void *p, const char *el, const char **attr) +MacroParser::MacroParser(std::string name, Macro ¯o)  { -  MacroParser *parser = (MacroParser*)XML_GetUserData(p); - -  //  printf("Start tag [%s]\n", el); +  this->macro = ¯o; -  // Convert to comfy C++ values... -  std::string name = el; -  std::map< std::string, std::string > attributes; - -  while(*attr) { -    std::string at_name = *attr; -    attr++; -    std::string at_value = *attr; -    attr++; +  std::string macrofile = std::string(XML) + "/" + name + ".xml"; +  fd = open(macrofile.c_str(), O_RDONLY); -    attributes.insert(make_pair(at_name, at_value)); +  if(fd == -1) { +    printf("Cannot open file \"%s\"...", macrofile.c_str()); +    printf("failed!\n"); +    return;    } +} -  // Do something reasonable with them... +MacroParser::~MacroParser() +{ +  if(fd != -1) close(fd); +} -  if(name == "include") { +int MacroParser::readData(char *data, size_t size) +{ +  return read(fd, data, size); +} +void MacroParser::startTag(std::string name, std::map< std::string, std::string> attributes) +{ +  if(name == "include") {      Macro inc; -    parse_macro(attributes["name"], inc); +    MacroParser parser(attributes["name"], inc); +    parser.parse();      WidgetList::iterator w = inc.widgets.front().widgets.begin();      while(w != inc.widgets.front().widgets.end()) { -      parser->stack.back()->widgets.push_back(*w); +      stack.back()->widgets.push_back(*w);        w++;      } @@ -86,9 +80,9 @@ static void start_hndl(void *p, const char *el, const char **attr)    if(name == "macro") { -    parser->macro->name = attributes["name"]; -    parser->macro->version = attributes["version"]; -    parser->macro->format = attributes["resume"]; +    macro->name = attributes["name"]; +    macro->version = attributes["version"]; +    macro->format = attributes["resume"];      return; // Don't do further parsing of this tag.    } @@ -110,14 +104,14 @@ static void start_hndl(void *p, const char *el, const char **attr)      Widget macrolist;      Widget *wp; -    if(parser->stack.size() > 0) {// We only pushback the child if there is a parent. -      parser->stack.back()->widgets.push_back(macrolist); -      wp = &parser->stack.back()->widgets.back(); +    if(stack.size() > 0) {// We only pushback the child if there is a parent. +      stack.back()->widgets.push_back(macrolist); +      wp = &stack.back()->widgets.back();      } else { -      parser->macro->widgets.push_back(macrolist); -      wp = &parser->macro->widgets.back(); +      macro->widgets.push_back(macrolist); +      wp = ¯o->widgets.back();      } -    parser->stack.push_back(wp); +    stack.push_back(wp);      wp->type = "listbox";      wp->properties["name"] = attributes["name"]; @@ -187,82 +181,25 @@ static void start_hndl(void *p, const char *el, const char **attr)    Widget *wp; -  if(parser->stack.size() > 0) {// We only pushback the child if there is a parent. -    parser->stack.back()->widgets.push_back(widget); -    wp = &parser->stack.back()->widgets.back(); +  if(stack.size() > 0) {// We only pushback the child if there is a parent. +    stack.back()->widgets.push_back(widget); +    wp = &stack.back()->widgets.back();    } else { -    parser->macro->widgets.push_back(widget); -    wp = &parser->macro->widgets.back(); +    macro->widgets.push_back(widget); +    wp = ¯o->widgets.back();    } -  parser->stack.push_back(wp); +  stack.push_back(wp);    std::map< std::string, std::string >::iterator i = attributes.begin();    while(i != attributes.end()) { -    //    WidgetProperty prop; -    //    prop.name = i->first; -    //    prop.value = i->second; -    //    wp->properties.push_back(prop);      wp->properties[i->first] = i->second;      i++;    }  } -static void end_hndl(void *p, const char *el) -{ -  MacroParser *parser = (MacroParser*)XML_GetUserData(p); -  -  //  printf("End tag [%s]\n", el); - -  if(std::string("include") != el) parser->stack.pop_back(); - -  if(!strcmp(el, "macro")) parser->done = true; -} - -void parse_macro(std::string name, Macro ¯o) +void MacroParser::endTag(std::string name)  { - -  XML_Parser p = XML_ParserCreate(NULL); -  if (! p) { -    fprintf(stderr, "Couldn't allocate memory for parser\n"); -    // throw Exception(...); -    return; -  } - -  MacroParser parser; -  parser.macro = ¯o; -  parser.done = false; - -  XML_SetUserData(p, &parser); -  XML_UseParserAsHandlerArg(p); -  XML_SetElementHandler(p, start_hndl, end_hndl); - -  std::string macrofile = std::string(XML) + "/" + name + ".xml"; -  int fd = open(macrofile.c_str(), O_RDONLY); - -  if(fd == -1) { -    printf("Cannot open file \"%s\"...", macrofile.c_str()); -    printf("failed!\n"); -    return; -  } - -  while(!parser.done) { -    char buf[32]; -    int len; - -    memset(buf, 0, sizeof(buf)); -    len = read(fd, buf, sizeof(buf) - 1); - -    parser.done = len == 0; - -    if (! XML_Parse(p, buf, len, parser.done)) { -      fprintf(stderr, "Parse error at line %d:\n%s\n", -	      XML_GetCurrentLineNumber(p), -	      XML_ErrorString(XML_GetErrorCode(p))); -      // throw Exception(...); -      return; -    } -  } - -  //  printf("%d requests\n", transaction.requests.size()); +  if(name != "include") stack.pop_back(); +  //  if(!strcmp(el, "macro")) done = true;  } diff --git a/server/src/macro_parser.h b/server/src/macro_parser.h index 9f701d4..248e586 100644 --- a/server/src/macro_parser.h +++ b/server/src/macro_parser.h @@ -29,8 +29,26 @@  #include <string> +#include "sax_parser.h"  #include "macro.h" -void parse_macro(std::string name, Macro ¯o); +class MacroParser : public SAXParser { +public: +  MacroParser(std::string name, Macro ¯o); +  ~MacroParser(); + +  void startTag(std::string name, std::map< std::string, std::string> attributes); +  void endTag(std::string name); + +protected: +  int readData(char *data, size_t size); + +private: +  Macro *macro; +  std::vector< Widget* > stack; +  bool done; + +  int fd; +};  #endif/*__PRACRO_MACRO_PARSER_H__*/ diff --git a/server/src/sax_parser.cc b/server/src/sax_parser.cc new file mode 100644 index 0000000..dd0a7a3 --- /dev/null +++ b/server/src/sax_parser.cc @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            sax_parser.cc + * + *  Mon Mar 24 14:40:15 CET 2008 + *  Copyright 2008 Bent Bisballe Nyeng, Lars Bisballe Jensen and Peter Skaarup + *  deva@aasimon.org, elsenator@gmail.com and piparum@piparum.dk + ****************************************************************************/ + +/* + *  This file is part of Pracro. + * + *  Pracro is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  Pracro 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 General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Pracro; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#include "sax_parser.h" + +static void start_hndl(void *p, const char *el, const char **attr) +{ +  SAXParser *parser = (SAXParser*)XML_GetUserData(p); + +  // Convert to comfy C++ values... +  std::string name = el; +  std::map< std::string, std::string > attributes; + +  while(*attr) { +    std::string at_name = *attr; +    attr++; +    std::string at_value = *attr; +    attr++; + +    attributes.insert(make_pair(at_name, at_value)); +  } + +  parser->startTag(name, attributes); +} + +static void end_hndl(void *p, const char *el) +{ +  SAXParser *parser = (SAXParser*)XML_GetUserData(p); +  std::string name = el; +  parser->endTag(name); +} + + +SAXParser::SAXParser() +{ +  p = XML_ParserCreate(NULL); +  if(!p) { +    fprintf(stderr, "Couldn't allocate memory for parser\n"); +    // throw Exception(...); +    return; +  } + +  XML_SetUserData(p, this); +  XML_UseParserAsHandlerArg(p); +  XML_SetElementHandler(p, start_hndl, end_hndl); +} + +int SAXParser::parse() +{ +  char buf[32]; +  int len; +   +  do { +    len = readData(buf, sizeof(buf) - 1); +    if (! XML_Parse(p, buf, len, len == 0)) { +      fprintf(stderr, "Parse error at line %d:\n%s\n", +              XML_GetCurrentLineNumber(p), +              XML_ErrorString(XML_GetErrorCode(p))); +      return -1; +    } + +    memset(buf, 0, sizeof(buf)); +  } while(len); + +  return 0; +} + +#ifdef TEST_SAXPARSER +/** + * Compile with: g++ -DTEST_SAXPARSER sax_parser.cc -lexpat -otext_saxparser + * Run with: ./test_saxparser [xmlfile] + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +class MyParser :public SAXParser { +public: +  MyParser(char *file) { +    fd = open(file, O_RDONLY); +  } + +  int readData(char *data, size_t size) { +    return read(fd, data, size); +  } + +  void startTag(std::string name, std::map< std::string, std::string> attributes) +  { +    printf("<%s>\n", name.c_str()); +  } + +private: +  int fd; +}; + +int main(int argc, char *argv[]) { +  if(argc < 2) return 1; +  MyParser parser(argv[1]); +  parser.parse(); +} + +#endif/*TEST_SAXPARSER*/ diff --git a/server/src/sax_parser.h b/server/src/sax_parser.h new file mode 100644 index 0000000..b6b48ba --- /dev/null +++ b/server/src/sax_parser.h @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + *            sax_parser.h + * + *  Mon Mar 24 14:40:15 CET 2008 + *  Copyright 2008 Bent Bisballe Nyeng, Lars Bisballe Jensen and Peter Skaarup + *  deva@aasimon.org, elsenator@gmail.com and piparum@piparum.dk + ****************************************************************************/ + +/* + *  This file is part of Pracro. + * + *  Pracro is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  Pracro 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 General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Pracro; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. + */ +#ifndef __PRACRO_SAX_PARSER_H__ +#define __PRACRO_SAX_PARSER_H__ + +#include <string> +#include <map> +#include <expat.h> + +class SAXParser { +public: +  SAXParser(); + +  int parse(); + +  virtual void startTag(std::string name, std::map< std::string, std::string> attributes) {} +  virtual void endTag(std::string name) {} + +protected: +  virtual int readData(char *data, size_t size) { return 0; } + +private: +  XML_Parser p; +}; + +#endif/*__PRACRO_SAX_PARSER_H__*/ diff --git a/server/src/server.cc b/server/src/server.cc index 2a4c882..930a6e7 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -81,7 +81,8 @@ static void connection(TCPSocket &socket)    printf("Got connection...\n");    Transaction transaction; -  parse(socket, transaction); +  XMLParser parser(socket, transaction); +  parser.parse();    socket.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");    socket.write("<pracro version=\"1.0\">\n"); @@ -94,7 +95,8 @@ static void connection(TCPSocket &socket)      printf("Handling request for \"%s\"...", request.macro.c_str());      Macro macro; -    parse_macro(request.macro, macro); +    MacroParser parser(request.macro, macro); +    parser.parse();      socket.write("  <macro version=\"" + macro.version + "\" name=\""                    + macro.name + "\" resume=\"" + macro.format + "\">\n"); @@ -122,7 +124,8 @@ static void connection(TCPSocket &socket)        db.post(transaction.user, transaction.cpr, now, commit);        Macro macro; -      parse_macro(commit.macro, macro); +      MacroParser parser(commit.macro, macro); +      parser.parse();        std::string resume = resume_parser(macro.format.c_str(), commit); diff --git a/server/src/xmlparser.cc b/server/src/xmlparser.cc index 6ef7338..71bb753 100644 --- a/server/src/xmlparser.cc +++ b/server/src/xmlparser.cc @@ -35,33 +35,8 @@  static bool done = false; -static void start_hndl(void *p, const char *el, const char **attr) +void XMLParser::startTag(std::string name, std::map< std::string, std::string> attributes)  { -  Transaction *transaction = (Transaction*)XML_GetUserData(p); - -  //  printf("Start tag [%s]\n", el); - -  // Convert to comfy C++ values... -  std::string name = el; -  std::map< std::string, std::string > attributes; - -  while(*attr) { -    std::string at_name = *attr; -    attr++; -    std::string at_value = *attr; -    attr++; - -    attributes.insert(make_pair(at_name, at_value)); -  } -  /* -    std::map< std::string, std::string >::iterator i = attributes.begin(); -    while(i != attributes.end()) { -      printf("%s=%s\n", i->first.c_str(), i->second.c_str()); -      i++; -    } -  */ - -  // Do something reasonable with them...    if(name == "pracro") {      transaction->user = attributes["user"];      transaction->cpr = attributes["cpr"]; @@ -82,54 +57,24 @@ static void start_hndl(void *p, const char *el, const char **attr)    }    if(name == "field") { -    //    Field f; -    //    f.name = attributes["name"]; -    //    f.value = attributes["value"]; -    //    transaction->commits.back().fields.push_back(f);      transaction->commits.back().fields[attributes["name"]] = attributes["value"]; -    //    printf("[%s]=[%s]\n", f.name.c_str(), f.value.c_str());    } -  } -static void end_hndl(void *p, const char *el) +void XMLParser::endTag(std::string name)  { -  //  printf("End tag [%s]\n", el); -  if(!strcmp(el, "pracro")) done = true; +  if(name == "pracro") done = true;  } -void parse(TCPSocket &socket, Transaction &transaction) +int XMLParser::readData(char *data, size_t size)  { +  if(done) return 0; +  return socket->read(data, size); +} -  XML_Parser p = XML_ParserCreate(NULL); -  if (! p) { -    fprintf(stderr, "Couldn't allocate memory for parser\n"); -    // throw Exception(...); -    return; -  } - -  XML_SetUserData(p, &transaction); -  XML_UseParserAsHandlerArg(p); -  XML_SetElementHandler(p, start_hndl, end_hndl); - -  while(!done) { -    char buf[32]; -    int len; - -    memset(buf, 0, sizeof(buf)); -    len = socket.read(buf, sizeof(buf) - 1); - -    done = len == 0; - -    if (! XML_Parse(p, buf, len, done)) { -      fprintf(stderr, "Parse error at line %d:\n%s\n", -	      XML_GetCurrentLineNumber(p), -	      XML_ErrorString(XML_GetErrorCode(p))); -      // throw Exception(...); -      return; -    } -  } - -  //  printf("%d requests\n", transaction.requests.size()); - +XMLParser::XMLParser(TCPSocket &socket, Transaction &transaction) +{ +  this->transaction = &transaction; +  this->socket = &socket; +  done = false;  } diff --git a/server/src/xmlparser.h b/server/src/xmlparser.h index 8e6b7aa..30e6767 100644 --- a/server/src/xmlparser.h +++ b/server/src/xmlparser.h @@ -27,9 +27,24 @@  #ifndef __PRACRO_XMLPARSER_H__  #define __PRACRO_XMLPARSER_H__ +#include "sax_parser.h"  #include "tcpsocket.h"  #include "transaction.h" -void parse(TCPSocket &socket, Transaction &transaction); +class XMLParser : public SAXParser { +public: +  XMLParser(TCPSocket &socket, Transaction &transaction); + +  void startTag(std::string name, std::map< std::string, std::string> attributes); +  void endTag(std::string name); + +protected: +  int readData(char *data, size_t size); + +private: +  Transaction *transaction; +  TCPSocket *socket; +  bool done; +};  #endif/*__PRACRO_XMLPARSER_H__*/ | 
