Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/serialization/example/demo.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 11.1 KB
Line 
1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// demo.cpp
3//
4// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
5// Use, modification and distribution is subject to the Boost Software
6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9
10#include <iomanip>
11#include <iostream>
12#include <fstream>
13#include <string>
14
15#include <boost/archive/tmpdir.hpp>
16
17#include <boost/archive/text_iarchive.hpp>
18#include <boost/archive/text_oarchive.hpp>
19
20#include <boost/serialization/base_object.hpp>
21#include <boost/serialization/utility.hpp>
22#include <boost/serialization/list.hpp>
23
24/////////////////////////////////////////////////////////////
25// The intent of this program is to serve as a tutorial for
26// users of the serialization package.  An attempt has been made
27// to illustrate most of the facilities of the package. 
28//
29// The intent is to create an example suffciently complete to
30// illustrate the usage and utility of the package while
31// including a minimum of other code.
32//
33// This illustration models the bus system of a small city.
34// This includes, multiple bus stops,  bus routes and schedules.
35// There are different kinds of stops.  Bus stops in general will
36// will appear on multiple routes.  A schedule will include
37// muliple trips on the same route.
38
39/////////////////////////////////////////////////////////////
40// gps coordinate
41//
42// llustrates serialization for a simple type
43//
44class gps_position
45{
46    friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
47    friend class boost::serialization::access;
48    int degrees;
49    int minutes;
50    float seconds;
51    template<class Archive>
52    void serialize(Archive & ar, const unsigned int /* file_version */){
53        ar & degrees & minutes & seconds;
54    }
55public:
56    // every serializable class needs a constructor
57    gps_position(){};
58    gps_position(int _d, int _m, float _s) : 
59        degrees(_d), minutes(_m), seconds(_s)
60    {}
61};
62std::ostream & operator<<(std::ostream &os, const gps_position &gp)
63{
64    return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
65}
66
67/////////////////////////////////////////////////////////////
68// One bus stop
69//
70// illustrates serialization of serializable members
71//
72
73class bus_stop
74{
75    friend class boost::serialization::access;
76    friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
77    virtual std::string description() const = 0;
78    gps_position latitude;
79    gps_position longitude;
80    template<class Archive>
81    void serialize(Archive &ar, const unsigned int version)
82    {
83        ar & latitude;
84        ar & longitude;
85    }
86protected:
87    bus_stop(const gps_position & _lat, const gps_position & _long) :
88        latitude(_lat), longitude(_long)
89    {}
90public:
91    bus_stop(){}
92    virtual ~bus_stop(){}
93};
94
95BOOST_IS_ABSTRACT(bus_stop)
96
97std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
98{
99    return os << bs.latitude << bs.longitude << ' ' << bs.description();
100}
101
102/////////////////////////////////////////////////////////////
103// Several kinds of bus stops
104//
105// illustrates serialization of derived types
106//
107class bus_stop_corner : public bus_stop
108{
109    friend class boost::serialization::access;
110    std::string street1;
111    std::string street2;
112    virtual std::string description() const
113    {
114        return street1 + " and " + street2;
115    }
116    template<class Archive>
117    void serialize(Archive &ar, const unsigned int version)
118    {
119        // save/load base class information
120        ar & boost::serialization::base_object<bus_stop>(*this);
121        ar & street1 & street2;
122    }
123
124public:
125    bus_stop_corner(){}
126    bus_stop_corner(const gps_position & _lat, const gps_position & _long,
127        const std::string & _s1, const std::string & _s2
128    ) :
129        bus_stop(_lat, _long), street1(_s1), street2(_s2)
130    {
131    }
132};
133
134class bus_stop_destination : public bus_stop
135{
136    friend class boost::serialization::access;
137    std::string name;
138    virtual std::string description() const
139    {
140        return name;
141    }
142    template<class Archive>
143    void serialize(Archive &ar, const unsigned int version)
144    {
145        ar & boost::serialization::base_object<bus_stop>(*this) & name;
146    }
147public:
148   
149    bus_stop_destination(){}
150    bus_stop_destination(
151        const gps_position & _lat, const gps_position & _long, const std::string & _name
152    ) :
153        bus_stop(_lat, _long), name(_name)
154    {
155    }
156};
157
158/////////////////////////////////////////////////////////////
159// a bus route is a collection of bus stops
160//
161// illustrates serialization of STL collection templates.
162//
163// illustrates serialzation of polymorphic pointer (bus stop *);
164//
165// illustrates storage and recovery of shared pointers is correct
166// and efficient.  That is objects pointed to by more than one
167// pointer are stored only once.  In such cases only one such
168// object is restored and pointers are restored to point to it
169//
170class bus_route
171{
172    friend class boost::serialization::access;
173    friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
174    typedef bus_stop * bus_stop_pointer;
175    std::list<bus_stop_pointer> stops;
176    template<class Archive>
177    void serialize(Archive &ar, const unsigned int version)
178    {
179        // in this program, these classes are never serialized directly but rather
180        // through a pointer to the base class bus_stop. So we need a way to be
181        // sure that the archive contains information about these derived classes.
182        //ar.template register_type<bus_stop_corner>();
183        ar.register_type(static_cast<bus_stop_corner *>(NULL));
184        //ar.template register_type<bus_stop_destination>();
185        ar.register_type(static_cast<bus_stop_destination *>(NULL));
186        // serialization of stl collections is already defined
187        // in the header
188        ar & stops;
189    }
190public:
191    bus_route(){}
192    void append(bus_stop *_bs)
193    {
194        stops.insert(stops.end(), _bs);
195    }
196};
197std::ostream & operator<<(std::ostream &os, const bus_route &br)
198{
199    std::list<bus_stop *>::const_iterator it;
200    // note: we're displaying the pointer to permit verification
201    // that duplicated pointers are properly restored.
202    for(it = br.stops.begin(); it != br.stops.end(); it++){
203        os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
204    }
205    return os;
206}
207
208/////////////////////////////////////////////////////////////
209// a bus schedule is a collection of routes each with a starting time
210//
211// Illustrates serialization of STL objects(pair) in a non-intrusive way.
212// See definition of operator<< <pair<F, S> >(ar, pair) and others in
213// serialization.hpp
214//
215// illustrates nesting of serializable classes
216//
217// illustrates use of version number to automatically grandfather older
218// versions of the same class.
219
220class bus_schedule
221{
222public:
223    // note: this structure was made public. because the friend declarations
224    // didn't seem to work as expected.
225    struct trip_info
226    {
227        template<class Archive>
228        void serialize(Archive &ar, const unsigned int file_version)
229        {
230            // in versions 2 or later
231            if(file_version >= 2)
232                // read the drivers name
233                ar & driver;
234            // all versions have the follwing info
235            ar & hour & minute;
236        }
237
238        // starting time
239        int hour;
240        int minute;
241        // only after system shipped was the driver's name added to the class
242        std::string driver;
243
244        trip_info(){}
245        trip_info(int _h, int _m, const std::string &_d) :
246            hour(_h), minute(_m), driver(_d)
247        {}
248    };
249private:
250    friend class boost::serialization::access;
251    friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
252    friend std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti);
253    std::list<std::pair<trip_info, bus_route *> > schedule;
254    template<class Archive>
255    void serialize(Archive &ar, const unsigned int version)
256    {
257        ar & schedule;
258    }
259public:
260    void append(const std::string &_d, int _h, int _m, bus_route *_br)
261    {
262        schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
263    }
264    bus_schedule(){}
265};
266BOOST_CLASS_VERSION(bus_schedule, 2)
267
268std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
269{
270    return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
271}
272std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
273{
274    std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
275    for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
276        os << it->first << *(it->second);
277    }
278    return os;
279}
280
281void save_schedule(const bus_schedule &s, const char * filename){
282    // make an archive
283    std::ofstream ofs(filename);
284    boost::archive::text_oarchive oa(ofs);
285    oa << s;
286}
287
288void
289restore_schedule(bus_schedule &s, const char * filename)
290{
291    // open the archive
292    std::ifstream ifs(filename);
293    boost::archive::text_iarchive ia(ifs);
294
295    // restore the schedule from the archive
296    ia >> s;
297}
298
299int main(int argc, char *argv[])
300{   
301    // make the schedule
302    bus_schedule original_schedule;
303
304    // fill in the data
305    // make a few stops
306    bus_stop *bs0 = new bus_stop_corner(
307        gps_position(34, 135, 52.560f),
308        gps_position(134, 22, 78.30f),
309        "24th Street", "10th Avenue"
310    );
311    bus_stop *bs1 = new bus_stop_corner(
312        gps_position(35, 137, 23.456f),
313        gps_position(133, 35, 54.12f),
314        "State street", "Cathedral Vista Lane"
315    );
316    bus_stop *bs2 = new bus_stop_destination(
317        gps_position(35, 136, 15.456f),
318        gps_position(133, 32, 15.300f),
319        "White House"
320    );
321    bus_stop *bs3 = new bus_stop_destination(
322        gps_position(35, 134, 48.789f),
323        gps_position(133, 32, 16.230f),
324        "Lincoln Memorial"
325    );
326
327    // make a  routes
328    bus_route route0;
329    route0.append(bs0);
330    route0.append(bs1);
331    route0.append(bs2);
332
333    // add trips to schedule
334    original_schedule.append("bob", 6, 24, &route0);
335    original_schedule.append("bob", 9, 57, &route0);
336    original_schedule.append("alice", 11, 02, &route0);
337
338    // make aother routes
339    bus_route route1;
340    route1.append(bs3);
341    route1.append(bs2);
342    route1.append(bs1);
343
344    // add trips to schedule
345    original_schedule.append("ted", 7, 17, &route1);
346    original_schedule.append("ted", 9, 38, &route1);
347    original_schedule.append("alice", 11, 47, &route1);
348
349    // display the complete schedule
350    std::cout << "original schedule";
351    std::cout << original_schedule;
352   
353    std::string filename(boost::archive::tmpdir());
354    filename += "/demofile.txt";
355
356    // save the schedule
357    save_schedule(original_schedule, filename.c_str());
358
359    // ... some time later
360    // make  a new schedule
361    bus_schedule new_schedule;
362
363    restore_schedule(new_schedule, filename.c_str());
364
365    // and display
366    std::cout << "\nrestored schedule";
367    std::cout << new_schedule;
368    // should be the same as the old one. (except for the pointer values)
369
370    delete bs0;
371    delete bs1;
372    delete bs2;
373    delete bs3;
374    return 0;
375}
Note: See TracBrowser for help on using the repository browser.