diff options
| author | Tim Redfern <tim@eclectronics.org> | 2014-01-09 16:50:51 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2014-01-09 16:50:51 +0000 |
| commit | d6571e5a9b8fc2bed416ff4798e3a29136004ff5 (patch) | |
| tree | 10371f8e55c345fd1590876b634b7a9cf51f9230 /NT/src/xmlIO.cpp | |
| parent | a940710de90c5bc2b9a3e74f19d60c769ab76643 (diff) | |
beginnng json output
Diffstat (limited to 'NT/src/xmlIO.cpp')
| -rw-r--r-- | NT/src/xmlIO.cpp | 673 |
1 files changed, 673 insertions, 0 deletions
diff --git a/NT/src/xmlIO.cpp b/NT/src/xmlIO.cpp new file mode 100644 index 0000000..be5efc0 --- /dev/null +++ b/NT/src/xmlIO.cpp @@ -0,0 +1,673 @@ +#include "xmlIO.h" + +#include <vector> +#include <string> +#include <iostream> + +//---------------------------------------- +// a pretty useful tokenization system: +static vector<string> tokenize(const string & str, const string & delim); +static vector<string> tokenize(const string & str, const string & delim) +{ + vector<string> tokens; + + size_t p0 = 0, p1 = string::npos; + while(p0 != string::npos) + { + p1 = str.find_first_of(delim, p0); + if(p1 != p0) + { + string token = str.substr(p0, p1 - p0); + tokens.push_back(token); + } + p0 = str.find_first_not_of(delim, p1); + } + return tokens; +} +//---------------------------------------- + +//---------------------------------------- +xmlIO::xmlIO(): + storedHandle(NULL) +{ + level = 0; + //we do this so that we have a valid handle + //without the need for loadFile + storedHandle = TiXmlHandle(&doc); +} + +//---------------------------------------- +xmlIO::xmlIO(const string& xmlFile): + storedHandle(NULL) +{ + level = 0; + //we do this so that we have a valid handle + //without the need for loadFile + storedHandle = TiXmlHandle(&doc); + loadFile(xmlFile); +} + +//--------------------------------------------------------- +xmlIO::~xmlIO() +{ +} + +//--------------------------------------------------------- +void xmlIO::setVerbose(bool _verbose){ +} + +//--------------------------------------------------------- +void xmlIO::clear(){ + //we clear from our root level + //this is usually the document + //but if we are pushed - it could + //be all the tags inside of the pushed + //node - including the node itself! + + storedHandle.ToNode()->Clear(); +} + +//--------------------------------------------------------- +bool xmlIO::loadFile(const string& xmlFile){ + + //string fullXmlFile = toDataPath(xmlFile); + + bool loadOkay = doc.LoadFile(xmlFile); + + //theo removed bool check as it would + //return false if the file exists but was + //empty + + //our push pop level should be set to 0! + level = 0; + + storedHandle = TiXmlHandle(&doc); + return loadOkay; +} + +//--------------------------------------------------------- +bool xmlIO::saveFile(const string& xmlFile){ + + //string fullXmlFile = toDataPath(xmlFile); + return doc.SaveFile(xmlFile); +} + +//--------------------------------------------------------- +bool xmlIO::saveFile(){ + return doc.SaveFile(); +} + +//--------------------------------------------------------- +void xmlIO::clearTagContents(const string& tag, int which){ + //we check it first to see if it exists + //otherwise setValue will make a new empty tag + if( tagExists(tag, which) )setValue(tag, "", which); +} + +//--------------------------------------------------------- +void xmlIO::removeTag(const string& tag, int which){ + + vector<string> tokens = tokenize(tag,":"); + + //no tags so we return + if( tokens.size() == 0 ) return; + + //grab the handle from the level we are at + //normally this is the doc but could be a pushed node + TiXmlHandle tagHandle = storedHandle; + + if(which < 0) which = 0; + + for(int x=0;x<(int)tokens.size();x++){ + + //we only support multi tags + //with same name at root level + if(x > 0) which = 0; + + TiXmlHandle isRealHandle = tagHandle.ChildElement( tokens.at(x), which); + + if ( !isRealHandle.ToNode() ) break; + else{ + if (x == (int)tokens.size()-1){ + //if we are at the last tag and it exists + //we use its parent to remove it - haha + tagHandle.ToNode()->RemoveChild( isRealHandle.ToNode() ); + } + tagHandle = isRealHandle; + } + } +} + +//--------------------------------------------------------- +int xmlIO::getValue(const string& tag, int defaultValue, int which){ + TiXmlHandle valHandle(NULL); + if (readTag(tag, valHandle, which)){ + return toInt(valHandle.ToText()->Value()); + } + return defaultValue; +} + +//--------------------------------------------------------- +double xmlIO::getValue(const string& tag, double defaultValue, int which){ + TiXmlHandle valHandle(NULL); + if (readTag(tag, valHandle, which)){ + return toFloat(valHandle.ToText()->Value()); + } + return defaultValue; +} + +//--------------------------------------------------------- +string xmlIO::getValue(const string& tag, const string& defaultValue, int which){ + TiXmlHandle valHandle(NULL); + if (readTag(tag, valHandle, which)){ + return valHandle.ToText()->ValueStr(); + } + return defaultValue; +} + +//--------------------------------------------------------- +bool xmlIO::readTag(const string& tag, TiXmlHandle& valHandle, int which){ + + vector<string> tokens = tokenize(tag,":"); + + TiXmlHandle tagHandle = storedHandle; + for(int x=0;x<(int)tokens.size();x++){ + if(x == 0)tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else tagHandle = tagHandle.FirstChildElement( tokens.at(x) ); + } + + // once we've walked, let's get that value... + valHandle = tagHandle.Child( 0 ); + return (valHandle.ToText() != NULL); +} + + +//--------------------------------------------------------- +bool xmlIO::pushTag(const string& tag, int which){ + + int pos = tag.find(":"); + + // Either find the tag specified, or the first tag if colon-seperated. + string tagToFind((pos > 0) ? tag.substr(0,pos) :tag); + + //we only allow to push one tag at a time. + TiXmlHandle isRealHandle = storedHandle.ChildElement(tagToFind, which); + + if( isRealHandle.ToNode() ){ + storedHandle = isRealHandle; + level++; + return true; + }else{ + //ofLog( OF_LOG_ERROR, "pushTag - <" + tag + "> tag not found"); + } + + return false; +} + +//--------------------------------------------------------- +int xmlIO::popTag(){ + + if(level >= 1){ + TiXmlHandle parent( (storedHandle.ToNode() )->Parent() ); + storedHandle = parent; + level--; + }else{ + storedHandle = TiXmlHandle(&doc); + level = 0; + } + + return level; +} + +//--------------------------------------------------------- +int xmlIO::getPushLevel(){ + return level; +} + +//--------------------------------------------------------- +bool xmlIO::tagExists(const string& tag, int which){ + + vector<string> tokens = tokenize(tag,":"); + + bool found = false; + + //grab the handle from the level we are at + //normally this is the doc but could be a pushed node + TiXmlHandle tagHandle = storedHandle; + + if(which < 0) which = 0; + + for(int x=0;x<(int)tokens.size();x++){ + + //we only support multi tags + //with same name at root level + if(x > 0) which = 0; + + TiXmlHandle isRealHandle = tagHandle.ChildElement( tokens.at(x), which); + + //as soon as we find a tag that doesn't exist + //we return false; + if ( !isRealHandle.ToNode() ){ + found = false; + break; + } + else{ + found = true; + tagHandle = isRealHandle; + } + } + + return found; +} + + +//--------------------------------------------------------- +int xmlIO::getNumTags(const string& tag){ + //this only works for tags at the current root level + + int pos = tag.find(":"); + + // Either find the tag specified, or the first tag if colon-seperated. + string tagToFind((pos > 0) ? tag.substr(0,pos) :tag); + + //grab the handle from the level we are at + //normally this is the doc but could be a pushed node + //TiXmlHandle tagHandle = storedHandle; + + int count = 0; + + //ripped from tinyXML as doing this ourselves once is a LOT! faster + //than having this called n number of times in a while loop - we go from n*n iterations to n iterations + + TiXmlElement* child = ( storedHandle.FirstChildElement( tagToFind ) ).ToElement(); + for (count = 0; child; child = child->NextSiblingElement( tagToFind ), ++count){ + //nothing + } + + return count; +} + + + +//--------------------------------------------------------- +int xmlIO::writeTag(const string& tag, const string& valueStr, int which){ + + vector<string> tokens = tokenize(tag,":"); + + // allocate on the stack + vector<TiXmlElement> elements; + elements.reserve(tokens.size()); + for(int x=0;x<(int)tokens.size();x++) + elements.push_back(tokens.at(x)); + + + TiXmlText Value(valueStr); + + // search our way up - do these tags exist? + // find the first that DOESNT exist, then move backwards... + TiXmlHandle tagHandle = storedHandle; + + bool addNewTag = false; + if(which == -1)addNewTag = true; + + for(int x=0;x<(int)tokens.size();x++){ + + if( x > 0 ){ + //multi tags of same name + //only for the root level + which = 0; + addNewTag = false; + } + + TiXmlHandle isRealHandle = tagHandle.ChildElement( tokens.at(x), which); + + if ( !isRealHandle.ToNode() || addNewTag){ + + for(int i=(int)tokens.size()-1;i>=x;i--){ + if (i == (int)tokens.size()-1){ + elements[i].InsertEndChild(Value); + } else { + elements[i].InsertEndChild(elements[i+1]); + } + } + + tagHandle.ToNode()->InsertEndChild(elements[x]); + + break; + + } else { + tagHandle = isRealHandle; + if (x == (int)tokens.size()-1){ + // what we want to change : TiXmlHandle valHandle = tagHandle.Child( 0 ); + tagHandle.ToNode()->Clear(); + tagHandle.ToNode()->InsertEndChild(Value); + } + } + } + + + //lets count how many tags with our name exist so we can return an index + + //ripped from tinyXML as doing this ourselves once is a LOT! faster + //than having this called n number of times in a while loop - we go from n*n iterations to n iterations + int numSameTags; + TiXmlElement* child = ( storedHandle.FirstChildElement( tokens.at(0) ) ).ToElement(); + for (numSameTags = 0; child; child = child->NextSiblingElement( tokens.at(0) ), ++numSameTags){ + //nothing + } + + return numSameTags; +} + +//--------------------------------------------------------- +int xmlIO::setValue(const string& tag, int value, int which){ + int tagID = writeTag(tag, toString(value).c_str(), which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::setValue(const string& tag, double value, int which){ + int tagID = writeTag(tag, toString(value).c_str(), which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::setValue(const string& tag, const string& value, int which){ + int tagID = writeTag(tag, value, which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addValue(const string& tag, int value){ + int tagID = writeTag(tag, toString(value).c_str(), -1) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addValue(const string& tag, double value){ + int tagID = writeTag(tag, toString(value).c_str(), -1) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addValue(const string& tag, const string& value){ + int tagID = writeTag(tag, value, -1) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addTag(const string& tag){ + int tagID = writeTag(tag, "", -1) -1; + return tagID; +} + +/******************* +* Attribute addons * +*******************/ + +//--------------------------------------------------------- +int xmlIO::addAttribute(const string& tag, const string& attribute, int value, int which){ + int tagID = writeAttribute(tag, attribute, toString(value).c_str(), which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addAttribute(const string& tag, const string& attribute, int value){ + return addAttribute(tag,attribute,value,-1); +} + +//--------------------------------------------------------- +int xmlIO::addAttribute(const string& tag, const string& attribute, double value, int which){ + int tagID = writeAttribute(tag, attribute, toString(value).c_str(), which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addAttribute(const string& tag, const string& attribute, double value){ + return addAttribute(tag,attribute,value,-1); +} + +//--------------------------------------------------------- +int xmlIO::addAttribute(const string& tag, const string& attribute, const string& value, int which){ + int tagID = writeAttribute(tag, attribute, value, which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::addAttribute(const string& tag, const string& attribute, const string& value){ + return addAttribute(tag,attribute,value,-1); +} + +//--------------------------------------------------------- +void xmlIO::removeAttribute(const string& tag, const string& attribute, int which){ + vector<string> tokens = tokenize(tag,":"); + TiXmlHandle tagHandle = storedHandle; + for (int x = 0; x < (int)tokens.size(); x++) { + if (x == 0) + tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else + tagHandle = tagHandle.FirstChildElement(tokens.at(x)); + } + + if (tagHandle.ToElement()) { + TiXmlElement* elem = tagHandle.ToElement(); + elem->RemoveAttribute(attribute); + } +} + +//--------------------------------------------------------- +void xmlIO::clearTagAttributes(const string& tag, int which){ + vector<string> names; + getAttributeNames( tag, names, which ); + for (vector<string>::iterator i = names.begin(); i != names.end(); i++) + removeAttribute(tag, *i, which); +} + +//--------------------------------------------------------- +int xmlIO::getNumAttributes(const string& tag, int which){ + vector<string> tokens = tokenize(tag,":"); + TiXmlHandle tagHandle = storedHandle; + for (int x = 0; x < (int)tokens.size(); x++) { + if (x == 0) + tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else + tagHandle = tagHandle.FirstChildElement(tokens.at(x)); + } + + if (tagHandle.ToElement()) { + TiXmlElement* elem = tagHandle.ToElement(); + + // Do stuff with the element here + TiXmlAttribute* first = elem->FirstAttribute(); + if (first) { + int count = 1; + for (TiXmlAttribute* curr = first; curr != elem->LastAttribute(); curr = curr->Next()) + count++; + return count; + } + } + return 0; +} + +//--------------------------------------------------------- +bool xmlIO::attributeExists(const string& tag, const string& attribute, int which){ + vector<string> tokens = tokenize(tag,":"); + TiXmlHandle tagHandle = storedHandle; + for (int x = 0; x < (int)tokens.size(); x++) { + if (x == 0) + tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else + tagHandle = tagHandle.FirstChildElement(tokens.at(x)); + } + + if (tagHandle.ToElement()) { + TiXmlElement* elem = tagHandle.ToElement(); + + // Do stuff with the element here + for (TiXmlAttribute* a = elem->FirstAttribute(); a; a = a->Next()) { + if (a->Name() == attribute) + return true; + } + } + return false; +} + +//--------------------------------------------------------- +bool xmlIO::getAttributeNames(const string& tag, vector<string>& outNames, int which){ + vector<string> tokens = tokenize(tag,":"); + TiXmlHandle tagHandle = storedHandle; + for (int x = 0; x < (int)tokens.size(); x++) { + if (x == 0) + tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else + tagHandle = tagHandle.FirstChildElement(tokens.at(x)); + } + + if (tagHandle.ToElement()) { + TiXmlElement* elem = tagHandle.ToElement(); + + // Do stuff with the element here + for (TiXmlAttribute* a = elem->FirstAttribute(); a; a = a->Next()) + outNames.push_back( string(a->Name()) ); + } + return !outNames.empty(); +} + +//--------------------------------------------------------- +int xmlIO::getAttribute(const string& tag, const string& attribute, int defaultValue, int which){ + int value = defaultValue; + readIntAttribute(tag, attribute, value, which); + return value; +} + +//--------------------------------------------------------- +double xmlIO::getAttribute(const string& tag, const string& attribute, double defaultValue, int which){ + double value = defaultValue; + readDoubleAttribute(tag, attribute, value, which); + return value; +} + +//--------------------------------------------------------- +string xmlIO::getAttribute(const string& tag, const string& attribute, const string& defaultValue, int which){ + string value = defaultValue; + readStringAttribute(tag, attribute, value, which); + return value; +} + +//--------------------------------------------------------- +int xmlIO::setAttribute(const string& tag, const string& attribute, int value, int which){ + char valueStr[255]; + sprintf(valueStr, "%i", value); + int tagID = writeAttribute(tag, attribute, valueStr, which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::setAttribute(const string& tag, const string& attribute, double value, int which){ + char valueStr[255]; + sprintf(valueStr, "%lf", value); + int tagID = writeAttribute(tag, attribute, valueStr, which) -1; + return tagID; +} + +//--------------------------------------------------------- +int xmlIO::setAttribute(const string& tag, const string& attribute, const string& value, int which){ + int tagID = writeAttribute(tag, attribute, value, which) -1; + return tagID; +} + +//--------------------------------------------------------- +TiXmlElement* xmlIO::getElementForAttribute(const string& tag, int which){ + vector<string> tokens = tokenize(tag,":"); + TiXmlHandle tagHandle = storedHandle; + for (int x = 0; x < (int)tokens.size(); x++) { + if (x == 0) + tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else + tagHandle = tagHandle.FirstChildElement(tokens.at(x)); + } + return tagHandle.ToElement(); +} + +//--------------------------------------------------------- +bool xmlIO::readIntAttribute(const string& tag, const string& attribute, int& outValue, int which){ + + TiXmlElement* elem = getElementForAttribute(tag, which); + if (elem) + return (elem->QueryIntAttribute(attribute, &outValue) == TIXML_SUCCESS); + return false; +} + +//--------------------------------------------------------- +bool xmlIO::readDoubleAttribute(const string& tag, const string& attribute, double& outValue, int which){ + + TiXmlElement* elem = getElementForAttribute(tag, which); + if (elem) + return (elem->QueryDoubleAttribute(attribute, &outValue) == TIXML_SUCCESS); + return false; +} + +//--------------------------------------------------------- +bool xmlIO::readStringAttribute(const string& tag, const string& attribute, string& outValue, int which){ + + TiXmlElement* elem = getElementForAttribute(tag, which); + if (elem) + { + const string* value = elem->Attribute(attribute); + if (value) + { + outValue = *value; + return true; + } + } + return false; +} + +//--------------------------------------------------------- +int xmlIO::writeAttribute(const string& tag, const string& attribute, const string& valueString, int which){ + vector<string> tokens = tokenize(tag,":"); + TiXmlHandle tagHandle = storedHandle; + for (int x = 0; x < (int)tokens.size(); x++) { + if (x == 0) + tagHandle = tagHandle.ChildElement(tokens.at(x), which); + else + tagHandle = tagHandle.FirstChildElement(tokens.at(x)); + } + + int ret = 0; + if (tagHandle.ToElement()) { + TiXmlElement* elem = tagHandle.ToElement(); + elem->SetAttribute(attribute, valueString); + + // Do we really need this? We could just ignore this and remove the 'addAttribute' functions... + // Now, just get the ID. + int numSameTags; + TiXmlElement* child = ( storedHandle.FirstChildElement( tokens.at(0) ) ).ToElement(); + for (numSameTags = 0; child; child = child->NextSiblingElement( tokens.at(0) ), ++numSameTags) { + // nothing + } + ret = numSameTags; + } + return ret; +} + +//--------------------------------------------------------- +bool xmlIO::loadFromBuffer( string buffer ) +{ + + int size = buffer.size(); + + bool loadOkay = doc.ReadFromMemory( buffer.c_str(), size);//, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING); + + return loadOkay; + +} +//--------------------------------------------------------- +void xmlIO::copyXmlToString(string & str) +{ + TiXmlPrinter printer; + doc.Accept(&printer); + + str = printer.CStr(); +} + |
