// demo_xml.cpp//// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .// Use, modification and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#include<iomanip>#include<iostream>#include<fstream>#include<string>#include<cstdio>// remove#include<boost/config.hpp>#ifdefined(BOOST_NO_STDC_NAMESPACE)namespace std{using::remove;}#endif#include<boost/archive/tmpdir.hpp>#include<boost/archive/xml_iarchive.hpp>#include<boost/archive/xml_oarchive.hpp>#include"demo_gps.hpp"voidsave_schedule(const bus_schedule &s,constchar* filename){// make an archive
std::ofstream ofs(filename);assert(ofs.good());
boost::archive::xml_oarchive oa(ofs);
oa <<BOOST_SERIALIZATION_NVP(s);}voidrestore_schedule(bus_schedule &s,constchar* filename){// open the archive
std::ifstream ifs(filename);assert(ifs.good());
boost::archive::xml_iarchive ia(ifs);// restore the schedule from the archive
ia >>BOOST_SERIALIZATION_NVP(s);}intmain(int argc,char*argv[]){// make the schedule
bus_schedule original_schedule;// fill in the data// make a few stops
bus_stop *bs0 =newbus_stop_corner(gps_position(34,135,52.560f),gps_position(134,22,78.30f),"24th Street","10th Avenue");
bus_stop *bs1 =newbus_stop_corner(gps_position(35,137,23.456f),gps_position(133,35,54.12f),"State street","Cathedral Vista Lane");
bus_stop *bs2 =newbus_stop_destination(gps_position(35,136,15.456f),gps_position(133,32,15.300f),"White House");
bus_stop *bs3 =newbus_stop_destination(gps_position(35,134,48.789f),gps_position(133,32,16.230f),"Lincoln Memorial");// make a routes
bus_route route0;
route0.append(bs0);
route0.append(bs1);
route0.append(bs2);// add trips to schedule
original_schedule.append("bob",6,24,&route0);
original_schedule.append("bob",9,57,&route0);
original_schedule.append("alice",11,02,&route0);// make aother routes
bus_route route1;
route1.append(bs3);
route1.append(bs2);
route1.append(bs1);// add trips to schedule
original_schedule.append("ted",7,17,&route1);
original_schedule.append("ted",9,38,&route1);
original_schedule.append("alice",11,47,&route1);// display the complete schedule
std::cout <<"original schedule";
std::cout << original_schedule;
std::string filename(boost::archive::tmpdir());
filename +="/demo.xml";// save the schedulesave_schedule(original_schedule, filename.c_str());// ... some time later// make a new schedule
bus_schedule new_schedule;restore_schedule(new_schedule, filename.c_str());// and display
std::cout <<"\nrestored schedule";
std::cout << new_schedule;// should be the same as the old one. (except for the pointer values)
std::remove(filename.c_str());delete bs0;delete bs1;delete bs2;delete bs3;return0;}
demo_gps.hpp
#ifndefBOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP#defineBOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP/1/2/3/4/5/6/7/8//// demo_gps.hpp//// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .// Use, modification and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#include<iomanip>#include<iostream>#include<fstream>#include<boost/serialization/string.hpp>#include<boost/serialization/nvp.hpp>#include<boost/serialization/utility.hpp>#include<boost/serialization/list.hpp>#include<boost/serialization/version.hpp>#include<boost/serialization/assume_abstract.hpp>// This illustration models the bus system of a small city.// This includes, multiple bus stops, bus routes and schedules.// There are different kinds of stops. Bus stops in general will// will appear on multiple routes. A schedule will include// muliple trips on the same route./// gps coordinate//// llustrates serialization for a simple type//classgps_position{friendclassboost::serialization::access;friend std::ostream &operator<<(std::ostream &os,const gps_position &gp);int degrees;int minutes;float seconds;template<classArchive>voidserialize(Archive & ar,constunsignedint/* file_version */){
ar &BOOST_SERIALIZATION_NVP(degrees)&BOOST_SERIALIZATION_NVP(minutes)&BOOST_SERIALIZATION_NVP(seconds);}public:// every serializable class needs a constructorgps_position(){};gps_position(int _d,int _m,float _s):degrees(_d),minutes(_m),seconds(_s){}};
std::ostream &operator<<(std::ostream &os,const gps_position &gp){return os <<' '<< gp.degrees <<(unsignedchar)186<< gp.minutes <<'\''<< gp.seconds <<'"';}/// One bus stop//// illustrates serialization of serializable members//classbus_stop{friendclassboost::serialization::access;virtual std::string description()const=0;
gps_position latitude;
gps_position longitude;template<classArchive>voidserialize(Archive &ar,constunsignedint version){
ar &BOOST_SERIALIZATION_NVP(latitude);
ar &BOOST_SERIALIZATION_NVP(longitude);}protected:bus_stop(const gps_position & _lat,const gps_position & _long):latitude(_lat),longitude(_long){}public:bus_stop(){}friend std::ostream &operator<<(std::ostream &os,const bus_stop &gp);virtual~bus_stop(){}};BOOST_SERIALIZATION_ASSUME_ABSTRACT(bus_stop)
std::ostream &operator<<(std::ostream &os,const bus_stop &bs){return os << bs.latitude << bs.longitude <<' '<< bs.description();}/// Several kinds of bus stops//// illustrates serialization of derived types//classbus_stop_corner:publicbus_stop{friendclassboost::serialization::access;
std::string street1;
std::string street2;virtual std::string description()const{return street1 +" and "+ street2;}template<classArchive>voidserialize(Archive &ar,constunsignedint version){// save/load base class information
ar &BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
ar &BOOST_SERIALIZATION_NVP(street1);
ar &BOOST_SERIALIZATION_NVP(street2);}public:bus_stop_corner(){}bus_stop_corner(const gps_position & _lat,const gps_position & _long,const std::string & _s1,const std::string & _s2
):bus_stop(_lat, _long),street1(_s1),street2(_s2){}};classbus_stop_destination:publicbus_stop{friendclassboost::serialization::access;
std::string name;virtual std::string description()const{return name;}template<classArchive>voidserialize(Archive &ar,constunsignedint version){
ar &BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)&BOOST_SERIALIZATION_NVP(name);}public:bus_stop_destination(){}bus_stop_destination(const gps_position & _lat,const gps_position & _long,const std::string & _name
):bus_stop(_lat, _long),name(_name){}};/// a bus route is a collection of bus stops//// illustrates serialization of STL collection templates.//// illustrates serialzation of polymorphic pointer (bus stop *);//// illustrates storage and recovery of shared pointers is correct// and efficient. That is objects pointed to by more than one// pointer are stored only once. In such cases only one such// object is restored and pointers are restored to point to it//classbus_route{friendclassboost::serialization::access;friend std::ostream &operator<<(std::ostream &os,const bus_route &br);typedef bus_stop * bus_stop_pointer;
std::list<bus_stop_pointer> stops;template<classArchive>voidserialize(Archive &ar,constunsignedint version){// in this program, these classes are never serialized directly but rather// through a pointer to the base class bus_stop. So we need a way to be// sure that the archive contains information about these derived classes.//ar.template register_type<bus_stop_corner>();
ar.register_type(static_cast<bus_stop_corner *>(NULL));//ar.template register_type<bus_stop_destination>();
ar.register_type(static_cast<bus_stop_destination *>(NULL));// serialization of stl collections is already defined// in the header
ar &BOOST_SERIALIZATION_NVP(stops);}public:bus_route(){}voidappend(bus_stop *_bs){
stops.insert(stops.end(), _bs);}};
std::ostream &operator<<(std::ostream &os,const bus_route &br){
std::list<bus_stop *>::const_iterator it;// note: we're displaying the pointer to permit verification// that duplicated pointers are properly restored.for(it = br.stops.begin(); it != br.stops.end(); it++){
os <<'\n'<< std::hex <<"0x"<<*it << std::dec <<' '<<**it;}return os;}/// a bus schedule is a collection of routes each with a starting time//// Illustrates serialization of STL objects(pair) in a non-intrusive way.// See definition of operator<< <pair<F, S> >(ar, pair)//// illustrates nesting of serializable classes//// illustrates use of version number to automatically grandfather older// versions of the same class.classbus_schedule{friendclassboost::serialization::access;friend std::ostream &operator<<(std::ostream &os,const bus_schedule &bs);template<classArchive>voidserialize(Archive &ar,constunsignedint version){
ar &BOOST_SERIALIZATION_NVP(schedule);}// note: this structure was made public. because the friend declarations// didn't seem to work as expected.public:structtrip_info{template<classArchive>voidserialize(Archive &ar,constunsignedint file_version){// in versions 2 or laterif(file_version >=2)// read the drivers name
ar &BOOST_SERIALIZATION_NVP(driver);// all versions have the follwing info
ar &BOOST_SERIALIZATION_NVP(hour)&BOOST_SERIALIZATION_NVP(minute);}// starting timeint hour;int minute;// only after system shipped was the driver's name added to the class
std::stringdriver;trip_info(){}trip_info(int _h,int _m,const std::string &_d):hour(_h),minute(_m),driver(_d){}~trip_info(){}};// friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);private:
std::list<std::pair<trip_info, bus_route *>> schedule;public:voidappend(const std::string &_d,int _h,int _m, bus_route *_br){
schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));}bus_schedule(){}};BOOST_CLASS_VERSION(bus_schedule::trip_info,3)BOOST_CLASS_VERSION(bus_schedule,2)
std::ostream &operator<<(std::ostream &os,const bus_schedule::trip_info &ti){return os <<'\n'<< ti.hour <<':'<< ti.minute <<' '<< ti.driver <<' ';}
std::ostream &operator<<(std::ostream &os,const bus_schedule &bs){
std::list<std::pair<bus_schedule::trip_info, bus_route *>>::const_iterator it;for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
os << it->first <<*(it->second);}return os;}#endif// BOOST_SERIALIZATION_EXAMPLE_DEMO_GPS_HPP