Skip to content

Instantly share code, notes, and snippets.

@RobertHue
Last active September 12, 2017 10:12
Show Gist options
  • Save RobertHue/ff79aa9afb60069abb4dc1060e9d4b7a to your computer and use it in GitHub Desktop.
Save RobertHue/ff79aa9afb60069abb4dc1060e9d4b7a to your computer and use it in GitHub Desktop.
Custom_Archive.hpp (boost::serialization) deriving from common_archive
/*
* Custom_Archive.hpp
*
* Created on: Sep 8, 2017
* Author: robert
*/
#ifndef Custom_ARCHIVE_HPP_
#define Custom_ARCHIVE_HPP_
#include <boost/config.hpp>
// for debug info
#include <iostream>
#include <fstream>
#include <ostream>
#include <istream>
#include <typeinfo>
#include <boost/archive/binary_oarchive_impl.hpp>
#include <boost/archive/binary_iarchive_impl.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
#include <boost/mpl/assert.hpp> // for BOOST_MPL_ASSER(( pred ));
namespace boost {
namespace archive {
inline std::string demangle(const char* name) {
int status = -4; // some arbitrary value to eliminate the compiler warning
// enable c++11 by passing the flag -std=c++11 to g++
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status==0) ? res.get() : name ;
}
////////////////////////////////////////////////////
////////////////// Custom OUTPUT ARCHIVE
////////////////////////////////////////////////////
class Custom_OArchive
: public boost::archive::detail::common_oarchive<Custom_OArchive>
{
// permit serialization system privileged access to permit
// implementation of inline templates for maimum speed
friend class save_access;
// member template for saving primitive types.
// Spezialize for any types/templates that need any special treatment
template<typename T>
void save(T& t) {
std::cout << "Save-Type: " << demangle(typeid(T).name()) << " with value: " << t << std::endl;
}
public:
////////////////////////////////////////////////////////////////
// public interface used by programs that use the
// serialization library
Custom_OArchive(const char * filename, unsigned int flags = 0)
: file(), status(), memtype(), space(), dset()
{
std::cout << "Construct Custom_OArchive with filename: " << filename << std::endl;
}
~Custom_OArchive() {
/*
* Release resources
*/
}
// archives are expected to support this function
void save_binary(void const* address, std::size_t count) {
std::cout << "save binary with " << address << " and count of " << count << std::endl;
}
/** Used to inject an object name into an archive */
void save_start(char const *name) {
std::cout << "save_start with param:" << name << std::endl;
}
/** Used to inject an object name into an archive */
void save_end(char const *name) {
std::cout << "save_end with param:" << name << std::endl;
}
/** Used to inject an object name into an archive */
void end_preamble() {
std::cout << "end_preamble" << std::endl;
}
// Anything not an attribute and not a name-value pair is an
// error and should be trapped here.
template<class T>
void save_override(T & t, BOOST_PFTO int)
{
std::cout << "save_override of " << demangle(typeid(T).name()) << std::endl;
// If your program fails to compile here, its most likely due to
// not specifying an nvp wrapper around the variable to
// be serialized.
BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
this->detail_common_oarchive::save_override(t, 0);
}
// special treatment for name-value pairs.
typedef detail::common_oarchive<Custom_OArchive> detail_common_oarchive;
template<class T>
void save_override(
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
const
#endif
::boost::serialization::nvp< T > & t,
int
) {
std::cout << "start" << std::endl;
this->This()->save_start(t.name());
this->detail_common_oarchive::save_override(t.const_value(), 0);
this->This()->save_end(t.name());
std::cout << "end" << std::endl;
}
// specific overrides for attributes - not name value pairs so we
// want to trap them before the above "fall through"
// ...
void save_override(const object_id_type & t, int) {
common_functionality(t);
}
void save_override(const object_reference_type & t, int) {
common_functionality(t);
}
void save_override(const version_type & t, int) {
common_functionality(t);
}
void save_override(const class_id_type & t, int) {
common_functionality(t);
}
void save_override(const class_id_optional_type & t, int) {
common_functionality(t);
}
void save_override(const class_id_reference_type & t, int) {
common_functionality(t);
}
void save_override(const class_name_type & t, int) {
common_functionality(t);
}
void save_override(const tracking_type & t, int) {
common_functionality(t);
}
private:
template<typename T>
void common_functionality(const T & t) {
std::cout << "common_functionality-Type: " << demangle(typeid(T).name()) << " with value: " << t << std::endl;
}
hid_t file, memtype, space, dset;
herr_t status;
};
////////////////////////////////////////////////////
////////////////// Custom INPUT ARCHIVE
////////////////////////////////////////////////////
class Custom_IArchive
: public boost::archive::detail::common_iarchive<Custom_IArchive>
{
// permit serialization system privileged access to permit
// implementation of inline templates for maimum speed
friend class load_access;
// member template for saving primitive types.
// Spezialize for any types/templates that need any special treatment
template<typename T>
void load(T& t) {
std::cout << "Load-Type: " << demangle(typeid(T).name()) << " with value: " << t << std::endl;
}
public:
////////////////////////////////////////////////////////////////
// public interface used by programs that use the
// serialization library
Custom_IArchive(const char * filename, unsigned int flags = 0)
{
std::cout << "Construct Custom_IArchive with filename: " << filename << std::endl;
}
// archives are expected to support this function
void load_binary(void* address, std::size_t count) {
std::cout << "load binary with " << address << " and count of " << count << std::endl;
}
/** Used to inject an object name into an archive */
void load_start(char const *name) {
std::cout << "load_start with param: " << name << std::endl;
}
/** Used to inject an object name into an archive */
void load_end(char const *name) {
std::cout << "load_end with param: " << name << std::endl;
}
/** Used to inject an object name into an archive */
void end_preamble() {
std::cout << "end_preamble" << std::endl;
}
// template<class T> void load_override(T & t, int) {
// std::cout << "load_override of " << demangle(typeid(T).name()) << std::endl;
// boost::archive::detail::common_iarchive<Custom_iarchive>::template load_override<T>(t, 0);
// this->detail_common_oarchive::save_override(t, 0); // better than above
// }
};
} // namespace archive
} // namespace boost
#endif /* Custom_ARCHIVE_HPP_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment