// the image writer and reader #include #include #include #include #include #include namespace image { class BinaryWriter: public boost::archive::detail::common_oarchive { //................................................................. methods public: BinaryWriter(std::ostream& os): boost::archive::detail::common_oarchive(0), _os(os) { } void save_binary(const void *address, std::size_t size) { if (!_os.write((const char*)address, size)) throw std::runtime_error("Cannot write binary image file!"); }; template void save_override(const T& t, int) { boost::archive::save(*this, t); } void save_override(const boost::archive::version_type&, int) {} void save_override(const boost::archive::object_id_type&, int) {} void save_override(const boost::archive::class_id_type&, int) {} void save_override(const boost::archive::class_id_optional_type&, int) {} void save_override(const boost::archive::class_id_reference_type&, int) {} void save_override(const boost::archive::tracking_type&, int) {} //................................................................. methods private: template void save(const T &t) { save_binary(&t, sizeof(T)); } friend class boost::archive::save_access; private: std::ostream& _os; }; class BinaryReader: public boost::archive::detail::common_iarchive { //................................................................. methods public: BinaryReader(std::istream& is): boost::archive::detail::common_iarchive(0), _is(is) { } template void load_override(T& t, int) { boost::archive::load(*this, t); } void load_override(boost::archive::version_type&, int) {} void load_override(boost::archive::object_id_type&, int) {} void load_override(boost::archive::class_id_type&, int) {} void load_override(boost::archive::class_id_optional_type&, int) {} void load_override(boost::archive::class_id_reference_type&, int) {} void load_override(boost::archive::tracking_type&, int) {} void load_binary(void *address, std::size_t size) { if (!_is.read((char*)address, size)) throw std::runtime_error("Cannot read binary image file!"); }; //................................................................. methods private: template void load(T &t) { load_binary(&t, sizeof(T)); } friend class boost::archive::load_access; //............................................................... variables private: std::istream& _is; }; } // make string streamable (does not work with boost/serializable/string.hpp) (!) // probably because class and version info is filtrered out... #include #include namespace boost { namespace serialization { // the following does not work - why?!? //BOOST_SERIALIZATION_SPLIT_FREE(std::string); template void serialize(Archive& ar, std::string& s, const unsigned int v) { split_free(ar, s, v); } template void save(Archive& ar, const std::string& s, const unsigned int) { int sz(s.size()); ar & sz; ar.save_binary((const void*)s.begin().operator->(), s.size()); } template void load(Archive& ar, std::string& s, const unsigned int) { std::string::size_type sz; ar & sz; s.resize(sz); ar.load_binary((void*)s.begin().operator->(), s.size()); } } } // print binary data #include #include #include inline std::string binary(const std::string& s) { std::string::size_type size(s.size()); std::string result; std::string txt; std::auto_ptr hex(new std::stringstream); for (std::string::size_type i(0); i=32&&(unsigned char)s[i]<128)?s[i]:'.'; if (i%10==9) { result+=hex->str()+txt+"\n"; // Stupid std::stringstream has no way to clear buffer... hex = std::auto_ptr(new std::stringstream); txt.clear(); } } if (txt.size()) result+=hex->str()+std::string(30-hex->str().size(), ' ')+txt+"\n"; return result; } // main, test the whole thing... #include int main(int, char const*const*const) try { std::string s("Hallo Welt!"); int i(4712); std::stringstream ss; image::BinaryWriter out(ss); out & s & i; std::cout<<"Stream contains: "<