mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-22 17:49:43 +01:00
Add XMLUtils.cpp and XMLUtils.h
These XML functions will be useful for de-duplicating copy-pasted XML handling code, while also making it so elements will get updated in place instead of being thrown out and starting from scratch every time a file is saved.
This commit is contained in:
parent
a1957fa518
commit
cb2f72fd8e
3 changed files with 170 additions and 0 deletions
|
@ -105,6 +105,7 @@ SET(VVV_SRC
|
|||
src/Tower.cpp
|
||||
src/UtilityClass.cpp
|
||||
src/WarpClass.cpp
|
||||
src/XMLUtils.cpp
|
||||
src/main.cpp
|
||||
src/Network.c
|
||||
)
|
||||
|
|
142
desktop_version/src/XMLUtils.cpp
Normal file
142
desktop_version/src/XMLUtils.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include <SDL.h>
|
||||
#include <tinyxml2.h>
|
||||
|
||||
namespace xml
|
||||
{
|
||||
|
||||
// Helper functions for these utils (not exported)
|
||||
|
||||
static inline tinyxml2::XMLDocument& get_document(tinyxml2::XMLNode* parent)
|
||||
{
|
||||
return *(parent->GetDocument());
|
||||
}
|
||||
|
||||
|
||||
// EXPORTED FUNCTIONS
|
||||
|
||||
|
||||
// Create a new element if it doesn't exist. Returns the element.
|
||||
tinyxml2::XMLElement* update_element(tinyxml2::XMLNode* parent, const char* name)
|
||||
{
|
||||
if (parent == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument& doc = get_document(parent);
|
||||
|
||||
tinyxml2::XMLElement* element = parent->FirstChildElement(name);
|
||||
if (element == NULL)
|
||||
{
|
||||
// It doesn't exist, so create a new one
|
||||
element = doc.NewElement(name);
|
||||
parent->LinkEndChild(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
// Same thing as above, but takes &parent instead of *parent
|
||||
tinyxml2::XMLElement* update_element(tinyxml2::XMLNode& parent, const char* name)
|
||||
{
|
||||
return update_element(&parent, name);
|
||||
}
|
||||
|
||||
// Same thing as above, but deletes the content inside the element, too.
|
||||
tinyxml2::XMLElement* update_element_delete_contents(tinyxml2::XMLNode* parent, const char* name)
|
||||
{
|
||||
tinyxml2::XMLDocument& doc = get_document(parent);
|
||||
|
||||
tinyxml2::XMLElement* element = update_element(parent, name);
|
||||
|
||||
for (tinyxml2::XMLNode* node = element->FirstChild();
|
||||
node != NULL;
|
||||
/* Increment code handled separately */)
|
||||
{
|
||||
// Unfortunately, element->DeleteNode() is private
|
||||
// Can't just doc.DeleteNode(node) and then go to next,
|
||||
// node->NextSiblingElement() will be NULL.
|
||||
// Instead, store pointer of node we want to delete. Then increment
|
||||
// `node`. And THEN delete the node.
|
||||
tinyxml2::XMLNode* delete_this = node;
|
||||
|
||||
node = node->NextSiblingElement();
|
||||
|
||||
doc.DeleteNode(delete_this);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
// Call update_element_delete_contents(), then immediately set its value to a
|
||||
// string. Returns the element.
|
||||
tinyxml2::XMLElement* update_tag(tinyxml2::XMLNode* parent, const char* name, const char* value)
|
||||
{
|
||||
tinyxml2::XMLElement* element = update_element_delete_contents(parent, name);
|
||||
|
||||
element->InsertNewText(value);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
// Same as above, but takes an int instead, and automatically converts it to a
|
||||
// string.
|
||||
tinyxml2::XMLElement* update_tag(tinyxml2::XMLNode* parent, const char* name, const int value)
|
||||
{
|
||||
char string[16];
|
||||
SDL_snprintf(string, sizeof(string), "%i", value);
|
||||
|
||||
return update_tag(parent, name, string);
|
||||
}
|
||||
|
||||
// Delete the declaration, if it exists. Then create a new declaration.
|
||||
// Returns the declaration.
|
||||
tinyxml2::XMLDeclaration* update_declaration(tinyxml2::XMLDocument& doc)
|
||||
{
|
||||
if (doc.FirstChild() != NULL)
|
||||
{
|
||||
tinyxml2::XMLDeclaration* decl = doc.FirstChild()->ToDeclaration();
|
||||
|
||||
if (decl != NULL)
|
||||
{
|
||||
doc.DeleteNode(decl);
|
||||
}
|
||||
}
|
||||
|
||||
tinyxml2::XMLDeclaration* decl = doc.NewDeclaration();
|
||||
doc.InsertFirstChild(decl);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
// Create a new comment if the first child of the node isn't a comment.
|
||||
// Returns the comment.
|
||||
tinyxml2::XMLComment* update_comment(tinyxml2::XMLNode* parent, const char* text)
|
||||
{
|
||||
if (parent == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument& doc = get_document(parent);
|
||||
|
||||
if (parent->FirstChild() == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tinyxml2::XMLComment* comment = parent->FirstChild()->ToComment();
|
||||
|
||||
if (comment == NULL)
|
||||
{
|
||||
// It doesn't exist, so create a new one
|
||||
comment = doc.NewComment(text);
|
||||
parent->InsertFirstChild(comment);
|
||||
}
|
||||
|
||||
return comment;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace xml
|
27
desktop_version/src/XMLUtils.h
Normal file
27
desktop_version/src/XMLUtils.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Forward decl, avoid including tinyxml2.h
|
||||
namespace tinyxml2
|
||||
{
|
||||
class XMLComment;
|
||||
class XMLDocument;
|
||||
class XMLDeclaration;
|
||||
class XMLElement;
|
||||
class XMLNode;
|
||||
}
|
||||
|
||||
namespace xml
|
||||
{
|
||||
|
||||
tinyxml2::XMLElement* update_element(tinyxml2::XMLNode* parent, const char* name);
|
||||
// Same thing as above, but takes &parent instead of *parent
|
||||
tinyxml2::XMLElement* update_element(tinyxml2::XMLNode& parent, const char* name);
|
||||
|
||||
tinyxml2::XMLElement* update_element_delete_contents(tinyxml2::XMLNode* parent, const char* name);
|
||||
|
||||
tinyxml2::XMLElement* update_tag(tinyxml2::XMLNode* parent, const char* name, const char* value);
|
||||
tinyxml2::XMLElement* update_tag(tinyxml2::XMLNode* parent, const char* name, const int value);
|
||||
|
||||
tinyxml2::XMLDeclaration* update_declaration(tinyxml2::XMLDocument& doc);
|
||||
|
||||
tinyxml2::XMLComment* update_comment(tinyxml2::XMLNode* parent, const char* text);
|
||||
|
||||
} // namespace xml
|
Loading…
Reference in a new issue