/*************************************************************************** * Copyright (C) 2005 by Christof Donat * * cdonat@gmx.de * * * * This program 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. * * * * 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "xmlparser.h" #include "logger.h" namespace xmlParser { bool parser::operator()(const string& content, int &pos, responseParserHook *hook) { return false; } bool spaceParser::operator()(const string& content, int &pos, responseParserHook *hook) { if( content[pos] == ' ' || content[pos] == '\t' || content[pos] == '\n' || content[pos] == '\r' ) { pos++; return true; } return false; } bool commentParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content.substr(pos,4) == "" && pos < content.length() ) pos++; if(pos < content.length()) { pos += 3; return (*hook)(8,content.substr(oldpos+4,(pos-oldpos)-7)); } pos = oldpos; return false; } return false; } bool nameParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( !( (content[pos] >= '0' && content[pos] <= '9' ) || (content[pos] >= 'a' && content[pos] <= 'z' ) || (content[pos] >= 'A' && content[pos] <= 'Z' ) || content[pos] == '.' || content[pos] == ':' || content[pos] == '_' ) ) return false; while( (content[pos] >= '0' && content[pos] <= '9' ) || (content[pos] >= 'a' && content[pos] <= 'z' ) || (content[pos] >= 'A' && content[pos] <= 'Z' ) || content[pos] == '.' || content[pos] == ':' || content[pos] == '_' ) pos++; return true; } bool attributeValueParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content[pos] == '"' ) { pos++; while( content[pos] != '"' && pos < content.length() ) pos++; if( pos >= content.length() ) { pos = oldpos; return false; } pos++; } else if( content[pos] == '\'' ) { pos++; while( content[pos] != '\'' && pos < content.length() ) pos++; if( pos >= content.length() ) { pos = oldpos; return false; } pos++; } else { pos = oldpos; return false; } return (*hook)(32,content.substr(oldpos+1,(pos-oldpos)-2)); } bool attributeParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( ! space(content,pos,hook) ) return false; while(space(content,pos,hook) && pos < content.length() ); int namestartpos = pos; if( ! name(content,pos,hook) ) { pos = oldpos; return false; } int nameendpos = pos; if( content[pos] != '=' ) { pos = oldpos; return false; } pos++; if( ! value(content,pos,hook) ) { pos = oldpos; return false; } return (*hook)(2,content.substr(oldpos+1,(nameendpos-oldpos)-1)); }; bool emptyelemParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content[pos] != '<' ) return false; pos++; if( !name(content,pos,hook) ) { pos = oldpos; return false; } int nameendpos = pos; while(attrib(content,pos,hook) && pos < content.length() ); while(space(content,pos,hook) && pos < content.length() ); if( content.substr(pos,2) != "/>" ) { pos = oldpos; return false; } pos += 2; return (*hook)(18,content.substr(oldpos+1,(nameendpos-oldpos)-1)); } bool startelemParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content[pos] != '<' ) return false; pos++; if( !name(content,pos,hook) ) { pos = oldpos; return false; } int nameendpos = pos; while(attrib(content,pos,hook) && pos < content.length() ); while(space(content,pos,hook) && pos < content.length() ); if( content[pos] != '>' ) { pos = oldpos; return false; } pos ++; return (*hook)(16,content.substr(oldpos+1,(nameendpos-oldpos)-1)); } bool endelemParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content.substr(pos,2) != "' ) { pos = oldpos; return false; } pos ++; return (*hook)(17,content.substr(oldpos+2,(nameendpos-oldpos)-2)); } bool textParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content[pos] == '<' ) return false; while( content[pos] != '<' && pos < content.length() ) pos++; return (*hook)(3,content.substr(oldpos,pos-oldpos)); }; bool cdataParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content.substr(pos,9) != "") ) && pos < content.length() ) pos++; if( !foundend ) { pos = oldpos; return false; } pos += 3; return (*hook)(4,content.substr(oldpos+9,(pos-oldpos)-12)); }; bool elemParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( emptyelem(content,pos,hook) ) return (*hook)(1,content.substr(oldpos,pos-oldpos)); if( ! elemstart(content,pos,hook) ) return false; bool foundend = false; while( !(foundend = endelem(content,pos,hook)) && pos < content.length() ) { if( ! ( comspace(content,pos,hook) || text(content,pos,hook) || (*this)(content,pos,hook) || cdata(content,pos,hook) ) ) { pos = oldpos; return false; } } if( foundend ) return (*hook)(1,content.substr(oldpos,pos-oldpos)); return false; } bool xmlpcParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( content.substr(pos,5) != "" ) { pos = oldpos; return false; } pos += 2; return (*hook)(7,string("xml")); } bool XMLParser::operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; while(space(content,pos,hook) && pos < content.length() ); if( ! xmlpc(content,pos,hook) ) { pos = oldpos; return false; } while(comspace(content,pos,hook) && pos < content.length() ); if( ! elem(content,pos,hook) ) { pos = oldpos; return false; } while(comspace(content,pos,hook) && pos < content.length() ); return (*hook)(9,content.substr(oldpos,pos-oldpos)); } bool ResponseParser::operator()(const string& content, responseParserHook *hook) { int pos = 0; bool rval = xml(content,pos,hook); if( pos < content.length() ) return false; return rval; } }