//////////////////////////////////////////////////////////////////////////////// // Scorched3D (c) 2000-2003 // // This file is part of Scorched3D. // // Scorched3D 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. // // Scorched3D 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 Scorched3D; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include XMLParser::XMLParser(bool useContentNodes) : root_(0), current_(0), useContentNodes_(useContentNodes), source_("Not Specified") { // Init the XML parser p_ = XML_ParserCreate(0); XML_SetStartElementHandler(p_, startElementStaticHandler); XML_SetEndElementHandler(p_, endElementStaticHandler); XML_SetCharacterDataHandler(p_, characterDataStaticHandler); XML_SetUserData(p_, this); } XMLParser::~XMLParser() { // Cleanup XML_ParserFree(p_); delete root_; } bool XMLParser::parse(const char *data, int len, int final) { // Parser the XML XML_Status status; status = XML_Parse(p_, data, len, final); return (status == XML_STATUS_OK); } const char *XMLParser::getParseError() { XML_Error errorCode = XML_GetErrorCode(p_); static char message[1024]; snprintf(message, 1024, "Parse Error, File %s: Line:%i Col:%i Error:%s", source_.c_str(), XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_), XML_ErrorString(errorCode)); return message; } void XMLParser::startElementHandler(const XML_Char *name, const XML_Char **atts) { if (!root_) { // Create the root node root_ = current_ = new XMLNode(name); root_->setUseContentNodes(useContentNodes_); root_->setSource(source_.c_str()); root_->setLine(XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_)); } else { DIALOG_ASSERT(current_); // Add a new child to this node XMLNode *newNode = new XMLNode(name); current_->setUseContentNodes(useContentNodes_); current_->addChild(newNode); current_ = newNode; current_->setLine(XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_)); } if (atts) { while (*atts) { const XML_Char *name = *atts; atts++; const XML_Char *value = *atts; atts++; XMLNode *param = new XMLNode(name, "", XMLNode::XMLParameterType); param->addContent(value, strlen(value)); param->setLine(XML_GetCurrentLineNumber(p_), XML_GetCurrentColumnNumber(p_)); current_->addParameter(param); } } } void XMLParser::endElementHandler(const XML_Char *name) { DIALOG_ASSERT(current_); DIALOG_ASSERT(strcmp(name, current_->getName()) == 0); current_ = (XMLNode *) current_->getParent(); } void XMLParser::characterDataHandler(const XML_Char *s, int len) { current_->addContent(s, len); } void XMLParser::startElementStaticHandler(void *userData, const XML_Char *name, const XML_Char **atts) { XMLParser *parser = (XMLParser *) userData; parser->startElementHandler(name, atts); } void XMLParser::endElementStaticHandler(void *userData, const XML_Char *name) { XMLParser *parser = (XMLParser *) userData; parser->endElementHandler(name); } void XMLParser::characterDataStaticHandler(void *userData, const XML_Char *s, int len) { XMLParser *parser = (XMLParser *) userData; parser->characterDataHandler(s, len); }