commit
34180fb816
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue