/***************************************************************************** ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Utils/VeryTinyXpath.cpp,v $ ** ** $Revision: 1.8 $ ** ** $Date: 2009-07-18 17:16:36 $ ** ** More info: http://www.bluemsx.com ** ** Copyright (C) 2003-2006 Daniel Vik ** ** This program 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. ** ** This program 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 this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ****************************************************************************** */ #include "VeryTinyXpath.h" #include "tinyxml.h" #include #include #include #include #include struct VtXpath { bool openForWrite; char filename[512]; TiXmlDocument* doc; }; typedef std::vector PathVector; static void createPathVector(PathVector& pathVector, va_list marker, int count) { while (count--) { char* nodePtr = va_arg(marker, char*); std::string node(nodePtr); pathVector.push_back(node); } } extern "C" VtXpath* vtXpathOpenForRead(const char* filename) { VtXpath* xpath = new VtXpath; strcpy(xpath->filename, filename); xpath->openForWrite = false; xpath->doc = new TiXmlDocument; xpath->doc->LoadFile(filename); if (xpath->doc->Error()) { vtXpathClose(xpath); return NULL; } return xpath; } extern "C" VtXpath* vtXpathOpenForWrite(const char* filename) { VtXpath* xpath = new VtXpath; xpath->openForWrite = true; strcpy(xpath->filename, filename); xpath->doc = new TiXmlDocument; return xpath; } extern "C" void vtXpathClose(VtXpath* xpath) { if (xpath == NULL) { return; } if (xpath->openForWrite) { xpath->doc->SaveFile(xpath->filename); } delete xpath->doc; delete xpath; } static const char* vtXpathGetStringFromPath(VtXpath* xpath, PathVector& pathVector) { if (xpath == NULL) { return NULL; } TiXmlElement* el = xpath->doc->FirstChildElement(pathVector[0].c_str()); if (el == NULL) { return NULL; } for (unsigned int i = 1; el != NULL && i < pathVector.size(); i++) { el = el->FirstChildElement(pathVector[i].c_str()); } if (el == NULL) { return NULL; } TiXmlNode* node = el->FirstChild(); if (node == NULL) { return NULL; } return node->Value(); } static void vtXpathSetStringFromPath(VtXpath* xpath, PathVector& pathVector, const char* value) { if (xpath == NULL) { return; } TiXmlElement* el = xpath->doc->FirstChildElement(pathVector[0].c_str()); if (el == NULL) { std::string rootDoc; rootDoc += ""; rootDoc += "<"; rootDoc += pathVector[0]; rootDoc += ">\n\n"; xpath->doc->Parse(rootDoc.c_str()); } el = xpath->doc->FirstChildElement(pathVector[0].c_str()); if (el == NULL) { return; } for (unsigned int i = 1; el != NULL && i < pathVector.size(); i++) { TiXmlElement* child = el->FirstChildElement(pathVector[i].c_str()); if (child == NULL) { child = (TiXmlElement*)el->InsertEndChild(TiXmlElement(pathVector[i].c_str())); } el = child; } if (el != NULL) { el->InsertEndChild(TiXmlText(value)); } } extern "C" int vtXpathGetInt(VtXpath* xpath, int numLevels, const char* first, ...) { PathVector pathVector; va_list marker; va_start(marker, numLevels); createPathVector(pathVector, marker, numLevels); va_end(marker); const char* strValue = vtXpathGetStringFromPath(xpath, pathVector); if (strValue == NULL) { return VTXPATH_INT_NOT_FOUND; } int value = atoi(strValue); if (value == 0 && strValue[0] != '0') { return VTXPATH_INT_NOT_FOUND; } return value; } extern "C" const char* vtXpathGetString(VtXpath* xpath, int numLevels, const char* first, ...) { PathVector pathVector; va_list marker; va_start(marker, numLevels); createPathVector(pathVector, marker, numLevels); va_end(marker); return vtXpathGetStringFromPath(xpath, pathVector); } extern "C" void vtXpathSetInt(VtXpath* xpath, int value, int numLevels, const char* first, ...) { PathVector pathVector; va_list marker; va_start(marker, numLevels); createPathVector(pathVector, marker, numLevels); va_end(marker); char buf[16]; sprintf(buf, "%d", value); vtXpathSetStringFromPath(xpath, pathVector, buf); } extern "C" void vtXpathSetString(VtXpath* xpath, const char* value, int numLevels, const char* first, ...) { PathVector pathVector; va_list marker; va_start(marker, numLevels); createPathVector(pathVector, marker, numLevels); va_end(marker); vtXpathSetStringFromPath(xpath, pathVector, value); }