Skip to content

Commit

Permalink
Update to TinyXML-2
Browse files Browse the repository at this point in the history
  • Loading branch information
rupertnash committed Jun 19, 2023
1 parent 4f6a3c7 commit d55008f
Show file tree
Hide file tree
Showing 20 changed files with 138 additions and 147 deletions.
4 changes: 2 additions & 2 deletions CMake/HemeLbOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ pass_var(HEMELB METIS_INCLUDE_DIR)
pass_var(HEMELB METIS_LIBRARY)
pass_var(HEMELB ParMETIS_INCLUDE_DIR)
pass_var(HEMELB ParMETIS_LIBRARY)
pass_var(HEMELB TINYXML_INCLUDE_DIR)
pass_var(HEMELB TINYXML_LIBRARIES)
pass_var(HEMELB TINYXML2_INCLUDE_DIR)
pass_var(HEMELB TINYXML2_LIBRARIES)
2 changes: 1 addition & 1 deletion Code/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ include(mpi)
include(HemeLbDependency)

find_hemelb_dependency(Boost REQUIRED)
find_hemelb_dependency(TinyXML REQUIRED)
find_hemelb_dependency(tinyxml2 REQUIRED)

find_hemelb_dependency(ParMETIS REQUIRED)
find_hemelb_dependency(CTemplate REQUIRED)
Expand Down
6 changes: 3 additions & 3 deletions Code/configuration/SimConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ namespace hemelb::configuration
const std::string& requiredBC) const
{
// Check that HEMELB_*LET_BOUNDARY is consistent with this
const std::string& ioletTypeName = ioletEl.GetName();
auto ioletTypeName = ioletEl.GetName();
std::string hemeIoletBC;

if (ioletTypeName == "inlet")
Expand All @@ -222,9 +222,9 @@ namespace hemelb::configuration

auto SimConfig::DoIOForInOutlets(const io::xml::Element ioletsEl) const -> std::vector<IoletConfig>
{
const std::string& nodeName = ioletsEl.GetName();
auto nodeName = ioletsEl.GetName();

const std::string childNodeName = nodeName.substr(0, nodeName.size() - 1);
auto childNodeName = nodeName.substr(0, nodeName.size() - 1);
std::vector<IoletConfig> ioletList;
for (io::xml::Element currentIoletNode = ioletsEl.GetChildOrNull(childNodeName);
currentIoletNode != io::xml::Element::Missing();
Expand Down
2 changes: 1 addition & 1 deletion Code/io/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ target_link_libraries(hemelb_io PUBLIC
hemelb_util
)
target_link_libraries(hemelb_io PRIVATE
TinyXML::TinyXML
tinyxml2::tinyxml2
)
54 changes: 36 additions & 18 deletions Code/io/xml.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
// license in the file LICENSE.
#include <stdexcept>

#include "tinyxml.h"
#include <tinyxml2.h>

#include "io/xml.h"

namespace hemelb::io::xml
{
using namespace tinyxml2;

Document::Document()
{
xmlDoc = std::make_unique<::TiXmlDocument>();
xmlDoc = std::make_unique<XMLDocument>();
// Associate our Document object with TinyXML's to allow
// look up of the filename in error reporting.
xmlDoc->SetUserData(this);
}

Document::Document(const std::filesystem::path& path) : Document()
Expand All @@ -28,18 +33,20 @@ namespace hemelb::io::xml
}

void Document::LoadFile(const std::filesystem::path& path) {
if (!xmlDoc->LoadFile(path.c_str())) {
filename = path;
if (xmlDoc->LoadFile(path.c_str()) != tinyxml2::XML_SUCCESS) {
throw ParseError(xmlDoc.get());
}
}

void Document::LoadString(std::string_view data) {
if (xmlDoc->Parse(data.data()) == nullptr) {
filename = "";
if (xmlDoc->Parse(data.data()) != XML_SUCCESS) {
throw ParseError(xmlDoc.get());
}
}

Element::Element(TiXmlElement const* el_) :
Element::Element(XMLElement const* el_) :
el(el_)
{
}
Expand All @@ -50,14 +57,14 @@ namespace hemelb::io::xml
{
return {};
}
const std::string& Element::GetName() const
std::string_view Element::GetName() const
{
return el->ValueStr();
return el->Name();
}

int Element::GetLine() const
{
return el->Row();
return el->GetLineNum();
}

Element Element::GetChildOrNull() const
Expand All @@ -67,7 +74,14 @@ namespace hemelb::io::xml

Element Element::GetChildOrNull(std::string_view name) const
{
return Element(el->FirstChildElement(name.data()));
// string_view does not guarantee a null terminated string,
// but tinyxml requires one...
// Recall that the allocation returned by alloca is freed
// on function return.
char* buf = static_cast<char*>(alloca(name.size() +1 ));
std::copy(name.begin(), name.end(), buf);
buf[name.size()] = '\0';
return Element(el->FirstChildElement(buf));
}

Element Element::GetChildOrThrow() const
Expand Down Expand Up @@ -190,28 +204,32 @@ namespace hemelb::io::xml
GetPathWorker(el, ans);
return ans.str();
}
void Element::GetPathWorker(const TiXmlElement* el, std::ostringstream& ans)
void Element::GetPathWorker(const XMLElement* el, std::ostringstream& ans)
{
const TiXmlNode* parent = el->Parent();
const TiXmlElement* parentEl = parent->ToElement();
const XMLNode* parent = el->Parent();
const XMLElement* parentEl = parent->ToElement();
if (parentEl != nullptr)
{
GetPathWorker(parentEl, ans);
}
else
{
const TiXmlDocument* doc = parent->ToDocument();
if (doc != nullptr)
// Documents owned by our Document class have a user data
// pointer to the instance.
const XMLDocument* doc = parent->ToDocument();
auto heme_doc = static_cast<Document const*>(doc->GetUserData());
auto fn = heme_doc->filename;
if (fn != "")
{
ans << doc->Value() << ":";
ans << fn << ":";
}
else
{
ans << "?:";
}
}

ans << "/" << el->Value() << "(" << el->Row() << ")";
ans << "/" << el->Value() << "(" << el->GetLineNum() << ")";
}

Element::operator bool() const {
Expand Down Expand Up @@ -340,8 +358,8 @@ namespace hemelb::io::xml
*this << "xml::";
}

ParseError::ParseError(const TiXmlDocument* node) : XmlError() {
*this << "Error parsing XML. TiXml says: " << node->ErrorDesc();
ParseError::ParseError(const XMLDocument* node) : XmlError() {
*this << "Error parsing XML. TinXML2 says: " << node->ErrorStr();
}

// Missing attribute
Expand Down
24 changes: 15 additions & 9 deletions Code/io/xml.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
#include "Exception.h"
#include "util/traits.h"

// Forward declare the TinyXML types needed.
class TiXmlDocument;
class TiXmlElement;
namespace tinyxml2 {
// Forward declare the TinyXML types needed.
class XMLDocument;
class XMLElement;
}

namespace hemelb::io::xml
{
Expand All @@ -37,20 +39,20 @@ namespace hemelb::io::xml
// Exposes a basic monadic interface.
class Element
{
TiXmlElement const* el = nullptr;
tinyxml2::XMLElement const* el = nullptr;

public:
static Element Missing();

Element() = default;
Element(TiXmlElement const* el);
Element(tinyxml2::XMLElement const* el);
~Element();

/**
* Get the name of the element
* @return
*/
const std::string& GetName() const;
std::string_view GetName() const;
void GetName(const std::string& str);
/**
* Get the line number
Expand Down Expand Up @@ -317,7 +319,7 @@ namespace hemelb::io::xml
* @param el
* @param ans
*/
static void GetPathWorker(const TiXmlElement* el, std::ostringstream& ans);
static void GetPathWorker(const tinyxml2::XMLElement* el, std::ostringstream& ans);

/**
* Equality and inequality operators for
Expand Down Expand Up @@ -445,7 +447,11 @@ namespace hemelb::io::xml
void LoadString(std::string_view path);

private:
std::unique_ptr<TiXmlDocument> xmlDoc;
std::unique_ptr<tinyxml2::XMLDocument> xmlDoc;
// Note that TinyXML-2 doesn't keep track of
// the doc filename, so we have to do that.
friend Element;
std::filesystem::path filename;
};

/**
Expand Down Expand Up @@ -481,7 +487,7 @@ namespace hemelb::io::xml
class ParseError : public XmlError
{
public:
ParseError(const TiXmlDocument*);
ParseError(const tinyxml2::XMLDocument*);
};

/**
Expand Down
2 changes: 1 addition & 1 deletion Code/tests/helpers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ add_test_lib(test-helpers
RandomSourceTests.cc
RecordingNet.cc
)
target_link_libraries(test-helpers PRIVATE TinyXML::TinyXML)
target_link_libraries(test-helpers PRIVATE tinyxml2::tinyxml2)
37 changes: 16 additions & 21 deletions Code/tests/helpers/FolderTestFixture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <unistd.h>

#include <catch2/catch.hpp>
#include <tinyxml.h>
#include <tinyxml2.h>

#include "resources/Resource.h"
#include "util/clock.h"
Expand All @@ -22,23 +22,22 @@ namespace fs = std::filesystem;

namespace hemelb::tests::helpers
{
void ModifyXMLInput(TiXmlDocument &document, std::vector<std::string> const& elements,
void ModifyXMLInput(tinyxml2::XMLDocument &document, std::vector<std::string> const& elements,
std::string const& _value)
{
std::string const& attribute = elements.back();
// Point to the *actual last elem*
// Point to the actual last *element* (cos last is the attr).
auto end = --elements.end();
auto child = document.FirstChildElement("hemelbsettings");
for (auto iter = elements.begin(); iter != end; ++iter) {
auto& name = *iter;
auto next_child = child->FirstChildElement(name);
if(next_child == nullptr) {
next_child = new TiXmlElement(name);
child->LinkEndChild(next_child);
auto next_child = child->FirstChildElement(name.c_str());
if (next_child == nullptr) {
next_child = child->InsertNewChildElement(name.c_str());
}
child = next_child;
}
child->SetAttribute(attribute, _value);
child->SetAttribute(attribute.c_str(), _value.c_str());
}

//! \brief Modify XML document by deleting an element if it exists
Expand All @@ -48,19 +47,19 @@ namespace hemelb::tests::helpers
//! \param[in] elements: hierarchy of elements, last item will be removed.
//! Should not include "hemelbsettings"
//! \param[in] value: Value to set the attribute to
void DeleteXMLInput(TiXmlDocument &document, std::vector<std::string> const& elements)
void DeleteXMLInput(tinyxml2::XMLDocument &document, std::vector<std::string> const& elements)
{
auto element = document.FirstChildElement("hemelbsettings");
for (std::string const &name : elements)
{
auto next_child = element->FirstChildElement(name);
auto next_child = element->FirstChildElement(name.c_str());
if(next_child == nullptr)
{
return;
}
element = next_child;
}
element->Parent()->RemoveChild(element);
element->Parent()->DeleteChild(element);
}

FolderTestFixture::FolderTestFixture()
Expand Down Expand Up @@ -124,23 +123,19 @@ namespace hemelb::tests::helpers
std::string const &_value) const
{
auto const filename = tempPath / resource;
TiXmlDocument document(filename.c_str());
document.LoadFile();
tinyxml2::XMLDocument document;
document.LoadFile(filename.c_str());
helpers::ModifyXMLInput(document, elements, _value);
std::ofstream output(filename);
[&](std::ostream& o, TiXmlDocument const& doc) {
o << doc;
} (output, document);
document.SaveFile(filename.c_str());
}

void FolderTestFixture::DeleteXMLInput(std::string const &resource, std::vector<std::string> const& elements) const
{
std::string const filename = tempPath / resource;
TiXmlDocument document(filename.c_str());
document.LoadFile();
tinyxml2::XMLDocument document;
document.LoadFile(filename.c_str());
helpers::DeleteXMLInput(document, elements);
std::ofstream output(filename);
output << document;
document.SaveFile(filename.c_str());
}

void FolderTestFixture::MoveToTempdir()
Expand Down
9 changes: 5 additions & 4 deletions Code/tests/helpers/FolderTestFixture.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@

#include "tests/helpers/HasCommsTestFixture.h"

class TiXmlDocument;
namespace tinyxml2 { class XMLDocument; }

namespace hemelb::tests::helpers
{
void ModifyXMLInput(TiXmlDocument &document, std::vector<std::string> const& elements,
void ModifyXMLInput(tinyxml2::XMLDocument &document, std::vector<std::string> const& elements,
std::string const& _value);

//! \brief Modify XML document
Expand All @@ -26,7 +27,7 @@ namespace hemelb::tests::helpers
//! Should not include "hemelbsettings"
//! \param[in] value: Value to set the attribute to
template<class T>
void ModifyXMLInput(TiXmlDocument &document, std::vector<std::string> const& elements,
void ModifyXMLInput(tinyxml2::XMLDocument &document, std::vector<std::string> const& elements,
T const &_value)
{
std::ostringstream attr_value;
Expand All @@ -41,7 +42,7 @@ namespace hemelb::tests::helpers
//! \param[in] elements: hierarchy of elements, last item will be removed.
//! Should not include "hemelbsettings"
//! \param[in] value: Value to set the attribute to
void DeleteXMLInput(TiXmlDocument &document, std::vector<std::string> const& elements);
void DeleteXMLInput(tinyxml2::XMLDocument &document, std::vector<std::string> const& elements);

class FolderTestFixture : public HasCommsTestFixture
{
Expand Down
Loading

0 comments on commit d55008f

Please sign in to comment.