schorsch-tech.de
Software, programming and stuff
Parcel Pattern
// STL Archive + stuff
#include <boost/serialization/export.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
// IMPORTANT: Archive Headers at last
// include headers that implement a archive in xml format
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
typedef boost::archive::text_oarchive oarchive;
typedef boost::archive::text_iarchive iarchive;
#include <iostream>
#include <sstream>
#include <fstream>
#include <functional>
#include <string>
#include <memory>
struct runtime
{
template <typename T>
void accept(const T& t)
{
std::cout << "runtime::accept(): " << t << std::endl;
}
};
struct base
{
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
// we need it, even it is empty for the serialization
}
virtual void operator()(runtime& rt) = 0;
};
template <typename T>
struct parcel : base
{
parcel() : data(T()) {}
parcel(const T& d)
{
data = d;
}
T data;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base);
ar & BOOST_SERIALIZATION_NVP(data);
}
virtual void operator()(runtime& rt) override
{
rt.accept(data);
}
};
template <typename T>
std::unique_ptr<base> create_parcel(const T& d)
{
return std::make_unique<parcel<T>>(parcel<T>(d));
}
std::string wrap_parcel(base* p_envelope)
{
std::string ret;
{
std::ostringstream oss;
boost::archive::text_oarchive oa(oss);
// serialize the base pointer
oa & BOOST_SERIALIZATION_NVP(p_envelope);
ret = oss.str();
}
return ret;
}
std::unique_ptr<base> unwarp_parcel(std::string data)
{
std::istringstream iss(data);
boost::archive::text_iarchive ia(iss);
base* p = nullptr;
ia & BOOST_SERIALIZATION_NVP(p);
return std::unique_ptr<base>(p);
}
void out()
{
std::ofstream ofs("test.txt");
int payload{ 100 };
auto envelope = create_parcel(payload);
auto data = wrap_parcel(envelope.get());
ofs << data;
}
void in()
{
std::ifstream ifs("test.txt");
std::string data;
std::getline(ifs, data, '\0');
auto a = unwarp_parcel(data);
runtime rt;
(*a)(rt);
}
BOOST_CLASS_EXPORT(parcel<int>)
int main(int argc, char* argv[])
{
out();
in();
}
Categories
software
Permanent link to this post: https://www.schorsch-tech.de//posts/parcel-pattern