summaryrefslogtreecommitdiff
path: root/shared/xmlBase.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:17 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:17 +0200
commitfd0853d2623dd278b08288331ed42e3be59252fb (patch)
treea7645daeaef8bdbed064faf4eb88e72cee58726c /shared/xmlBase.cpp
parent2.1 (diff)
downloadFreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.tar.gz
FreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.tar.bz2
FreeFileSync-fd0853d2623dd278b08288331ed42e3be59252fb.zip
2.2
Diffstat (limited to 'shared/xmlBase.cpp')
-rw-r--r--shared/xmlBase.cpp387
1 files changed, 387 insertions, 0 deletions
diff --git a/shared/xmlBase.cpp b/shared/xmlBase.cpp
new file mode 100644
index 00000000..19ec0ab6
--- /dev/null
+++ b/shared/xmlBase.cpp
@@ -0,0 +1,387 @@
+#include "xmlBase.h"
+#include "globalFunctions.h"
+#include <wx/ffile.h>
+#include <wx/intl.h>
+
+
+std::string getTypeName(xmlAccess::XmlType type)
+{
+ switch (type)
+ {
+ case xmlAccess::XML_GUI_CONFIG:
+ return "GUI";
+ case xmlAccess::XML_BATCH_CONFIG:
+ return "BATCH";
+ case xmlAccess::XML_GLOBAL_SETTINGS:
+ return "GLOBAL";
+ case xmlAccess::XML_REAL_CONFIG:
+ return "REAL";
+ case xmlAccess::XML_OTHER:
+ break;
+ }
+ assert(false);
+ return "OTHER";
+}
+
+
+xmlAccess::XmlType xmlAccess::getXmlType(const wxString& filename)
+{
+ if (!wxFileExists(filename))
+ return XML_OTHER;
+
+ //workaround to get a FILE* from a unicode filename
+ wxFFile configFile(filename, wxT("rb"));
+ if (!configFile.IsOpened())
+ return XML_OTHER;
+
+ FILE* inputFile = configFile.fp();
+
+ TiXmlDocument doc;
+ if (!doc.LoadFile(inputFile)) //fails if inputFile is no proper XML
+ return XML_OTHER;
+
+ TiXmlElement* root = doc.RootElement();
+
+ if (!root || (root->ValueStr() != std::string("FreeFileSync"))) //check for FFS configuration xml
+ return XML_OTHER;
+
+ const char* cfgType = root->Attribute("XmlType");
+ if (!cfgType)
+ return XML_OTHER;
+
+ const std::string type(cfgType);
+
+ if (type == getTypeName(XML_GUI_CONFIG))
+ return XML_GUI_CONFIG;
+ else if (type == getTypeName(XML_BATCH_CONFIG))
+ return XML_BATCH_CONFIG;
+ else if (type == getTypeName(XML_GLOBAL_SETTINGS))
+ return XML_GLOBAL_SETTINGS;
+ else if (type == getTypeName(XML_REAL_CONFIG))
+ return XML_REAL_CONFIG;
+
+ return XML_OTHER;
+}
+
+
+bool xmlAccess::loadXmlDocument(const wxString& fileName, const xmlAccess::XmlType type, TiXmlDocument& document)
+{
+ if (!wxFileExists(fileName)) //avoid wxWidgets error message when wxFFile receives not existing file
+ return false;
+
+ //workaround to get a FILE* from a unicode filename
+ wxFFile dummyFile(fileName, wxT("rb")); //binary mode needed for TiXml to work correctly in this case
+ if (dummyFile.IsOpened())
+ {
+ FILE* inputFile = dummyFile.fp();
+
+ TiXmlBase::SetCondenseWhiteSpace(false); //do not condense whitespace characters
+
+ if (document.LoadFile(inputFile)) //load XML; fails if inputFile is no proper XML
+ {
+ TiXmlElement* root = document.RootElement();
+
+ if (root && (root->ValueStr() == std::string("FreeFileSync"))) //check for FFS configuration xml
+ {
+ const char* cfgType = root->Attribute("XmlType");
+ if (cfgType)
+ return std::string(cfgType) == getTypeName(type);
+ }
+ }
+ }
+
+ return false;
+}
+
+
+void xmlAccess::getDefaultXmlDocument(const XmlType type, TiXmlDocument& document)
+{
+ TiXmlBase::SetCondenseWhiteSpace(false); //do not condense whitespace characters
+
+ TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); //delete won't be necessary later; ownership passed to TiXmlDocument!
+ document.LinkEndChild(decl);
+
+ TiXmlElement* root = new TiXmlElement("FreeFileSync");
+
+ root->SetAttribute("XmlType", getTypeName(type)); //xml configuration type
+
+ document.LinkEndChild(root);
+}
+
+
+bool xmlAccess::saveXmlDocument(const wxString& fileName, const TiXmlDocument& document)
+{
+ //workaround to get a FILE* from a unicode filename
+ wxFFile dummyFile(fileName, wxT("w")); //no need for "binary" mode here
+ if (!dummyFile.IsOpened())
+ return false;
+
+ FILE* outputFile = dummyFile.fp();
+
+ return document.SaveFile(outputFile); //save XML
+}
+
+
+//################################################################################################################
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, std::string& output)
+{
+ if (parent)
+ {
+ const TiXmlElement* child = parent->FirstChildElement(name);
+ if (child)
+ {
+ const char* text = child->GetText();
+ if (text) //may be NULL!!
+ output = text;
+ else //NULL means empty string
+ output.clear();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, wxString& output)
+{
+ std::string tempString;
+ if (!readXmlElement(name, parent, tempString))
+ return false;
+
+ output = wxString::FromUTF8(tempString.c_str());
+ return true;
+}
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, int& output)
+{
+ std::string temp;
+ if (!readXmlElement(name, parent, temp))
+ return false;
+
+ output = globalFunctions::stringToInt(temp);
+ return true;
+}
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, unsigned int& output)
+{
+ int dummy = 0;
+ if (!xmlAccess::readXmlElement(name, parent, dummy))
+ return false;
+
+ output = static_cast<unsigned int>(dummy);
+ return true;
+}
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, long& output)
+{
+ std::string temp;
+ if (readXmlElement(name, parent, temp))
+ {
+ output = globalFunctions::stringToLong(temp);
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, bool& output)
+{
+ std::string dummy;
+ if (readXmlElement(name, parent, dummy))
+ {
+ output = dummy == "true";
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* parent, std::vector<wxString>& output)
+{
+ if (parent)
+ {
+ output.clear();
+
+ //load elements
+ const TiXmlElement* element = parent->FirstChildElement(name);
+ while (element)
+ {
+ const char* text = element->GetText();
+ if (text) //may be NULL!!
+ output.push_back(wxString::FromUTF8(text));
+ else
+ output.push_back(wxEmptyString);
+
+ element = element->NextSiblingElement();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+
+bool xmlAccess::readXmlAttribute(const std::string& name, const TiXmlElement* node, std::string& output)
+{
+ if (node)
+ {
+ const std::string* attrib = node->Attribute(name);
+ if (attrib) //may be NULL!
+ {
+ output = *attrib;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool xmlAccess::readXmlAttribute(const std::string& name, const TiXmlElement* node, int& output)
+{
+ std::string dummy;
+ if (readXmlAttribute(name, node, dummy))
+ {
+ output = globalFunctions::stringToInt(dummy);
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool xmlAccess::readXmlAttribute(const std::string& name, const TiXmlElement* node, unsigned int& output)
+{
+ std::string dummy;
+ if (readXmlAttribute(name, node, dummy))
+ {
+ output = globalFunctions::stringToInt(dummy);
+ return true;
+ }
+ else
+ return false;
+}
+
+
+bool xmlAccess::readXmlAttribute(const std::string& name, const TiXmlElement* node, bool& output)
+{
+ std::string dummy;
+ if (readXmlAttribute(name, node, dummy))
+ {
+ output = dummy == "true";
+ return true;
+ }
+ else
+ return false;
+}
+
+
+//################################################################################################################
+
+
+void xmlAccess::addXmlElement(const std::string& name, const std::string& value, TiXmlElement* parent)
+{
+ if (parent)
+ {
+ TiXmlElement* subElement = new TiXmlElement(name);
+ parent->LinkEndChild(subElement);
+ subElement->LinkEndChild(new TiXmlText(value));
+ }
+}
+
+
+void xmlAccess::addXmlElement(const std::string& name, const wxString& value, TiXmlElement* parent)
+{
+ addXmlElement(name, std::string(value.ToUTF8()), parent);
+}
+
+
+void xmlAccess::addXmlElement(const std::string& name, const int value, TiXmlElement* parent)
+{
+ addXmlElement(name, globalFunctions::numberToString(value), parent);
+}
+
+
+void xmlAccess::addXmlElement(const std::string& name, const unsigned int value, TiXmlElement* parent)
+{
+ addXmlElement(name, static_cast<int>(value), parent);
+}
+
+
+void xmlAccess::addXmlElement(const std::string& name, const long value, TiXmlElement* parent)
+{
+ addXmlElement(name, globalFunctions::numberToString(value), parent);
+}
+
+
+void xmlAccess::addXmlElement(const std::string& name, const bool value, TiXmlElement* parent)
+{
+ if (value)
+ addXmlElement(name, std::string("true"), parent);
+ else
+ addXmlElement(name, std::string("false"), parent);
+}
+
+
+void xmlAccess::addXmlElement(const std::string& name, const std::vector<wxString>& value, TiXmlElement* parent)
+{
+ for (std::vector<wxString>::const_iterator i = value.begin(); i != value.end(); ++i)
+ addXmlElement(name, std::string(i->ToUTF8()), parent);
+}
+
+
+void xmlAccess::addXmlAttribute(const std::string& name, const std::string& value, TiXmlElement* node)
+{
+ if (node)
+ node->SetAttribute(name, value);
+}
+
+
+void xmlAccess::addXmlAttribute(const std::string& name, const int value, TiXmlElement* node)
+{
+ addXmlAttribute(name, globalFunctions::numberToString(value), node);
+}
+
+
+void xmlAccess::addXmlAttribute(const std::string& name, const unsigned int value, TiXmlElement* node)
+{
+ addXmlAttribute(name, globalFunctions::numberToString(value), node);
+}
+
+
+void xmlAccess::addXmlAttribute(const std::string& name, const bool value, TiXmlElement* node)
+{
+ if (value)
+ addXmlAttribute(name, std::string("true"), node);
+ else
+ addXmlAttribute(name, std::string("false"), node);
+}
+
+
+using xmlAccess::XmlParser;
+
+void XmlParser::logError(const std::string& nodeName)
+{
+ failedNodes.push_back(wxString::FromUTF8(nodeName.c_str()));
+}
+
+bool XmlParser::errorsOccured() const
+{
+ return !failedNodes.empty();
+}
+
+const wxString XmlParser::getErrorMessageFormatted() const
+{
+ wxString errorMessage = wxString(_("Could not read values for the following XML nodes:")) + wxT("\n");
+ for (std::vector<wxString>::const_iterator i = failedNodes.begin(); i != failedNodes.end(); ++i)
+ errorMessage += wxString(wxT("<")) + *i + wxT(">") + ((i - failedNodes.begin() + 1) % 3 == 0 ? wxT("\n") : wxT(" "));
+ return errorMessage;
+}
+
bgstack15