summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/xmlfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/xmlfile.cpp')
-rw-r--r--src/lib/util/xmlfile.cpp124
1 files changed, 61 insertions, 63 deletions
diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp
index 5a6e2d7a741..893018f5384 100644
--- a/src/lib/util/xmlfile.cpp
+++ b/src/lib/util/xmlfile.cpp
@@ -37,7 +37,7 @@ namespace util { namespace xml {
struct parse_info
{
XML_Parser parser;
- data_node * rootnode;
+ file::ptr rootnode;
data_node * curnode;
uint32_t flags;
};
@@ -60,31 +60,33 @@ static void expat_element_end(void *data, const XML_Char *name);
XML FILE OBJECTS
***************************************************************************/
+file::file() { }
+file::~file() { }
+
+
/*-------------------------------------------------
- file_create - create a new xml file
- object
+ create - create a new, empty XML file
-------------------------------------------------*/
-data_node *data_node::file_create()
+file::ptr file::create()
{
- try { return new data_node(); }
- catch (...) { return nullptr; }
+ try { return ptr(new file()); }
+ catch (...) { return ptr(); }
}
/*-------------------------------------------------
- file_read - parse an XML file into its
- nodes
+ read - parse an XML file into its nodes
-------------------------------------------------*/
-data_node *data_node::file_read(util::core_file &file, parse_options const *opts)
+file::ptr file::read(util::core_file &file, parse_options const *opts)
{
parse_info info;
int done;
/* set up the parser */
if (!expat_setup_parser(info, opts))
- return nullptr;
+ return ptr();
/* loop through the file and parse it */
do
@@ -105,9 +107,9 @@ data_node *data_node::file_read(util::core_file &file, parse_options const *opts
opts->error->error_column = XML_GetCurrentColumnNumber(info.parser);
}
- info.rootnode->file_free();
+ info.rootnode.reset();
XML_ParserFree(info.parser);
- return nullptr;
+ return ptr();
}
}
while (!done);
@@ -116,7 +118,7 @@ data_node *data_node::file_read(util::core_file &file, parse_options const *opts
XML_ParserFree(info.parser);
/* return the root node */
- return info.rootnode;
+ return std::move(info.rootnode);
}
@@ -125,14 +127,14 @@ data_node *data_node::file_read(util::core_file &file, parse_options const *opts
nodes
-------------------------------------------------*/
-data_node *data_node::string_read(const char *string, parse_options const *opts)
+file::ptr file::string_read(const char *string, parse_options const *opts)
{
parse_info info;
int length = (int)strlen(string);
/* set up the parser */
if (!expat_setup_parser(info, opts))
- return nullptr;
+ return ptr();
/* parse the data */
if (XML_Parse(info.parser, string, length, 1) == XML_STATUS_ERROR)
@@ -144,16 +146,16 @@ data_node *data_node::string_read(const char *string, parse_options const *opts)
opts->error->error_column = XML_GetCurrentColumnNumber(info.parser);
}
- info.rootnode->file_free();
+ info.rootnode.reset();
XML_ParserFree(info.parser);
- return nullptr;
+ return ptr();
}
/* free the parser */
XML_ParserFree(info.parser);
/* return the root node */
- return info.rootnode;
+ return std::move(info.rootnode);
}
@@ -161,33 +163,17 @@ data_node *data_node::string_read(const char *string, parse_options const *opts)
file_write - write an XML tree to a file
-------------------------------------------------*/
-void data_node::file_write(util::core_file &file) const
+void file::write(util::core_file &file) const
{
/* ensure this is a root node */
- if (get_name())
- return;
+ assert(!get_name());
/* output a simple header */
file.printf("<?xml version=\"1.0\"?>\n");
file.printf("<!-- This file is autogenerated; comments and unknown tags will be stripped -->\n");
/* loop over children of the root and output */
- for (data_node const *node = get_first_child(); node; node = node->get_next_sibling())
- node->write_recursive(0, file);
-}
-
-
-/*-------------------------------------------------
- file_free - free an XML file object
--------------------------------------------------*/
-
-void data_node::file_free()
-{
- /* ensure this is a root node */
- if (get_name())
- return;
-
- delete this;
+ write_recursive(0, file);
}
@@ -211,7 +197,7 @@ data_node::data_node(data_node *parent, const char *name, const char *value)
: line(0)
, m_next(nullptr)
, m_first_child(nullptr)
- , m_name(name ? name : "")
+ , m_name(name)
, m_value(value ? value : "")
, m_parent(parent)
, m_attributes()
@@ -356,6 +342,9 @@ data_node const *data_node::find_next_matching_sibling(const char *name, const c
data_node *data_node::add_child(const char *name, const char *value)
{
+ if (!name || !*name)
+ return nullptr;
+
/* new element: create a new node */
data_node *node;
try { node = new data_node(this, name, value); }
@@ -743,10 +732,10 @@ static bool expat_setup_parser(parse_info &info, parse_options const *opts)
}
/* create a root node */
- info.rootnode = data_node::file_create();
- if (info.rootnode == nullptr)
+ info.rootnode = file::create();
+ if (!info.rootnode)
return false;
- info.curnode = info.rootnode;
+ info.curnode = info.rootnode.get();
/* create the XML parser */
memcallbacks.malloc_fcn = expat_malloc;
@@ -755,7 +744,7 @@ static bool expat_setup_parser(parse_info &info, parse_options const *opts)
info.parser = XML_ParserCreate_MM(nullptr, &memcallbacks, nullptr);
if (info.parser == nullptr)
{
- info.rootnode->file_free();
+ info.rootnode.reset();
return false;
}
@@ -867,36 +856,45 @@ void data_node::add_attribute(const char *name, const char *value)
void data_node::write_recursive(int indent, util::core_file &file) const
{
- /* output this tag */
- file.printf("%*s<%s", indent, "", get_name());
-
- /* output any attributes */
- for (attribute_node const &anode : m_attributes)
- file.printf(" %s=\"%s\"", anode.name, anode.value);
-
- if (!get_first_child() && !get_value())
+ if (!get_name())
{
- /* if there are no children and no value, end the tag here */
- file.printf(" />\n");
+ /* root node doesn't generate tag */
+ for (data_node const *child = this->get_first_child(); child; child = child->get_next_sibling())
+ child->write_recursive(indent, file);
}
else
{
- /* otherwise, close this tag and output more stuff */
- file.printf(">\n");
+ /* output this tag */
+ file.printf("%*s<%s", indent, "", get_name());
- /* if there is a value, output that here */
- if (get_value())
- file.printf("%*s%s\n", indent + 4, "", get_value());
+ /* output any attributes */
+ for (attribute_node const &anode : m_attributes)
+ file.printf(" %s=\"%s\"", anode.name, anode.value);
- /* loop over children and output them as well */
- if (get_first_child())
+ if (!get_first_child() && !get_value())
{
- for (data_node const *child = this->get_first_child(); child; child = child->get_next_sibling())
- child->write_recursive(indent + 4, file);
+ /* if there are no children and no value, end the tag here */
+ file.printf(" />\n");
}
+ else
+ {
+ /* otherwise, close this tag and output more stuff */
+ file.printf(">\n");
- /* write a closing tag */
- file.printf("%*s</%s>\n", indent, "", get_name());
+ /* if there is a value, output that here */
+ if (get_value())
+ file.printf("%*s%s\n", indent + 4, "", get_value());
+
+ /* loop over children and output them as well */
+ if (get_first_child())
+ {
+ for (data_node const *child = this->get_first_child(); child; child = child->get_next_sibling())
+ child->write_recursive(indent + 4, file);
+ }
+
+ /* write a closing tag */
+ file.printf("%*s</%s>\n", indent, "", get_name());
+ }
}
}