ULTIMA4: Starting to change Config to use XMLTree

This commit is contained in:
Paul Gilbert 2020-03-19 12:57:40 -07:00 committed by Paul Gilbert
parent 521292bb4d
commit fdc42e4feb
6 changed files with 30 additions and 106 deletions

View File

@ -83,7 +83,7 @@ const XMLNode *XMLNode::subtree(const Common::String &h) const {
}
}
return 0;
return nullptr;
}

View File

@ -56,6 +56,9 @@ public:
const Common::String &reference(const Common::String &, bool &);
const XMLNode *subtree(const Common::String &) const;
const Common::String &id() const {
return _id;
}
const Common::String &value(void) const {
return _content;
}

View File

@ -125,6 +125,10 @@ void XMLTree::write() {
}
}
const XMLNode *XMLTree::getNode(const Common::String &key) const {
return _tree->subtree(key);
}
bool XMLTree::hasNode(const Common::String &key) const {
const XMLNode *sub = _tree->subtree(key);
if (sub)

View File

@ -61,6 +61,7 @@ public:
return _readOnly;
}
const XMLNode *getNode(const Common::String &key) const;
bool hasNode(const Common::String &key) const;
bool checkRoot(const Common::String &key) const;

View File

@ -36,30 +36,8 @@ Config *Config::_instance;
Config::Config() {
_instance = this;
#ifdef TODO
doc = xmlParseFile(Config::CONFIG_XML_LOCATION_POINTER);
if (!doc) {
printf("Failed to read core config.xml. Assuming it is located at '%s'", Config::CONFIG_XML_LOCATION_POINTER);
errorFatal("error parsing config.xml");
}
xmlXIncludeProcess(doc);
if (settings.validateXml && doc->intSubset) {
Common::String errorMessage;
xmlValidCtxt cvp;
if (verbose)
printf("validating config.xml\n");
cvp.userData = &errorMessage;
cvp.error = &accumError;
// Error changed to not fatal due to regression in libxml2
if (!xmlValidateDocument(&cvp, doc))
errorWarning("xml validation error:\n%s", errorMessage.c_str());
}
#endif
if (!_doc.readConfigFile("data/config.xml"))
error("Failed to read core configuration");
}
Config::~Config() {
@ -67,44 +45,18 @@ Config::~Config() {
}
const Config *Config::getInstance() {
#ifdef TODO
if (!instance) {
xmlRegisterInputCallbacks(&xmlFileMatch, &fileOpen, xmlFileRead, xmlFileClose);
instance = new Config;
if (!_instance) {
_instance = new Config();
}
#endif
return _instance;
}
ConfigElement Config::getElement(const Common::String &name) const {
#ifdef TODO
xmlXPathContextPtr context;
xmlXPathObjectPtr result;
Common::String path = "/config/" + name;
context = xmlXPathNewContext(doc);
result = xmlXPathEvalExpression(reinterpret_cast<const xmlChar *>(path.c_str()), context);
if(xmlXPathNodeSetIsEmpty(result->nodesetval))
errorFatal("no match for xpath %s\n", path.c_str());
xmlXPathFreeContext(context);
if (result->nodesetval->nodeNr > 1)
errorWarning("more than one match for xpath %s\n", path.c_str());
xmlNodePtr node = result->nodesetval->nodeTab[0];
xmlXPathFreeObject(result);
return ConfigElement(node);
#else
return ConfigElement();
#endif
const Shared::XMLNode *node = _doc.getNode(name);
return ConfigElement(node);
}
char DEFAULT_CONFIG_XML_LOCATION[] = "config.xml";
char * Config::CONFIG_XML_LOCATION_POINTER = &DEFAULT_CONFIG_XML_LOCATION[0];
Std::vector<Common::String> Config::getGames() {
Std::vector<Common::String> result;
result.push_back("Ultima IV");
@ -114,39 +66,10 @@ Std::vector<Common::String> Config::getGames() {
void Config::setGame(const Common::String &name) {
}
void *Config::fileOpen(const char *filename) {
#ifdef TODO
void *result;
Common::String pathname(u4find_conf(filename));
/*-------------------------------------------------------------------*/
if (pathname.empty())
return NULL;
result = xmlFileOpen(pathname.c_str());
if (verbose)
printf("xml parser opened %s: %s\n", pathname.c_str(), result ? "success" : "failed");
return result;
#else
return nullptr;
#endif
}
void Config::accumError(void *l, const char *fmt, ...) {
#ifdef TODO
Common::String* errorMessage = static_cast<Common::String *>(l);
char buffer[1000];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
errorMessage->append(buffer);
#endif
}
ConfigElement::ConfigElement(xmlNodePtr xmlNode) : _node(xmlNode), _name(reinterpret_cast<const char *>(xmlNode->name)) {
ConfigElement::ConfigElement(const Shared::XMLNode *xmlNode) :
_node(xmlNode), _name(xmlNode->id().c_str()) {
}
ConfigElement::ConfigElement(const ConfigElement &e) : _node(e._node), _name(e._name) {
@ -264,7 +187,7 @@ Std::vector<ConfigElement> ConfigElement::getChildren() const {
Std::vector<ConfigElement> result;
#ifdef TODO
for (xmlNodePtr child = node->children; child; child = child->next) {
for (Shared::XMLNode * child = node->children; child; child = child->next) {
if (child->type == XML_ELEMENT_NODE)
result.push_back(ConfigElement(child));
}

View File

@ -23,7 +23,8 @@
#ifndef ULTIMA4_CONFIG_H
#define ULTIMA4_CONFIG_H
#include "ultima/ultima4/xml.h"
#include "ultima/shared/conf/xml_tree.h"
#include "ultima/shared/conf/xml_node.h"
#include "ultima/shared/std/containers.h"
namespace Ultima {
@ -106,6 +107,9 @@ class ConfigElement;
* Singleton class that manages the XML configuration tree.
*/
class Config {
private:
static Config *_instance;
Shared::XMLTree _doc;
public:
static const Config *getInstance();
public:
@ -116,16 +120,6 @@ public:
static Std::vector<Common::String> getGames();
static void setGame(const Common::String &name);
static char * CONFIG_XML_LOCATION_POINTER;
private:
static void *fileOpen(const char *filename);
static void accumError(void *l, const char *fmt, ...);
static Config *_instance;
xmlDocPtr _doc;
};
/**
@ -133,8 +127,11 @@ private:
* thin wrapper around the XML DOM element.
*/
class ConfigElement {
private:
const Shared::XMLNode *_node;
Common::String _name;
public:
ConfigElement(xmlNodePtr xmlNode);
ConfigElement(const Shared::XMLNode *xmlNode);
ConfigElement(const ConfigElement &e);
ConfigElement();
~ConfigElement();
@ -151,11 +148,7 @@ public:
Std::vector<ConfigElement> getChildren() const;
xmlNodePtr getNode() const { return _node; }
private:
xmlNodePtr _node;
Common::String _name;
const Shared::XMLNode *getNode() const { return _node; }
};
} // End of namespace Ultima4