Merge pull request #343 from borglab/fix/serializationToFile

SerializeToXMLFile fix
release/4.3a0
Varun Agrawal 2020-06-24 19:07:35 -05:00 committed by GitHub
commit 34180fb816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 210 additions and 87 deletions

View File

@ -42,123 +42,218 @@
namespace gtsam { namespace gtsam {
// Serialization directly to strings in compressed format /** @name Standard serialization
template<class T> * Serialization in default compressed format
std::string serialize(const T& input) { */
std::ostringstream out_archive_stream; ///@{
/// serializes to a stream
template <class T>
void serializeToStream(const T& input, std::ostream& out_archive_stream) {
boost::archive::text_oarchive out_archive(out_archive_stream); boost::archive::text_oarchive out_archive(out_archive_stream);
out_archive << input; out_archive << input;
return out_archive_stream.str();
} }
template<class T> /// deserializes from a stream
void deserialize(const std::string& serialized, T& output) { template <class T>
std::istringstream in_archive_stream(serialized); void deserializeFromStream(std::istream& in_archive_stream, T& output) {
boost::archive::text_iarchive in_archive(in_archive_stream); boost::archive::text_iarchive in_archive(in_archive_stream);
in_archive >> output; in_archive >> output;
} }
template<class T> /// serializes to a string
template <class T>
std::string serializeToString(const T& input) {
std::ostringstream out_archive_stream;
serializeToStream(input, out_archive_stream);
return out_archive_stream.str();
}
/// deserializes from a string
template <class T>
void deserializeFromString(const std::string& serialized, T& output) {
std::istringstream in_archive_stream(serialized);
deserializeFromStream(in_archive_stream, output);
}
/// serializes to a file
template <class T>
bool serializeToFile(const T& input, const std::string& filename) { bool serializeToFile(const T& input, const std::string& filename) {
std::ofstream out_archive_stream(filename.c_str()); std::ofstream out_archive_stream(filename.c_str());
if (!out_archive_stream.is_open()) if (!out_archive_stream.is_open()) return false;
return false; serializeToStream(input, out_archive_stream);
boost::archive::text_oarchive out_archive(out_archive_stream);
out_archive << input;
out_archive_stream.close(); out_archive_stream.close();
return true; return true;
} }
template<class T> /// deserializes from a file
template <class T>
bool deserializeFromFile(const std::string& filename, T& output) { bool deserializeFromFile(const std::string& filename, T& output) {
std::ifstream in_archive_stream(filename.c_str()); std::ifstream in_archive_stream(filename.c_str());
if (!in_archive_stream.is_open()) if (!in_archive_stream.is_open()) return false;
return false; deserializeFromStream(in_archive_stream, output);
boost::archive::text_iarchive in_archive(in_archive_stream);
in_archive >> output;
in_archive_stream.close(); in_archive_stream.close();
return true; return true;
} }
// Serialization to XML format with named structures /// serializes to a string
template<class T> template <class T>
std::string serializeXML(const T& input, const std::string& name="data") { std::string serialize(const T& input) {
std::ostringstream out_archive_stream; return serializeToString(input);
// braces to flush out_archive as it goes out of scope before taking str()
// fixes crash with boost 1.66-1.68
// see https://github.com/boostorg/serialization/issues/82
{
boost::archive::xml_oarchive out_archive(out_archive_stream);
out_archive << boost::serialization::make_nvp(name.c_str(), input);
}
return out_archive_stream.str();
} }
template<class T> /// deserializes from a string
void deserializeXML(const std::string& serialized, T& output, const std::string& name="data") { template <class T>
std::istringstream in_archive_stream(serialized); void deserialize(const std::string& serialized, T& output) {
boost::archive::xml_iarchive in_archive(in_archive_stream); deserializeFromString(serialized, output);
in_archive >> boost::serialization::make_nvp(name.c_str(), output);
} }
///@}
template<class T> /** @name XML Serialization
bool serializeToXMLFile(const T& input, const std::string& filename, const std::string& name="data") { * Serialization to XML format with named structures
std::ofstream out_archive_stream(filename.c_str()); */
if (!out_archive_stream.is_open()) ///@{
return false; /// serializes to a stream in XML
template <class T>
void serializeToXMLStream(const T& input, std::ostream& out_archive_stream,
const std::string& name = "data") {
boost::archive::xml_oarchive out_archive(out_archive_stream); boost::archive::xml_oarchive out_archive(out_archive_stream);
out_archive << boost::serialization::make_nvp(name.c_str(), input);; out_archive << boost::serialization::make_nvp(name.c_str(), input);
out_archive_stream.close();
return true;
} }
template<class T> /// deserializes from a stream in XML
bool deserializeFromXMLFile(const std::string& filename, T& output, const std::string& name="data") { template <class T>
std::ifstream in_archive_stream(filename.c_str()); void deserializeFromXMLStream(std::istream& in_archive_stream, T& output,
if (!in_archive_stream.is_open()) const std::string& name = "data") {
return false;
boost::archive::xml_iarchive in_archive(in_archive_stream); boost::archive::xml_iarchive in_archive(in_archive_stream);
in_archive >> boost::serialization::make_nvp(name.c_str(), output); in_archive >> boost::serialization::make_nvp(name.c_str(), output);
in_archive_stream.close();
return true;
} }
// Serialization to binary format with named structures /// serializes to a string in XML
template<class T> template <class T>
std::string serializeBinary(const T& input, const std::string& name="data") { std::string serializeToXMLString(const T& input,
const std::string& name = "data") {
std::ostringstream out_archive_stream; std::ostringstream out_archive_stream;
boost::archive::binary_oarchive out_archive(out_archive_stream); serializeToXMLStream(input, out_archive_stream, name);
out_archive << boost::serialization::make_nvp(name.c_str(), input);
return out_archive_stream.str(); return out_archive_stream.str();
} }
template<class T> /// deserializes from a string in XML
void deserializeBinary(const std::string& serialized, T& output, const std::string& name="data") { template <class T>
void deserializeFromXMLString(const std::string& serialized, T& output,
const std::string& name = "data") {
std::istringstream in_archive_stream(serialized); std::istringstream in_archive_stream(serialized);
boost::archive::binary_iarchive in_archive(in_archive_stream); deserializeFromXMLStream(in_archive_stream, output, name);
in_archive >> boost::serialization::make_nvp(name.c_str(), output);
} }
template<class T> /// serializes to an XML file
bool serializeToBinaryFile(const T& input, const std::string& filename, const std::string& name="data") { template <class T>
bool serializeToXMLFile(const T& input, const std::string& filename,
const std::string& name = "data") {
std::ofstream out_archive_stream(filename.c_str()); std::ofstream out_archive_stream(filename.c_str());
if (!out_archive_stream.is_open()) if (!out_archive_stream.is_open()) return false;
return false; serializeToXMLStream(input, out_archive_stream, name);
boost::archive::binary_oarchive out_archive(out_archive_stream);
out_archive << boost::serialization::make_nvp(name.c_str(), input);
out_archive_stream.close(); out_archive_stream.close();
return true; return true;
} }
template<class T> /// deserializes from an XML file
bool deserializeFromBinaryFile(const std::string& filename, T& output, const std::string& name="data") { template <class T>
bool deserializeFromXMLFile(const std::string& filename, T& output,
const std::string& name = "data") {
std::ifstream in_archive_stream(filename.c_str()); std::ifstream in_archive_stream(filename.c_str());
if (!in_archive_stream.is_open()) if (!in_archive_stream.is_open()) return false;
return false; deserializeFromXMLStream(in_archive_stream, output, name);
boost::archive::binary_iarchive in_archive(in_archive_stream);
in_archive >> boost::serialization::make_nvp(name.c_str(), output);
in_archive_stream.close(); in_archive_stream.close();
return true; return true;
} }
} // \namespace gtsam /// serializes to a string in XML
template <class T>
std::string serializeXML(const T& input,
const std::string& name = "data") {
return serializeToXMLString(input, name);
}
/// deserializes from a string in XML
template <class T>
void deserializeXML(const std::string& serialized, T& output,
const std::string& name = "data") {
deserializeFromXMLString(serialized, output, name);
}
///@}
/** @name Binary Serialization
* Serialization to binary format with named structures
*/
///@{
/// serializes to a stream in binary
template <class T>
void serializeToBinaryStream(const T& input, std::ostream& out_archive_stream,
const std::string& name = "data") {
boost::archive::binary_oarchive out_archive(out_archive_stream);
out_archive << boost::serialization::make_nvp(name.c_str(), input);
}
/// deserializes from a stream in binary
template <class T>
void deserializeFromBinaryStream(std::istream& in_archive_stream, T& output,
const std::string& name = "data") {
boost::archive::binary_iarchive in_archive(in_archive_stream);
in_archive >> boost::serialization::make_nvp(name.c_str(), output);
}
/// serializes to a string in binary
template <class T>
std::string serializeToBinaryString(const T& input,
const std::string& name = "data") {
std::ostringstream out_archive_stream;
serializeToBinaryStream(input, out_archive_stream, name);
return out_archive_stream.str();
}
/// deserializes from a string in binary
template <class T>
void deserializeFromBinaryString(const std::string& serialized, T& output,
const std::string& name = "data") {
std::istringstream in_archive_stream(serialized);
deserializeFromBinaryStream(in_archive_stream, output, name);
}
/// serializes to a binary file
template <class T>
bool serializeToBinaryFile(const T& input, const std::string& filename,
const std::string& name = "data") {
std::ofstream out_archive_stream(filename.c_str());
if (!out_archive_stream.is_open()) return false;
serializeToBinaryStream(input, out_archive_stream, name);
out_archive_stream.close();
return true;
}
/// deserializes from a binary file
template <class T>
bool deserializeFromBinaryFile(const std::string& filename, T& output,
const std::string& name = "data") {
std::ifstream in_archive_stream(filename.c_str());
if (!in_archive_stream.is_open()) return false;
deserializeFromBinaryStream(in_archive_stream, output, name);
in_archive_stream.close();
return true;
}
/// serializes to a string in binary
template <class T>
std::string serializeBinary(const T& input,
const std::string& name = "data") {
return serializeToBinaryString(input, name);
}
/// deserializes from a string in binary
template <class T>
void deserializeBinary(const std::string& serialized, T& output,
const std::string& name = "data") {
deserializeFromBinaryString(serialized, output, name);
}
///@}
} // namespace gtsam

View File

@ -26,6 +26,7 @@
#include <gtsam/base/serialization.h> #include <gtsam/base/serialization.h>
#include <boost/serialization/serialization.hpp> #include <boost/serialization/serialization.hpp>
#include <boost/filesystem.hpp>
// whether to print the serialized text to stdout // whether to print the serialized text to stdout
@ -40,22 +41,37 @@ T create() {
return T(); return T();
} }
// Creates or empties a folder in the build folder and returns the relative path
boost::filesystem::path resetFilesystem(
boost::filesystem::path folder = "actual") {
boost::filesystem::remove_all(folder);
boost::filesystem::create_directory(folder);
return folder;
}
// Templated round-trip serialization // Templated round-trip serialization
template<class T> template<class T>
void roundtrip(const T& input, T& output) { void roundtrip(const T& input, T& output) {
// Serialize
std::string serialized = serialize(input); std::string serialized = serialize(input);
if (verbose) std::cout << serialized << std::endl << std::endl; if (verbose) std::cout << serialized << std::endl << std::endl;
deserialize(serialized, output); deserialize(serialized, output);
} }
// This version requires equality operator // Templated round-trip serialization using a file
template<class T>
void roundtripFile(const T& input, T& output) {
boost::filesystem::path path = resetFilesystem()/"graph.dat";
serializeToFile(input, path.string());
deserializeFromFile(path.string(), output);
}
// This version requires equality operator and uses string and file round-trips
template<class T> template<class T>
bool equality(const T& input = T()) { bool equality(const T& input = T()) {
T output = create<T>(); T output = create<T>(), outputf = create<T>();
roundtrip<T>(input,output); roundtrip<T>(input,output);
return input==output; roundtripFile<T>(input,outputf);
return (input==output) && (input==outputf);
} }
// This version requires Testable // This version requires Testable
@ -77,20 +93,26 @@ bool equalsDereferenced(const T& input) {
// Templated round-trip serialization using XML // Templated round-trip serialization using XML
template<class T> template<class T>
void roundtripXML(const T& input, T& output) { void roundtripXML(const T& input, T& output) {
// Serialize
std::string serialized = serializeXML<T>(input); std::string serialized = serializeXML<T>(input);
if (verbose) std::cout << serialized << std::endl << std::endl; if (verbose) std::cout << serialized << std::endl << std::endl;
// De-serialize
deserializeXML(serialized, output); deserializeXML(serialized, output);
} }
// Templated round-trip serialization using XML File
template<class T>
void roundtripXMLFile(const T& input, T& output) {
boost::filesystem::path path = resetFilesystem()/"graph.xml";
serializeToXMLFile(input, path.string());
deserializeFromXMLFile(path.string(), output);
}
// This version requires equality operator // This version requires equality operator
template<class T> template<class T>
bool equalityXML(const T& input = T()) { bool equalityXML(const T& input = T()) {
T output = create<T>(); T output = create<T>(), outputf = create<T>();
roundtripXML<T>(input,output); roundtripXML<T>(input,output);
return input==output; roundtripXMLFile<T>(input,outputf);
return (input==output) && (input==outputf);
} }
// This version requires Testable // This version requires Testable
@ -112,20 +134,26 @@ bool equalsDereferencedXML(const T& input = T()) {
// Templated round-trip serialization using XML // Templated round-trip serialization using XML
template<class T> template<class T>
void roundtripBinary(const T& input, T& output) { void roundtripBinary(const T& input, T& output) {
// Serialize
std::string serialized = serializeBinary<T>(input); std::string serialized = serializeBinary<T>(input);
if (verbose) std::cout << serialized << std::endl << std::endl; if (verbose) std::cout << serialized << std::endl << std::endl;
// De-serialize
deserializeBinary(serialized, output); deserializeBinary(serialized, output);
} }
// Templated round-trip serialization using Binary file
template<class T>
void roundtripBinaryFile(const T& input, T& output) {
boost::filesystem::path path = resetFilesystem()/"graph.bin";
serializeToBinaryFile(input, path.string());
deserializeFromBinaryFile(path.string(), output);
}
// This version requires equality operator // This version requires equality operator
template<class T> template<class T>
bool equalityBinary(const T& input = T()) { bool equalityBinary(const T& input = T()) {
T output = create<T>(); T output = create<T>(), outputf = create<T>();
roundtripBinary<T>(input,output); roundtripBinary<T>(input,output);
return input==output; roundtripBinaryFile<T>(input,outputf);
return (input==output) && (input==outputf);
} }
// This version requires Testable // This version requires Testable