diff --git a/tesseract_common/include/tesseract_common/serialization.h b/tesseract_common/include/tesseract_common/serialization.h index bce0ab5c27f..f86a22f07f8 100644 --- a/tesseract_common/include/tesseract_common/serialization.h +++ b/tesseract_common/include/tesseract_common/serialization.h @@ -156,6 +156,28 @@ struct Serialization return true; } + template + static std::vector toArchiveBinaryData(const SerializableType& archive_type, + const std::string& name = "") + { + std::stringstream ss; + { // Must be scoped because all data is not written until the oost::archive::xml_oarchive goes out of scope + boost::archive::xml_oarchive oa(ss); + + // Boost uses the same function for serialization and deserialization so it requires a non-const reference + // Because we are only serializing here it is safe to cast away const + if (name.empty()) + oa << boost::serialization::make_nvp("archive_type", + const_cast(archive_type)); // NOLINT + else + oa << boost::serialization::make_nvp(name.c_str(), + const_cast(archive_type)); // NOLINT + } + + std::string data = ss.str(); + return std::vector(data.begin(), data.end()); + } + template static SerializableType fromArchiveStringXML(const std::string& archive_xml) { @@ -199,6 +221,21 @@ struct Serialization return archive_type; } + + template + static SerializableType fromArchiveBinaryData(const std::vector& archive_binary) + { + SerializableType archive_type; + + { // Must be scoped because all data is not written until the oost::archive::xml_oarchive goes out of scope + std::stringstream ss; + std::copy(archive_binary.begin(), archive_binary.end(), std::ostreambuf_iterator(ss)); + boost::archive::xml_iarchive ia(ss); + ia >> BOOST_SERIALIZATION_NVP(archive_type); + } + + return archive_type; + } }; } // namespace tesseract_common #endif // TESSERACT_COMMON_SERIALIZATION_H diff --git a/tesseract_common/include/tesseract_common/unit_test_utils.h b/tesseract_common/include/tesseract_common/unit_test_utils.h index 79fbcaf6b0d..5b1d2a5ac48 100644 --- a/tesseract_common/include/tesseract_common/unit_test_utils.h +++ b/tesseract_common/include/tesseract_common/unit_test_utils.h @@ -70,6 +70,15 @@ void testSerialization(const SerializableType& object, const std::string& typena SerializableType nobject{ tesseract_common::Serialization::fromArchiveStringXML(object_string) }; EXPECT_FALSE(object != nobject); // Using != because it call == for code coverage } + + { // Archive program to binary data + std::vector object_data = + tesseract_common::Serialization::toArchiveBinaryData(object, typename_string); + EXPECT_FALSE(object_data.empty()); + + SerializableType nobject{ tesseract_common::Serialization::fromArchiveBinaryData(object_data) }; + EXPECT_FALSE(object != nobject); // Using != because it call == for code coverage + } } /** @@ -109,6 +118,17 @@ void testSerializationPtr(const std::shared_ptr& object, const tesseract_common::Serialization::fromArchiveStringXML>(object_string); EXPECT_FALSE(*object != *nobject); // Using != because it call == for code coverage } + + { // Archive program to binary data + std::vector object_data = + tesseract_common::Serialization::toArchiveBinaryData>(object, + typename_string); + EXPECT_FALSE(object_data.empty()); + + auto nobject = + tesseract_common::Serialization::fromArchiveBinaryData>(object_data); + EXPECT_FALSE(*object != *nobject); // Using != because it call == for code coverage + } } /** @@ -161,6 +181,20 @@ void testSerializationDerivedClass(const std::shared_ptr& auto object_derived = std::dynamic_pointer_cast(object); EXPECT_FALSE(*object_derived != *nobject_derived); // Using != because it call == for code coverage } + + { // Archive program to binary data + std::vector object_data = + tesseract_common::Serialization::toArchiveBinaryData>(object, + typename_string); + EXPECT_FALSE(object_data.empty()); + + auto nobject = + tesseract_common::Serialization::fromArchiveBinaryData>(object_data); + auto nobject_derived = std::dynamic_pointer_cast(nobject); + + auto object_derived = std::dynamic_pointer_cast(object); + EXPECT_FALSE(*object_derived != *nobject_derived); // Using != because it call == for code coverage + } } } // namespace tesseract_common #endif // TESSERACT_COMMON_UTILS_H