#include #include #include #include #include #include "housestylewriter.h" #include "contexthandler.h" using namespace std; HouseStyleWriter::HouseStyleWriter(vector &v) : hswd(new HouseStyleWriterData()) { set elementSet; size_t vectorsize = v.size(); for (size_t i = 0; i < vectorsize; ++i) elementSet.insert(v[i].elementCount); hswd->setState(STATE_UNKNOWN); hswd->v = v; hswd->elementSet = elementSet; XML_SetUserData(p, hswd.get()); XML_SetElementHandler(p, start, end); XML_SetCharacterDataHandler(p, characterdata); XML_SetXmlDeclHandler(p, xmldecl); XML_SetCdataSectionHandler(p, cdatastart, cdataend); XML_SetDefaultHandler(p, defaulthandler); } HouseStyleWriter::~HouseStyleWriter() { } string HouseStyleWriter::getOutput() { return hswd->output; } void XMLCALL HouseStyleWriter::start(void *data, const XML_Char *el, const XML_Char **attr) { HouseStyleWriterData *hswd; hswd = (HouseStyleWriterData *)data; hswd->setState(STATE_ON_START); if (hswd->textnode.size()) { if (hswd->elementSet.count(hswd->getCount())) modify(hswd->v, hswd->textnode, hswd->getCount()); hswd->output += xmliseTextNode(hswd->textnode); hswd->textnode = ""; } hswd->output += '<'; hswd->output += el; for (; *attr; attr += 2) { hswd->output += ' '; hswd->output += *attr; hswd->output += "=\""; hswd->output += xmliseAttribute(*(attr + 1)); hswd->output += '"'; } hswd->output += '>'; } void XMLCALL HouseStyleWriter::end(void *data, const XML_Char *el) { HouseStyleWriterData *hswd; hswd = (HouseStyleWriterData *)data; //++(hswd->elementCount); hswd->setState(STATE_ON_END); if (hswd->textnode.size()) { if (hswd->elementSet.count(hswd->getCount())) modify(hswd->v, hswd->textnode, hswd->getCount()); hswd->output += xmliseTextNode(hswd->textnode); hswd->textnode = ""; } hswd->output += "output += el; hswd->output += '>'; } void XMLCALL HouseStyleWriter::characterdata(void *data, const XML_Char *s, int len) { HouseStyleWriterData *hswd; hswd = (HouseStyleWriterData *)data; hswd->textnode.append(s, len); } void XMLCALL HouseStyleWriter::xmldecl( void *data, const XML_Char *version, const XML_Char *encoding, int standalone) { HouseStyleWriterData *hswd; hswd = (HouseStyleWriterData *)data; hswd->output += "output += version; hswd->output += "\" encoding=\"UTF-8\""; if (standalone != -1) { hswd->output += " standalone=\""; hswd->output += (standalone) ? "yes" : "no"; hswd->output += "\""; } hswd->output += "?>"; } void XMLCALL HouseStyleWriter::cdatastart(void *data) { HouseStyleWriterData *hswd; hswd = (HouseStyleWriterData *)data; hswd->setState(STATE_ON_CDATA_START); if (hswd->textnode.size()) { if (hswd->elementSet.count(hswd->getCount())) modify(hswd->v, hswd->textnode, hswd->getCount()); hswd->output += hswd->textnode; hswd->textnode = ""; } hswd->output += "setState(STATE_ON_CDATA_END); if (hswd->textnode.size()) { if (hswd->elementSet.count(hswd->getCount())) modify(hswd->v, hswd->textnode, hswd->getCount()); hswd->output += hswd->textnode; hswd->textnode = ""; } hswd->output += "]]>"; } void XMLCALL HouseStyleWriter::defaulthandler( void *data, const XML_Char *s, int len) { HouseStyleWriterData *hswd; hswd = (HouseStyleWriterData *)data; hswd->output.append(s, len); } void HouseStyleWriter::modify( vector &v, string &buffer, unsigned elementCount) { int vectorsize, os_adjust, exclusion; vectorsize = v.size(); os_adjust = exclusion = 0; string cmp1, cmp2; for (int i = 0; i < vectorsize; ++i) { unsigned vectorElementCount = v[i].elementCount; if (vectorElementCount < elementCount) continue; else if (vectorElementCount > elementCount) break; else if (vectorElementCount == elementCount) { int offset = (int)v[i].offset + os_adjust; if (offset < exclusion) continue; // check match is as expected try { cmp1 = v[i].match; cmp2 = buffer.substr(offset, v[i].match.size()); } catch (std::exception& e) { continue; } if (cmp1.compare(cmp2)) continue; buffer.replace(offset, v[i].match.size(), v[i].replace.c_str()); os_adjust += v[i].replace.size() - v[i].match.size(); exclusion = offset + v[i].replace.size(); } } }