Skip to content

Commit

Permalink
Merge c86f6d1 into 63b8bf6
Browse files Browse the repository at this point in the history
  • Loading branch information
jennuine authored Jul 22, 2022
2 parents 63b8bf6 + c86f6d1 commit 57a1081
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 50 deletions.
108 changes: 58 additions & 50 deletions src/Utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,6 @@ namespace ignition
return _s;
}

/// \brief Splits a string into tokens. This was copied from ignition
/// common, ign-common/Util.hh, to avoid adding another dependency.
/// Remove this function if ign-common every becomes a dependency.
/// \param[in] _str Input string.
/// \param[in] _delim Token delimiter.
/// \return Vector of tokens.
std::vector<std::string> split(const std::string &_str,
const std::string &_delim)
{
std::vector<std::string> tokens;
char *saveptr;
char *str = strdup(_str.c_str());

auto token = ignstrtok(str, _delim.c_str(), &saveptr);

while (token)
{
tokens.push_back(token);
token = ignstrtok(NULL, _delim.c_str(), &saveptr);
}

free(str);
return tokens;
}

/////////////////////////////////////////////
ignition::math::Vector3d Convert(const msgs::Vector3d &_v)
{
Expand Down Expand Up @@ -780,10 +755,12 @@ namespace ignition
case msgs::PointCloudPacked::Field::FLOAT64:
offset += 8;
break;
// LCOV_EXCL_START
default:
std::cerr << "PointCloudPacked field datatype of ["
<< _type << "] is invalid.\n";
break;
// LCOV_EXCL_STOP
}
};

Expand Down Expand Up @@ -987,31 +964,46 @@ namespace ignition
return false;
}

// Get the top level <model> element.
tinyxml2::XMLElement *modelElement = modelConfigDoc.FirstChildElement(
// Get the top level <model> or <world> element.
tinyxml2::XMLElement *topElement = modelConfigDoc.FirstChildElement(
"model");
if (!modelElement)
bool isModel = true;
if (!topElement)
{
std::cerr << "Model config string does not contain a <model> element\n";
return false;
topElement = modelConfigDoc.FirstChildElement("world");
if (!topElement)
{
std::cerr << "Model config string does not contain a "
<< "<model> or <world> element\n";
return false;
}
isModel = false;
}

// Read the name, which is a mandatory element.
tinyxml2::XMLElement *elem = modelElement->FirstChildElement("name");
tinyxml2::XMLElement *elem = topElement->FirstChildElement("name");
if (!elem || !elem->GetText())
{
std::cerr << "Model config string does not contain a <name> element\n";
return false;
}
meta.set_name(trimmed(elem->GetText()));

// Read the version, if present.
elem = topElement->FirstChildElement("version");
if (elem && elem->GetText())
{
auto version = std::stoi(trimmed(elem->GetText()));
meta.set_version(version);
}

// Read the description, if present.
elem = modelElement->FirstChildElement("description");
elem = topElement->FirstChildElement("description");
if (elem && elem->GetText())
meta.set_description(trimmed(elem->GetText()));

// Read the dependencies, if any.
elem = modelElement->FirstChildElement("depend");
elem = topElement->FirstChildElement("depend");
while (elem)
{
auto modelElem = elem->FirstChildElement("model");
Expand All @@ -1028,7 +1020,7 @@ namespace ignition
}

// Read the authors, if any.
elem = modelElement->FirstChildElement("author");
elem = topElement->FirstChildElement("author");
while (elem)
{
ignition::msgs::FuelMetadata::Contact *author = meta.add_authors();
Expand All @@ -1049,7 +1041,7 @@ namespace ignition
}

// Get the most recent SDF file
elem = modelElement->FirstChildElement("sdf");
elem = topElement->FirstChildElement("sdf");
math::SemanticVersion maxVer;
while (elem)
{
Expand All @@ -1059,23 +1051,34 @@ namespace ignition
math::SemanticVersion ver(trimmed(verStr));
if (ver > maxVer)
{
meta.mutable_model()->mutable_file_format()->set_name("sdf");
ignition::msgs::Version *verMsg =
meta.mutable_model()->mutable_file_format()->mutable_version();
ignition::msgs::Version *verMsg;

if (isModel)
{
meta.mutable_model()->mutable_file_format()->set_name("sdf");
verMsg =
meta.mutable_model()->mutable_file_format()->mutable_version();
meta.mutable_model()->set_file(trimmed(elem->GetText()));
}
else
{
meta.mutable_world()->mutable_file_format()->set_name("sdf");
verMsg =
meta.mutable_world()->mutable_file_format()->mutable_version();
meta.mutable_world()->set_file(trimmed(elem->GetText()));
}

verMsg->set_major(ver.Major());
verMsg->set_minor(ver.Minor());
verMsg->set_patch(ver.Patch());
verMsg->set_prerelease(ver.Prerelease());
verMsg->set_build(ver.Build());

meta.mutable_model()->set_file(trimmed(elem->GetText()));
}
}

elem = elem->NextSiblingElement("sdf");
}
if (meta.model().file().empty())
if (meta.model().file().empty() && meta.world().file().empty())
{
std::cerr << "Model config string does not contain an <sdf> element\n";
return false;
Expand All @@ -1101,7 +1104,11 @@ namespace ignition
}

out << "<?xml version='1.0'?>\n"
<< " <model>\n";
<< " <model>\n"
<< " <sdf version='"
<< _meta.model().file_format().version().major()
<< "." << _meta.model().file_format().version().minor() << "'>"
<< _meta.model().file() << "</sdf>\n";
}
else
{
Expand All @@ -1112,15 +1119,16 @@ namespace ignition
}

out << "<?xml version='1.0'?>\n"
<< " <world>\n";
<< " <world>\n"
<< " <sdf version='"
<< _meta.world().file_format().version().major()
<< "." << _meta.world().file_format().version().minor() << "'>"
<< _meta.world().file() << "</sdf>\n";
}

out << " <name>" << _meta.name() << "</name>\n"
<< " <version>" << _meta.version() << "</version>\n"
<< " <sdf version='" << _meta.model().file_format().version().major()
<< "." << _meta.model().file_format().version().minor() << "'>"
<< _meta.model().file() << "</sdf>\n"
<< " <description>" << _meta.description() << "</description>\n";
<< " <version>" << _meta.version() << "</version>\n"
<< " <description>" << _meta.description() << "</description>\n";

// Output author information.
for (int i = 0; i < _meta.authors_size(); ++i)
Expand All @@ -1135,9 +1143,9 @@ namespace ignition
for (int i = 0; i < _meta.dependencies_size(); ++i)
{
out << " <depend>\n"
<< " <model>"
<< " <model>\n"
<< " <uri>" << _meta.dependencies(i).uri() << "</uri>\n"
<< " </model>"
<< " </model>\n"
<< " </depend>\n";
}

Expand Down
127 changes: 127 additions & 0 deletions src/Utility_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,133 @@ TEST(UtilityTest, ConvertFloat)
EXPECT_DOUBLE_EQ(s, 0.999f);
}


/////////////////////////////////////////////////
TEST(UtilityTest, ConvertFuelMetadata)
{
msgs::FuelMetadata metaMsg;
std::string modelConfigInput, worldConfigInput;

// test ConvertFuelMetadata(string, msgs::FuelMetadata)
{
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));

metaMsg.Clear();
modelConfigInput = "<test/>";
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));

metaMsg.Clear();
modelConfigInput = "<model>test</model>";
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));

// Test <model>
metaMsg.Clear();
modelConfigInput = R"(
<model>
<name>test_model</name>
</model>
)";
EXPECT_FALSE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));

metaMsg.Clear();
modelConfigInput = R"(<?xml version='1.0'?>
<model>
<sdf version='1.7'>model.sdf</sdf>
<name>test_model</name>
<version>3</version>
<description>A model for testing</description>
<author>
<name>Foo Bar</name>
<email>[email protected]</email>
</author>
<depend>
<model>
<uri>model://some_model</uri>
</model>
</depend>
</model>
)";

EXPECT_TRUE(msgs::ConvertFuelMetadata(modelConfigInput, metaMsg));
EXPECT_EQ("test_model", metaMsg.name());
EXPECT_EQ(3, metaMsg.version());
EXPECT_EQ("A model for testing", metaMsg.description());
EXPECT_EQ("model.sdf", metaMsg.model().file());
EXPECT_EQ("sdf", metaMsg.model().file_format().name());
EXPECT_EQ(1, metaMsg.model().file_format().version().major());
EXPECT_EQ(7, metaMsg.model().file_format().version().minor());
EXPECT_EQ(1, metaMsg.authors().size());
EXPECT_EQ("Foo Bar", metaMsg.authors(0).name());
EXPECT_EQ("[email protected]", metaMsg.authors(0).email());
EXPECT_EQ(1, metaMsg.dependencies().size());
EXPECT_EQ("model://some_model", metaMsg.dependencies(0).uri());

// Test <world>
metaMsg.Clear();
worldConfigInput = R"(<?xml version='1.0'?>
<world>
<sdf version='1.7'>world.sdf</sdf>
<name>test_world</name>
<version>2</version>
<description>A world for testing</description>
</world>
)";
EXPECT_TRUE(msgs::ConvertFuelMetadata(worldConfigInput, metaMsg));
EXPECT_EQ("test_world", metaMsg.name());
EXPECT_EQ(2, metaMsg.version());
EXPECT_EQ("A world for testing", metaMsg.description());
EXPECT_EQ("world.sdf", metaMsg.world().file());
EXPECT_EQ("sdf", metaMsg.world().file_format().name());
EXPECT_EQ(1, metaMsg.world().file_format().version().major());
EXPECT_EQ(7, metaMsg.world().file_format().version().minor());
EXPECT_EQ(0, metaMsg.authors().size());
EXPECT_EQ(0, metaMsg.dependencies().size());
}

// test ConvertFuelMetadata(msgs::FuelMetadata, string)
{
std::string modelConfig;

// Test <world>
metaMsg.Clear();
metaMsg.mutable_world()->set_file("world.sdf");
EXPECT_FALSE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));

metaMsg.set_name("test_world");
metaMsg.set_description("A world for testing");
metaMsg.set_version(2);
metaMsg.mutable_world()->mutable_file_format()->set_name("sdf");
metaMsg.mutable_world()->mutable_file_format()
->mutable_version()->set_major(1);
metaMsg.mutable_world()->mutable_file_format()
->mutable_version()->set_minor(7);
EXPECT_TRUE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));

EXPECT_EQ(worldConfigInput, modelConfig);

// Test <model>
metaMsg.Clear();
metaMsg.mutable_model()->set_file("model.sdf");
EXPECT_FALSE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));

metaMsg.set_name("test_model");
metaMsg.set_description("A model for testing");
metaMsg.set_version(3);
metaMsg.mutable_model()->mutable_file_format()->set_name("sdf");
metaMsg.mutable_model()->mutable_file_format()
->mutable_version()->set_major(1);
metaMsg.mutable_model()->mutable_file_format()
->mutable_version()->set_minor(7);
EXPECT_TRUE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));

metaMsg.add_authors()->set_name("Foo Bar");
metaMsg.mutable_authors(0)->set_email("[email protected]");
metaMsg.add_dependencies()->set_uri("model://some_model");
EXPECT_TRUE(msgs::ConvertFuelMetadata(metaMsg, modelConfig));
EXPECT_EQ(modelConfigInput, modelConfig);
}
}

/////////////////////////////////////////////////
TEST(UtilityTest, SetVector3)
{
Expand Down

0 comments on commit 57a1081

Please sign in to comment.