Skip to content

Commit 5bd09a9

Browse files
Fix decoder and encode mismatch fails YAML deserialization. (#2277) (#2298)
* Fix decoder and encode mismatch fails YAML deserialization. * Change decoder to handle Sequence with Map compatibility. --------- (cherry picked from commit 141537e) Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com> Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
1 parent 5052864 commit 5bd09a9

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

rosbag2_storage/src/rosbag2_storage/qos.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -279,27 +279,42 @@ Node convert<std::unordered_map<std::string, rclcpp::QoS>>::encode(
279279
{
280280
Node node{NodeType::Sequence};
281281
for (const auto & [key, value] : rhs) {
282-
node.force_insert(key, value);
282+
Node element;
283+
element["topic"] = key;
284+
element["qos"] = value;
285+
node.push_back(element);
283286
}
284287
return node;
285288
}
286289

287290
bool convert<std::unordered_map<std::string, rclcpp::QoS>>::decode(
288291
const Node & node, std::unordered_map<std::string, rclcpp::QoS> & rhs, int version)
289292
{
290-
if (!node.IsMap()) {
293+
rhs.clear();
294+
295+
if (node.IsSequence()) {
296+
// New sequence format
297+
for (const auto & element : node) {
298+
std::string topic = element["topic"].as<std::string>();
299+
// Using rosbag2_storage::Rosbag2QoS for decoding because rclcpp::QoS is not default
300+
// constructable. Note: It is safe to use upcast when inserting into the unordered_map
301+
rhs.insert(
302+
{topic, decode_for_version<rosbag2_storage::Rosbag2QoS>(element["qos"], version)});
303+
}
304+
} else if (node.IsMap()) {
305+
// Legacy map format for backward compatibility
306+
for (const auto & element : node) {
307+
// Using rosbag2_storage::Rosbag2QoS for decoding because rclcpp::QoS is not default
308+
// constructable. Note: It is safe to use upcast when inserting into the unordered_map
309+
rhs.insert(
310+
{element.first.as<std::string>(),
311+
decode_for_version<rosbag2_storage::Rosbag2QoS>(element.second, version)
312+
});
313+
}
314+
} else {
291315
return false;
292316
}
293317

294-
rhs.clear();
295-
for (const auto & element : node) {
296-
// Using rosbag2_storage::Rosbag2QoS for decoding because rclcpp::QoS is not default
297-
// constructable. Note: It is safe to use upcast when inserting into the unordered_map
298-
rhs.insert(
299-
{element.first.as<std::string>(),
300-
decode_for_version<rosbag2_storage::Rosbag2QoS>(element.second, version)
301-
});
302-
}
303318
return true;
304319
}
305320
} // namespace YAML

rosbag2_transport/test/rosbag2_transport/test_record_options.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,19 @@ TEST(record_options, test_yaml_decode_for_all_and_exclude)
7878
ASSERT_EQ(record_options.regex, "[xyz]/topic");
7979
ASSERT_EQ(record_options.exclude_regex, "[x]/topic");
8080
}
81+
82+
TEST(record_options, test_large_serialization)
83+
{
84+
rosbag2_transport::RecordOptions options;
85+
options.topics = std::vector<std::string>(100000, "test_topic");
86+
options.services = std::vector<std::string>(100000, "test_service");
87+
88+
ASSERT_NO_THROW({
89+
auto node = YAML::convert<rosbag2_transport::RecordOptions>().encode(options);
90+
std::stringstream serializer;
91+
serializer << node;
92+
auto recreated_node = YAML::Load(serializer.str()).as<rosbag2_transport::RecordOptions>();
93+
ASSERT_EQ(options.topics, recreated_node.topics);
94+
ASSERT_EQ(options.services, recreated_node.services);
95+
});
96+
}

0 commit comments

Comments
 (0)