Skip to content

Commit

Permalink
Merge 8c3b313 into 131750f
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoag authored Mar 23, 2023
2 parents 131750f + 8c3b313 commit 0831fbd
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 15 deletions.
2 changes: 1 addition & 1 deletion include/sdf/Error.hh
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace sdf
/// This has been created to help preserve behavior.
FATAL_ERROR,

/// \brief Generic warning saved as error due to WarningsPolicy config
/// \brief Generic warning saved as error due to WarningsPolicy config.
WARNING,

/// \brief The joint axis expressed-in value does not match the name of an
Expand Down
51 changes: 50 additions & 1 deletion include/sdf/Plugin.hh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ namespace sdf
public: Plugin(const std::string &_filename, const std::string &_name,
const std::string &_xmlContent = "");

/// \brief A constructor that initializes the plugin's filename, name, and
/// optionally the content.
/// \param[out] _errors Vector of errors.
/// \param[in] _filename Filename of the shared library associated with
/// this plugin.
/// \param[in] _name The name of the plugin.
/// \param[in] _xmlContent Optional XML content that will be stored in
/// this plugin.
public: Plugin(sdf::Errors &_errors, const std::string &_filename,
const std::string &_name,
const std::string &_xmlContent = "");

/// \brief Load the plugin based on a element pointer. This is *not* the
/// usual entry point. Typical usage of the SDF DOM is through the Root
/// object.
Expand Down Expand Up @@ -107,6 +119,14 @@ namespace sdf
/// \param[in] _elem Element to insert.
public: void InsertContent(const sdf::ElementPtr _elem);

/// \brief Insert an element into the plugin content. This does not
/// modify the values in the sdf::ElementPtr returned by the `Element()`
/// function.
/// \param[out] _errors Vector of errors.
/// \param[in] _elem Element to insert.
public: void InsertContent(sdf::Errors &_errors,
const sdf::ElementPtr _elem);

/// \brief Insert XML content into this plugin. This function does not
/// modify the values in the sdf::ElementPtr returned by the `Element()`
/// function. The provided content must be valid XML.
Expand All @@ -116,6 +136,17 @@ namespace sdf
/// content of this plugin is not modified. True otherwise
public: bool InsertContent(const std::string _content);

/// \brief Insert XML content into this plugin. This function does not
/// modify the values in the sdf::ElementPtr returned by the `Element()`
/// function. The provided content must be valid XML.
/// \param[out] _errors Vector of errors.
/// \param[in] _content A string that contains valid XML. The XML is
/// inserted into this plugin if it is valid.
/// \return False if the provided content was invalid, in which case the
/// content of this plugin is not modified. True otherwise
public: bool InsertContent(sdf::Errors &_errors,
const std::string _content);

/// \brief Set the filename of the shared library.
/// \param[in] _filename Filename of the shared library associated with
/// this plugin.
Expand All @@ -134,6 +165,14 @@ namespace sdf
/// \return SDF element pointer with updated plugin values.
public: sdf::ElementPtr ToElement() const;

/// \brief Create and return an SDF element filled with data from this
/// plugin.
/// Note that parameter passing functionality is not captured with this
/// function.
/// \param[out] _errors Vector of errors.
/// \return SDF element pointer with updated plugin values.
public: sdf::ElementPtr ToElement(sdf::Errors &_errors) const;

/// \brief Copy assignment operator
/// \param[in] _plugin Plugin to copy
/// \return A reference to this plugin
Expand Down Expand Up @@ -188,8 +227,18 @@ namespace sdf
return _in;
}

/// \brief Initializer function to help Plugin constructors.
/// \param[out] _errors Vector of errors.
/// \param[in] _filename Filename of the shared library associated with
/// this plugin.
/// \param[in] _name The name of the plugin.
/// \param[in] _xmlContent Optional XML content that will be stored in
/// this plugin.
private: void Init(sdf::Errors &_errors, const std::string &_filename,
const std::string &_name, const std::string &_xmlContent);

/// \brief Private data pointer.
std::unique_ptr<sdf::PluginPrivate> dataPtr;
public: std::unique_ptr<sdf::PluginPrivate> dataPtr;
};

/// \brief A vector of Plugin.
Expand Down
69 changes: 56 additions & 13 deletions src/Plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,28 @@ Plugin::Plugin()
Plugin::Plugin(const std::string &_filename, const std::string &_name,
const std::string &_xmlContent)
: dataPtr(std::make_unique<sdf::PluginPrivate>())
{
sdf::Errors errors;
this->Init(errors, _filename, _name, _xmlContent);
sdf::throwOrPrintErrors(errors);
}

/////////////////////////////////////////////////
Plugin::Plugin(sdf::Errors &_errors, const std::string &_filename,
const std::string &_name, const std::string &_xmlContent)
: dataPtr(std::make_unique<sdf::PluginPrivate>())
{
this->Init(_errors, _filename, _name, _xmlContent);
}

void Plugin::Init(sdf::Errors &_errors, const std::string &_filename,
const std::string &_name, const std::string &_xmlContent)
{
this->SetFilename(_filename);
this->SetName(_name);
std::string trimmed = sdf::trim(_xmlContent);
if (!trimmed.empty())
this->InsertContent(trimmed);
this->InsertContent(_errors, trimmed);
}

/////////////////////////////////////////////////
Expand Down Expand Up @@ -102,7 +118,7 @@ Errors Plugin::Load(ElementPtr _sdf)

// Read the filename
std::pair<std::string, bool> filenamePair =
_sdf->Get<std::string>("filename", this->dataPtr->filename);
_sdf->Get<std::string>(errors, "filename", this->dataPtr->filename);
this->dataPtr->filename = filenamePair.first;
if (!filenamePair.second)
{
Expand All @@ -114,7 +130,7 @@ Errors Plugin::Load(ElementPtr _sdf)
for (sdf::ElementPtr innerElem = _sdf->GetFirstElement();
innerElem; innerElem = innerElem->GetNextElement(""))
{
this->dataPtr->contents.push_back(innerElem->Clone());
this->dataPtr->contents.push_back(innerElem->Clone(errors));
}

return errors;
Expand Down Expand Up @@ -150,14 +166,22 @@ sdf::ElementPtr Plugin::Element() const
return this->dataPtr->sdf;
}

/////////////////////////////////////////////////
sdf::ElementPtr Plugin::ToElement() const
{
sdf::Errors errors;
auto result = this->ToElement(errors);
sdf::throwOrPrintErrors(errors);
return result;
}

/////////////////////////////////////////////////
sdf::ElementPtr Plugin::ToElement(sdf::Errors &_errors) const
{
sdf::ElementPtr elem(new sdf::Element);
sdf::initFile("plugin.sdf", elem);

elem->GetAttribute("name")->Set(this->Name());
elem->GetAttribute("filename")->Set(this->Filename());
elem->GetAttribute("name")->Set(this->Name(), _errors);
elem->GetAttribute("filename")->Set(this->Filename(), _errors);

// Insert plugin content
for (const sdf::ElementPtr &content : this->dataPtr->contents)
Expand All @@ -181,18 +205,37 @@ const std::vector<sdf::ElementPtr> &Plugin::Contents() const
/////////////////////////////////////////////////
void Plugin::InsertContent(const sdf::ElementPtr _elem)
{
this->dataPtr->contents.push_back(_elem->Clone());
sdf::Errors errors;
this->InsertContent(errors, _elem);
sdf::throwOrPrintErrors(errors);
}

/////////////////////////////////////////////////
void Plugin::InsertContent(sdf::Errors &_errors, const sdf::ElementPtr _elem)
{
this->dataPtr->contents.push_back(_elem->Clone(_errors));
}

/////////////////////////////////////////////////
bool Plugin::InsertContent(const std::string _content)
{
sdf::Errors errors;
bool result = this->InsertContent(errors, _content);
sdf::throwOrPrintErrors(errors);
return result;
}

/////////////////////////////////////////////////
bool Plugin::InsertContent(sdf::Errors &_errors, const std::string _content)
{
// Read the XML content
auto xmlDoc = tinyxml2::XMLDocument(true, tinyxml2::COLLAPSE_WHITESPACE);;
auto xmlDoc = tinyxml2::XMLDocument(true, tinyxml2::COLLAPSE_WHITESPACE);
xmlDoc.Parse(_content.c_str());
if (xmlDoc.Error())
{
sdferr << "Error parsing XML from string: " << xmlDoc.ErrorStr() << '\n';
std::stringstream ss;
ss << "Error parsing XML from string: " << xmlDoc.ErrorStr();
_errors.push_back({ErrorCode::PARSING_ERROR, ss.str()});
return false;
}

Expand All @@ -209,20 +252,20 @@ bool Plugin::InsertContent(const std::string _content)
for (const tinyxml2::XMLAttribute *attribute = xml->FirstAttribute();
attribute; attribute = attribute->Next())
{
element->AddAttribute(attribute->Name(), "string", "", 1, "");
element->AddAttribute(attribute->Name(), "string", "", 1, _errors, "");
element->GetAttribute(attribute->Name())->SetFromString(
attribute->Value());
attribute->Value(), _errors);
}

// Copy the value
if (xml->GetText() != nullptr)
element->AddValue("string", xml->GetText(), true);
element->AddValue("string", xml->GetText(), true, _errors);

// Copy all children
copyChildren(element, xml, false);

// Add the element to this plugin
this->InsertContent(element);
this->InsertContent(_errors, element);
}

return true;
Expand Down
28 changes: 28 additions & 0 deletions src/Plugin_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "sdf/parser.hh"
#include "sdf/Plugin.hh"
#include "sdf/Element.hh"
#include "test_utils.hh"

/////////////////////////////////////////////////
TEST(DOMPlugin, Construction)
Expand Down Expand Up @@ -471,3 +472,30 @@ TEST(DOMPlugin, EqualityOperators)
plugin.SetFilename("new-filename");
EXPECT_EQ(plugin, plugin2);
}

///////////////////////////////////////////////
TEST(DOMPlugin, ErrorOutput)
{
std::stringstream buffer;
sdf::testing::RedirectConsoleStream redir(
sdf::Console::Instance()->GetMsgStream(), &buffer);

#ifdef _WIN32
sdf::Console::Instance()->SetQuiet(false);
sdf::testing::ScopeExit revertSetQuiet(
[]
{
sdf::Console::Instance()->SetQuiet(true);
});
#endif

sdf::Errors errors;
sdf::Plugin Plugin(errors, "", "", "Not valid xml");
ASSERT_EQ(errors.size(), 1u);
EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::PARSING_ERROR);
EXPECT_NE(std::string::npos, errors[0].Message().find(
"Error parsing XML from string: "));

// Check nothing has been printed
EXPECT_TRUE(buffer.str().empty()) << buffer.str();
}

0 comments on commit 0831fbd

Please sign in to comment.