diff options
Diffstat (limited to 'src/lib/util/xmlfile.cpp')
-rw-r--r-- | src/lib/util/xmlfile.cpp | 124 |
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()); + } } } |