#include #include #include #include #include "xmlrulereader.h" #include "rule.h" #include "stringset.h" using namespace std; RuleData::RuleData( boost::shared_ptr > dictionaryParameter, boost::shared_ptr > passiveDictionaryParameter, boost::shared_ptr > > ruleVectorParameter) : dictionary(dictionaryParameter), passiveDictionary(passiveDictionaryParameter), ruleVector(ruleVectorParameter) { dictionaryFound = false; initialiseAttributes(); ruleCount = 0; } RuleData::~RuleData() { } XmlRuleReader::XmlRuleReader( boost::shared_ptr > dictionaryParameter, boost::shared_ptr > passiveDictionaryParameter, boost::shared_ptr > > ruleVectorParameter) : ud(new RuleData( dictionaryParameter, passiveDictionaryParameter, ruleVectorParameter)) { ud->setState(STATE_UNKNOWN); ud->p = p; XML_SetUserData(p, ud.get()); XML_SetElementHandler(p, start, end); XML_SetCharacterDataHandler(p, characterdata); } XmlRuleReader::~XmlRuleReader() { } int XmlRuleReader::getRuleCount() { return ud->ruleCount; } string XmlRuleReader::getIncorrectPatternReport() { return ud->incorrectPatternReport; } void XmlRuleReader::getExcludeVector(vector &v) { v = ud->excludeVector; } void XmlRuleReader::getIncludeVector(vector &v) { v = ud->includeVector; } void XMLCALL XmlRuleReader::start( void *data, const XML_Char *el, const XML_Char **attr) { RuleData *ud; ud = (RuleData *)data; if (!strcmp(el, "rule")) ud->setState(STATE_IN_RULE); else if (!strcmp(el, "term")) { ud->setState(STATE_IN_TERM); while (*attr) { if (!strcmp(*attr, "passive") && !strcmp(*(attr + 1), "true")) ud->passive = true; attr += 2; } } else if (!strcmp(el, "find")) { while (*attr) { if (!strcmp(*attr, "matchcase") && !strcmp(*(attr + 1), "true")) ud->matchcase = true; else if (!strcmp(*attr, "cipher") && !strcmp(*(attr + 1), "true")) ud->cipher = true; attr += 2; } ud->setState(STATE_IN_FIND); } else if (!strcmp(el, "replace")) { while (*attr) { if (!strcmp(*attr, "adjustcase") && !strcmp(*(attr + 1), "true")) ud->adjustcase = true; else if (!strcmp(*attr, "tentative") && !strcmp(*(attr + 1), "true")) ud->tentative = true; attr += 2; } ud->setState(STATE_IN_REPLACE); } else if (!strcmp(el, "report")) ud->setState(STATE_IN_REPORT); else if (!strcmp(el, "exclude")) ud->setState(STATE_IN_EXCLUDE); else if (!strcmp(el, "include")) ud->setState(STATE_IN_INCLUDE); else if (!strcmp(el, "title")) ud->setState(STATE_IN_TITLE); else ud->setState(STATE_UNKNOWN); } void XMLCALL XmlRuleReader::end(void *data, const XML_Char *el) { RuleData *ud; ud = (RuleData *)data; if (!strcmp(el, "term")) { if (ud->term != "") { ud->dictionary->insert(ud->term); ud->dictionaryFound = true; if (ud->passive) { ud->passiveDictionary->insert(ud->term); ud->passive = false; } ud->term = ""; } ud->setState(STATE_UNKNOWN); } // handle end of rule else if (!strcmp(el, "rule")) { try { boost::shared_ptr rule(new Rule( ud->find, ud->matchcase, ud->replace)); string report = ud->title; if (ud->report != "") { report += ": "; report += ud->report; } rule->setReport(report); rule->setTentativeAttribute(ud->tentative); rule->setAdjustCaseAttribute(ud->adjustcase); ud->ruleVector->push_back(rule); ++(ud->ruleCount); ud->find = ""; ud->replace = ""; ud->report = ""; ud->setState(STATE_UNKNOWN); ud->initialiseAttributes(); } catch (exception& e) { ud->incorrectPatternReport = "Cannot compile: " + ud->find + "\r\nError: " + e.what(); XML_StopParser(ud->p, XML_FALSE); } } else if (!strcmp(el, "find")) ud->setState(STATE_UNKNOWN); else if (!strcmp(el, "replace")) ud->setState(STATE_UNKNOWN); else if (!strcmp(el, "report")) ud->setState(STATE_UNKNOWN); // handle excludes/includes else if (!strcmp(el, "exclude")) { ud->excludeVector.push_back(ud->exclude); ud->exclude = ""; ud->setState(STATE_UNKNOWN); } else if (!strcmp(el, "include")) { ud->includeVector.push_back(ud->include); ud->include = ""; ud->setState(STATE_UNKNOWN); } else if (!strcmp(el, "title")) ud->setState(STATE_UNKNOWN); // count each dictionary as one rule else if (!strcmp(el, "dictionary")) { if (ud->dictionaryFound) ++(ud->ruleCount); } } void XMLCALL XmlRuleReader::characterdata( void *data, const XML_Char *s, int len) { RuleData *ud; ud = (RuleData *)data; switch (ud->getState()) { case STATE_IN_FIND: ud->find.append(s, len); break; case STATE_IN_REPLACE: ud->replace.append(s, len); break; case STATE_IN_REPORT: ud->report.append(s, len); break; case STATE_IN_EXCLUDE: ud->exclude.append(s, len); break; case STATE_IN_INCLUDE: ud->include.append(s, len); break; case STATE_IN_TITLE: ud->title.append(s, len); break; case STATE_IN_TERM: ud->term.append(s, len); break; default: break; } } void RuleData::initialiseAttributes() { matchcase = adjustcase = tentative = passive = false; }