#include #include #include #include #include "housestylereader.h" using namespace std; HouseStyleReader::HouseStyleReader( map > > &m ) : WrapExpat(true), ud(new HouseStyleReaderData()) { ud->setState(STATE_UNKNOWN); ud->depth = ud->cutoffDepth = 0; ud->filterActive = false; ud->filterMap = m; XML_SetUserData(p, ud.get()); XML_SetElementHandler(p, start, end); XML_SetCharacterDataHandler(p, characterdata); XML_SetCdataSectionHandler(p, cdatastart, cdataend); } HouseStyleReader::~HouseStyleReader() { } void HouseStyleReader::getNodeVector(vector > &v) { v = ud->nodevector; } void XMLCALL HouseStyleReader::start(void *data, const XML_Char *el, const XML_Char **attr) { HouseStyleReaderData *ud; ud = (HouseStyleReaderData *)data; ud->setState(STATE_ON_START); ++(ud->depth); if (ud->textnode.size()) { if (!ud->filterActive) ud->nodevector.push_back(make_pair(ud->textnode, ud->getCount())); ud->textnode = ""; } if (!ud->filterActive && ud->filterMap.find(el) != ud->filterMap.end()) { map > attributeMap; attributeMap = ud->filterMap[el]; // no attribute keys/values specified if (attributeMap.empty()) { ud->filterActive = true; ud->cutoffDepth = ud->depth; } // examine attribute keys/values else { for (; *attr; attr += 2) { char *key, *value; key = (char *)*attr; value = (char *)*(attr + 1); set valueSet; valueSet = attributeMap[key]; if (attributeMap.find(key) != attributeMap.end()) { if (valueSet.count(value)) { ud->filterActive = true; ud->cutoffDepth = ud->depth; } } } } ud->cutoffDepth = ud->depth; } } void XMLCALL HouseStyleReader::end(void *data, const XML_Char *el) { HouseStyleReaderData *ud; ud = (HouseStyleReaderData *)data; ud->setState(STATE_ON_END); --(ud->depth); if (ud->textnode.size()) { if (!ud->filterActive) ud->nodevector.push_back(make_pair(ud->textnode, ud->getCount())); ud->textnode = ""; } if (ud->filterActive && ud->depth < ud->cutoffDepth) { ud->cutoffDepth = 0; ud->filterActive = false; } } void XMLCALL HouseStyleReader::characterdata(void *data, const XML_Char *s, int len) { HouseStyleReaderData *ud; ud = (HouseStyleReaderData *)data; ud->textnode.append(s, len); } void XMLCALL HouseStyleReader::cdatastart(void *data) { HouseStyleReaderData *ud; ud = (HouseStyleReaderData *)data; ud->setState(STATE_ON_CDATA_START); if (ud->textnode.size()) { if (!ud->filterActive) ud->nodevector.push_back(make_pair(ud->textnode, ud->getCount())); ud->textnode = ""; } } void XMLCALL HouseStyleReader::cdataend(void *data) { HouseStyleReaderData *ud; ud = (HouseStyleReaderData *)data; ud->setState(STATE_ON_CDATA_END); if (ud->textnode.size()) { if (!ud->filterActive) ud->nodevector.push_back(make_pair(ud->textnode, ud->getCount())); ud->textnode = ""; } }