Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making PrintValues() and ToString() able to not print default elements #575

Merged
merged 24 commits into from
Jun 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d50c89d
adding element default check
Apr 19, 2021
233a922
renaming variables and integration test
May 7, 2021
0a3dca6
checking for error on load
May 7, 2021
18c9bb2
Merge branch 'sdf9' into marcoag/add_default_check
azeey May 10, 2021
c1953c8
fix typo and added test for child defult elements
May 11, 2021
f21a958
rename set flag since it's only related to parsing
May 11, 2021
441713b
adding test for default elements in copy and clone
May 11, 2021
52cd85f
code clean, extra tests for SetExplicitlySetInFile
May 12, 2021
051cd48
removing whitespaces
May 12, 2021
23e9447
Add failing test showing that SetExplicitlySetInFile sets the flag on…
azeey May 12, 2021
a8699ac
Merge pull request #1 from azeey/suggestion_add_default_check
May 14, 2021
369ea0d
refactor SetExplicitlySetInFile to avoid sibblings
May 14, 2021
bbaef61
style fixes
May 14, 2021
64f226f
adding default elements as comments
May 17, 2021
4fcfa21
test for adding child to default element
May 17, 2021
761f7bc
rename ptr variables for clarity
May 17, 2021
5c5e809
dont output default elements in tostring and print
May 10, 2021
f223cd3
Merge branch 'sdf9' of https://github.com/osrf/sdformat into marcoag/…
May 19, 2021
c978065
fix to function declarations
May 20, 2021
376550f
reverting to maintain default element behavior
May 28, 2021
b7b8c2b
remove extra blank line
May 28, 2021
68b830f
adding flags for default attributes and elements
Jun 10, 2021
daa3bc2
removing extra blank lines
Jun 10, 2021
f90794a
unit test xml correction and clarifications
Jun 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions include/sdf/Element.hh
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ namespace sdf
/// \param[in] _prefix String value to prefix to the output.
public: void PrintValues(std::string _prefix) const;

/// \brief Output Element's values to stdout.
/// \param[in] _prefix String value to prefix to the output.
/// \param[in] _includeDefaultElements flag to print default elements.
/// \param[in] _includeDefaultAttributes flag to print default attributes.
public: void PrintValues(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes) const;

/// \brief Helper function for SDF::PrintDoc
///
/// This generates the SDF html documentation.
Expand All @@ -171,6 +179,18 @@ namespace sdf
/// \return The string representation.
public: std::string ToString(const std::string &_prefix) const;

/// \brief Convert the element values to a string representation.
azeey marked this conversation as resolved.
Show resolved Hide resolved
/// Current behavior of ToString(const std::string &_prefix) can be
/// achieved by calling this function with _includeDefaultElements=true
/// and _includeDefaultAttributes=false
/// \param[in] _prefix String value to prefix to the output.
/// \param[in] _includeDefaultElements flag to include default elements.
/// \param[in] _includeDefaultAttributes flag to include default attributes.
/// \return The string representation.
public: std::string ToString(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes) const;

/// \brief Add an attribute value.
/// \param[in] _key Key value.
/// \param[in] _type Type of data the attribute will hold.
Expand Down Expand Up @@ -422,14 +442,22 @@ namespace sdf

/// \brief Generate a string (XML) representation of this object.
/// \param[in] _prefix arbitrary prefix to put on the string.
/// \param[in] _includeDefaultElements flag to include default elements.
/// \param[in] _includeDefaultAttributes flag to include default attributes.
/// \param[out] _out the std::ostreamstream to write output to.
private: void ToString(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes,
std::ostringstream &_out) const;

/// \brief Generate a string (XML) representation of this object.
/// \param[in] _prefix arbitrary prefix to put on the string.
/// \param[in] _includeDefaultElements flag to include default elements.
/// \param[in] _includeDefaultAttributes flag to include default attributes.
/// \param[out] _out the std::ostreamstream to write output to.
private: void PrintValuesImpl(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes,
std::ostringstream &_out) const;

/// \brief Create a new Param object and return it.
Expand Down
111 changes: 77 additions & 34 deletions src/Element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -442,47 +442,59 @@ void Element::PrintDocLeftPane(std::string &_html, int _spacing,
}

void Element::PrintValuesImpl(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes,
std::ostringstream &_out) const
{
_out << _prefix << "<" << this->dataPtr->name;

Param_V::const_iterator aiter;
for (aiter = this->dataPtr->attributes.begin();
aiter != this->dataPtr->attributes.end(); ++aiter)
if (this->GetExplicitlySetInFile() || _includeDefaultElements)
{
// Only print attribute values if they were set
// TODO(anyone): GetRequired is added here to support up-conversions where a
// new required attribute with a default value is added. We would have
// better separation of concerns if the conversion process set the required
// attributes with their default values.
if ((*aiter)->GetSet() || (*aiter)->GetRequired())
{
_out << " " << (*aiter)->GetKey() << "='"
<< (*aiter)->GetAsString() << "'";
}
}
_out << _prefix << "<" << this->dataPtr->name;

if (this->dataPtr->elements.size() > 0)
{
_out << ">\n";
ElementPtr_V::const_iterator eiter;
for (eiter = this->dataPtr->elements.begin();
eiter != this->dataPtr->elements.end(); ++eiter)
Param_V::const_iterator aiter;
for (aiter = this->dataPtr->attributes.begin();
aiter != this->dataPtr->attributes.end(); ++aiter)
{
(*eiter)->ToString(_prefix + " ", _out);
// Only print attribute values if they were set
// TODO(anyone): GetRequired is added here to support up-conversions where
// a new required attribute with a default value is added. We would have
// better separation of concerns if the conversion process set the
// required attributes with their default values.
if ((*aiter)->GetSet() || (*aiter)->GetRequired() ||
_includeDefaultAttributes)
azeey marked this conversation as resolved.
Show resolved Hide resolved
{
_out << " " << (*aiter)->GetKey() << "='"
<< (*aiter)->GetAsString() << "'";
}
}
_out << _prefix << "</" << this->dataPtr->name << ">\n";
}
else
{
if (this->dataPtr->value)

if (this->dataPtr->elements.size() > 0)
{
_out << ">" << this->dataPtr->value->GetAsString()
<< "</" << this->dataPtr->name << ">\n";
_out << ">\n";
ElementPtr_V::const_iterator eiter;
for (eiter = this->dataPtr->elements.begin();
eiter != this->dataPtr->elements.end(); ++eiter)
{
if ((*eiter)->GetExplicitlySetInFile() || _includeDefaultElements)
{
(*eiter)->ToString(_prefix + " ",
_includeDefaultElements,
_includeDefaultAttributes,
_out);
}
}
_out << _prefix << "</" << this->dataPtr->name << ">\n";
}
else
{
_out << "/>\n";
if (this->dataPtr->value)
{
_out << ">" << this->dataPtr->value->GetAsString()
<< "</" << this->dataPtr->name << ">\n";
}
else
{
_out << "/>\n";
}
}
}
}
Expand All @@ -491,25 +503,56 @@ void Element::PrintValuesImpl(const std::string &_prefix,
void Element::PrintValues(std::string _prefix) const
{
std::ostringstream ss;
PrintValuesImpl(_prefix, ss);
PrintValuesImpl(_prefix, true, false, ss);
std::cout << ss.str();
}

/////////////////////////////////////////////////
void Element::PrintValues(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes) const
{
std::ostringstream ss;
PrintValuesImpl(_prefix,
_includeDefaultElements,
_includeDefaultAttributes,
ss);
std::cout << ss.str();
}

/////////////////////////////////////////////////
std::string Element::ToString(const std::string &_prefix) const
{
std::ostringstream out;
this->ToString(_prefix, out);
this->ToString(_prefix, true, false, out);
return out.str();
}

/////////////////////////////////////////////////
std::string Element::ToString(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes) const
{
std::ostringstream out;
this->ToString(_prefix,
_includeDefaultElements,
_includeDefaultAttributes,
out);
return out.str();
}

/////////////////////////////////////////////////
void Element::ToString(const std::string &_prefix,
bool _includeDefaultElements,
bool _includeDefaultAttributes,
std::ostringstream &_out) const
{
if (this->dataPtr->includeFilename.empty())
{
PrintValuesImpl(_prefix, _out);
PrintValuesImpl(_prefix,
_includeDefaultElements,
_includeDefaultAttributes,
_out);
}
else
{
Expand Down
70 changes: 69 additions & 1 deletion src/Element_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,6 @@ TEST(Element, ToStringValue)
"myprefix< test='foo'>val</>\n");
}


/////////////////////////////////////////////////
TEST(Element, ToStringClonedElement)
{
Expand Down Expand Up @@ -575,6 +574,75 @@ TEST(Element, ToStringInclude)
ASSERT_EQ(stringval, "myprefix<include filename='foo.txt'/>\n");
}

/////////////////////////////////////////////////
TEST(Element, ToStringDefaultElements)
{
sdf::ElementPtr parent = std::make_shared<sdf::Element>();
parent->SetName("parent");
sdf::ElementPtr elem = std::make_shared<sdf::Element>();
elem->SetName("elem");
elem->SetParent(parent);
parent->InsertElement(elem);
sdf::ElementPtr elem2 = std::make_shared<sdf::Element>();
elem2->SetName("elem2");
elem2->SetParent(parent);
parent->InsertElement(elem2);

std::ostringstream stream;
stream
<< "<parent>\n"
<< " <elem/>\n"
<< " <elem2/>\n"
<< "</parent>\n";

EXPECT_EQ(parent->ToString("", false, false), stream.str());
EXPECT_EQ(parent->ToString(""), stream.str());
EXPECT_EQ(parent->ToString("", true, false), stream.str());

elem->SetExplicitlySetInFile(false);

std::ostringstream stream2;
stream2
<< "<parent>\n"
<< " <elem2/>\n"
<< "</parent>\n";

EXPECT_EQ(parent->ToString("", false, false), stream2.str());
EXPECT_EQ(parent->ToString(""), stream.str());
EXPECT_EQ(parent->ToString("", true, false), stream.str());

parent->SetExplicitlySetInFile(false);

EXPECT_EQ(parent->ToString("", false, false), "");
EXPECT_EQ(parent->ToString(""), stream.str());
EXPECT_EQ(parent->ToString("", true, false), stream.str());
}

/////////////////////////////////////////////////
TEST(Element, ToStringDefaultAttributes)
{
sdf::ElementPtr element = std::make_shared<sdf::Element>();
element->SetName("foo");
element->AddAttribute("test", "string", "foo", false, "foo description");
element->AddAttribute("test2", "string", "bar", true, "bar description");

EXPECT_EQ(element->ToString(""), element->ToString("", true, false));
EXPECT_EQ(element->ToString(""), element->ToString("", false, false));

std::ostringstream stream;
stream << "<foo test2='bar'/>\n";

EXPECT_EQ(element->ToString(""), stream.str());
EXPECT_EQ(element->ToString("", true, false), stream.str());
EXPECT_EQ(element->ToString("", false, false), stream.str());

std::ostringstream stream2;
stream2 << "<foo test='foo' test2='bar'/>\n";

EXPECT_EQ(element->ToString("", true, true), stream2.str());
EXPECT_EQ(element->ToString("", false, true), stream2.str());
}

/////////////////////////////////////////////////
TEST(Element, DocLeftPane)
{
Expand Down
Loading