# s11n-boost.h

Go to the documentation of this file.

    00001 ///
    00002 /// \file       s11n-boost.h
    00003 ///             Non-intrusive versions of serialization functions for the
    00004 ///             record classes.  These template functions make it possible
    00005 ///             to use the record classes with the Boost::Serialization
    00006 ///             library.
    00007 ///
    00008
    00009 /*
    00010     Copyright (C) 2005-2011, Net Direct Inc. (http://www.netdirect.ca/)
    00011
    00012     This program is free software; you can redistribute it and/or modify
    00013     it under the terms of the GNU General Public License as published by
    00014     the Free Software Foundation; either version 2 of the License, or
    00015     (at your option) any later version.
    00016
    00017     This program is distributed in the hope that it will be useful,
    00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00020
    00021     See the GNU General Public License in the COPYING file at the
    00022     root directory of this project for more details.
    00023 */
    00024
    00025 #ifndef __BARRY_S11N_BOOST_H__
    00026 #define __BARRY_S11N_BOOST_H__
    00027
    00028 #include "dll.h"
    00029 #include "record.h"
    00030 #include <boost/serialization/vector.hpp>
    00031
    00032 ///////////////////////////////////////////////////////////////////////////////
    00033 // special versions
    00034 //
    00035 // BARRY_BASE_S11N_VERSION      - the base version where all record data is
    00036 //                                stored so it can be fully retrieved and
    00037 //                                uploaded to the handheld device later.
    00038 // BARRY_POD_MAP_VERSION        - if these templates are called with a version
    00039 //                                equal or greater than this, only mappable,
    00040 //                                POD data is included in the serialization
    00041 //
    00042 #define BARRY_BASE_S11N_VERSION         0
    00043 #define BARRY_POD_MAP_VERSION           1000
    00044
    00045 // namespace boost::serialization, for the non-intrusive version
    00046 namespace boost {
    00047 namespace serialization {
    00048
    00049 template <class ArchiveT>
    00050 void serialize(ArchiveT &ar, Barry::UnknownField &uf, const unsigned int ver)
    00051 {
    00052         ar & make_nvp("type", uf.type);
    00053         ar & make_nvp("data", uf.data.raw_data);
    00054 }
    00055
    00056 template <class ArchiveT>
    00057 void serialize(ArchiveT &ar, Barry::Contact::GroupLink &g, const unsigned int ver)
    00058 {
    00059         ar & make_nvp("Link", g.Link);
    00060         ar & make_nvp("Unknown", g.Unknown);
    00061 }
    00062
    00063 template <class ArchiveT>
    00064 void serialize(ArchiveT &ar, Barry::CategoryList &cl, const unsigned int ver)
    00065 {
    00066         std::vector<std::string> &sl = cl;
    00067         ar & make_nvp("CategoryList", sl);
    00068 }
    00069
    00070 template <class ArchiveT>
    00071 void serialize(ArchiveT &ar, Barry::Contact &c, const unsigned int ver)
    00072 {
    00073         ar & make_nvp("RecType", c.RecType);
    00074         ar & make_nvp("RecordId", c.RecordId);
    00075
    00076         ar & make_nvp("EmailAddresses", c.EmailAddresses);
    00077         ar & make_nvp("Phone", c.Phone);
    00078         ar & make_nvp("Fax", c.Fax);
    00079         ar & make_nvp("HomeFax", c.HomeFax);
    00080         ar & make_nvp("WorkPhone", c.WorkPhone);
    00081         ar & make_nvp("HomePhone", c.HomePhone);
    00082         ar & make_nvp("MobilePhone", c.MobilePhone);
    00083         ar & make_nvp("MobilePhone2", c.MobilePhone2);
    00084         ar & make_nvp("Pager", c.Pager);
    00085         ar & make_nvp("PIN", c.PIN);
    00086         ar & make_nvp("Radio", c.Radio);
    00087         ar & make_nvp("WorkPhone2", c.WorkPhone2);
    00088         ar & make_nvp("HomePhone2", c.HomePhone2);
    00089         ar & make_nvp("OtherPhone", c.OtherPhone);
    00090         ar & make_nvp("FirstName", c.FirstName);
    00091         ar & make_nvp("LastName", c.LastName);
    00092         ar & make_nvp("Company", c.Company);
    00093         ar & make_nvp("DefaultCommunicationsMethod", c.DefaultCommunicationsMethod);
    00094         ar & make_nvp("Address1", c.WorkAddress.Address1);
    00095         ar & make_nvp("Address2", c.WorkAddress.Address2);
    00096         ar & make_nvp("Address3", c.WorkAddress.Address3);
    00097         ar & make_nvp("City", c.WorkAddress.City);
    00098         ar & make_nvp("Province", c.WorkAddress.Province);
    00099         ar & make_nvp("PostalCode", c.WorkAddress.PostalCode);
    00100         ar & make_nvp("Country", c.WorkAddress.Country);
    00101         ar & make_nvp("JobTitle", c.JobTitle);
    00102         ar & make_nvp("PublicKey", c.PublicKey);
    00103         ar & make_nvp("URL", c.URL);
    00104         ar & make_nvp("Prefix", c.Prefix);
    00105         ar & make_nvp("Categories", c.Categories);
    00106         ar & make_nvp("HomeAddress1", c.HomeAddress.Address1);
    00107         ar & make_nvp("HomeAddress2", c.HomeAddress.Address2);
    00108         ar & make_nvp("HomeAddress3", c.HomeAddress.Address3);
    00109         ar & make_nvp("Notes", c.Notes);
    00110         ar & make_nvp("UserDefined1", c.UserDefined1);
    00111         ar & make_nvp("UserDefined2", c.UserDefined2);
    00112         ar & make_nvp("UserDefined3", c.UserDefined3);
    00113         ar & make_nvp("UserDefined4", c.UserDefined4);
    00114         ar & make_nvp("HomeCity", c.HomeAddress.City);
    00115         ar & make_nvp("HomeProvince", c.HomeAddress.Province);
    00116         ar & make_nvp("HomePostalCode", c.HomeAddress.PostalCode);
    00117         ar & make_nvp("HomeCountry", c.HomeAddress.Country);
    00118         ar & make_nvp("Image", c.Image);
    00119         ar & make_nvp("Nickname", c.Nickname);
    00120
    00121         if( ver < BARRY_POD_MAP_VERSION ) {
    00122                 ar & make_nvp("GroupLinks", c.GroupLinks);
    00123                 ar & make_nvp("Unknowns", c.Unknowns);
    00124         }
    00125 }
    00126
    00127 template <class ArchiveT>
    00128 void serialize(ArchiveT &ar, Barry::EmailAddress &a, const unsigned int ver)
    00129 {
    00130         ar & make_nvp("Name", a.Name);
    00131         ar & make_nvp("Email", a.Email);
    00132 }
    00133
    00134 template <class ArchiveT>
    00135 void serialize(ArchiveT &ar, Barry::Message &m, const unsigned int ver)
    00136 {
    00137         ar & make_nvp("From", m.From);
    00138         ar & make_nvp("To", m.To);
    00139         ar & make_nvp("Cc", m.Cc);
    00140         ar & make_nvp("Sender", m.Sender);
    00141         ar & make_nvp("ReplyTo", m.ReplyTo);
    00142         ar & make_nvp("Subject", m.Subject);
    00143         ar & make_nvp("Body", m.Body);
    00144         ar & make_nvp("Attachment", m.Attachment);
    00145         ar & make_nvp("MessageRecordId", m.MessageRecordId);
    00146         ar & make_nvp("MessageReplyTo", m.MessageReplyTo);
    00147         ar & make_nvp("MessageDateSent", m.MessageDateSent);
    00148         ar & make_nvp("MessageDateReceived", m.MessageDateReceived);
    00149
    00150         ar & make_nvp("MessageTruncated", m.MessageTruncated);
    00151         ar & make_nvp("MessageRead", m.MessageRead);
    00152         ar & make_nvp("MessageReply", m.MessageReply);
    00153         ar & make_nvp("MessageSaved", m.MessageSaved);
    00154         ar & make_nvp("MessageSavedDeleted", m.MessageSavedDeleted);
    00155
    00156         ar & make_nvp("MessagePriority", m.Priority);
    00157         ar & make_nvp("MessageSensitivity", m.Sensitivity);
    00158
    00159         if( ver < BARRY_POD_MAP_VERSION ) {
    00160                 ar & make_nvp("Unknowns", m.Unknowns);
    00161         }
    00162 }
    00163
    00164 template <class ArchiveT>
    00165 void serialize(ArchiveT &ar, Barry::Calendar &c, const unsigned int ver)
    00166 {
    00167         ar & make_nvp("RecType", c.RecType);
    00168         ar & make_nvp("RecordId", c.RecordId);
    00169
    00170         ar & make_nvp("AllDayEvent", c.AllDayEvent);
    00171
    00172         ar & make_nvp("Subject", c.Subject);
    00173         ar & make_nvp("Notes", c.Notes);
    00174         ar & make_nvp("Location", c.Location);
    00175
    00176         ar & make_nvp("NotificationTime", c.NotificationTime);
    00177         ar & make_nvp("StartTime", c.StartTime);
    00178         ar & make_nvp("EndTime", c.EndTime);
    00179
    00180         ar & make_nvp("Organizer", c.Organizer);
    00181         ar & make_nvp("AcceptedBy", c.AcceptedBy);
    00182         ar & make_nvp("Invited", c.Invited);
    00183
    00184         ar & make_nvp("FreeBusyFlag", c.FreeBusyFlag);
    00185         ar & make_nvp("ClassFlag", c.ClassFlag);
    00186
    00187         ar & make_nvp("Recurring", c.Recurring);
    00188         ar & make_nvp("RecurringType", c.RecurringType);
    00189         ar & make_nvp("Interval", c.Interval);
    00190         ar & make_nvp("RecurringEndTime", c.RecurringEndTime);
    00191         ar & make_nvp("Perpetual", c.Perpetual);
    00192         ar & make_nvp("CalendarID", c.CalendarID);
    00193         ar & make_nvp("TimeZoneCode", c.TimeZoneCode);
    00194         ar & make_nvp("TimeZoneValid", c.TimeZoneValid);
    00195
    00196         ar & make_nvp("DayOfWeek", c.DayOfWeek);
    00197         ar & make_nvp("WeekOfMonth", c.WeekOfMonth);
    00198         ar & make_nvp("DayOfMonth", c.DayOfMonth);
    00199         ar & make_nvp("MonthOfYear", c.MonthOfYear);
    00200         ar & make_nvp("WeekDays", c.WeekDays);
    00201
    00202         if( ver < BARRY_POD_MAP_VERSION ) {
    00203                 ar & make_nvp("Unknowns", c.Unknowns);
    00204         }
    00205 }
    00206
    00207 template <class ArchiveT>
    00208 void serialize(ArchiveT &ar, Barry::CalendarAll &c, const unsigned int ver)
    00209 {
    00210         serialize(ar, static_cast<Barry::Calendar&>(c), ver);
    00211
    00212         ar & make_nvp("MailAccount", c.MailAccount);
    00213 }
    00214
    00215 template <class ArchiveT>
    00216 void serialize(ArchiveT &ar, Barry::CallLog &c, const unsigned int ver)
    00217 {
    00218         ar & make_nvp("RecType", c.RecType);
    00219         ar & make_nvp("RecordId", c.RecordId);
    00220
    00221         ar & make_nvp("Duration", c.Duration);
    00222         ar & make_nvp("Timestamp", c.Timestamp);
    00223         ar & make_nvp("ContactName", c.ContactName);
    00224         ar & make_nvp("PhoneNumber", c.PhoneNumber);
    00225
    00226         ar & make_nvp("DirectionFlag", c.DirectionFlag);
    00227         ar & make_nvp("StatusFlag", c.StatusFlag);
    00228         ar & make_nvp("PhoneTypeFlag", c.PhoneTypeFlag);
    00229         ar & make_nvp("PhoneInfoFlag", c.PhoneInfoFlag);
    00230
    00231         if( ver < BARRY_POD_MAP_VERSION ) {
    00232                 ar & make_nvp("Unknowns", c.Unknowns);
    00233         }
    00234 }
    00235
    00236 template <class ArchiveT>
    00237 void serialize(ArchiveT &ar, Barry::Bookmark &c, const unsigned int ver)
    00238 {
    00239         ar & make_nvp("RecType", c.RecType);
    00240         ar & make_nvp("RecordId", c.RecordId);
    00241         ar & make_nvp("Index", c.Index);
    00242
    00243         ar & make_nvp("Name", c.Name);
    00244         ar & make_nvp("Icon", c.Icon);
    00245         ar & make_nvp("Url", c.Url);
    00246
    00247         ar & make_nvp("BrowserIdentity", c.BrowserIdentity);
    00248         ar & make_nvp("DisplayMode", c.DisplayMode);
    00249         ar & make_nvp("JavaScriptMode", c.JavaScriptMode);
    00250
    00251         if( ver < BARRY_POD_MAP_VERSION ) {
    00252                 ar & make_nvp("Unknowns", c.Unknowns);
    00253         }
    00254 }
    00255
    00256 template <class ArchiveT>
    00257 void serialize(ArchiveT &ar, Barry::ServiceBookConfig &c, const unsigned int ver)
    00258 {
    00259         ar & make_nvp("Format", c.Format);
    00260
    00261         if( ver < BARRY_POD_MAP_VERSION ) {
    00262                 ar & make_nvp("Unknowns", c.Unknowns);
    00263         }
    00264 }
    00265
    00266 template <class ArchiveT>
    00267 void serialize(ArchiveT &ar, Barry::ServiceBook &c, const unsigned int ver)
    00268 {
    00269         ar & make_nvp("RecType", c.RecType);
    00270         ar & make_nvp("RecordId", c.RecordId);
    00271
    00272         ar & make_nvp("Name", c.Name);
    00273         ar & make_nvp("HiddenName", c.HiddenName);
    00274         ar & make_nvp("Description", c.Description);
    00275         ar & make_nvp("DSID", c.DSID);
    00276         ar & make_nvp("BesDomain", c.BesDomain);
    00277         ar & make_nvp("UniqueId", c.UniqueId);
    00278         ar & make_nvp("ContentId", c.ContentId);
    00279         ar & make_nvp("Config", c.Config);
    00280
    00281         if( ver < BARRY_POD_MAP_VERSION ) {
    00282                 ar & make_nvp("Unknowns", c.Unknowns);
    00283         }
    00284 }
    00285
    00286 template <class ArchiveT>
    00287 void serialize(ArchiveT &ar, Barry::Memo &m, const unsigned int ver)
    00288 {
    00289         ar & make_nvp("RecType", m.RecType);
    00290         ar & make_nvp("RecordId", m.RecordId);
    00291
    00292         ar & make_nvp("Title", m.Title);
    00293         ar & make_nvp("Body", m.Body);
    00294         ar & make_nvp("Categories", m.Categories);
    00295
    00296         if( ver < BARRY_POD_MAP_VERSION ) {
    00297                 ar & make_nvp( "Unknowns", m.Unknowns);
    00298         }
    00299 }
    00300
    00301 template <class ArchiveT>
    00302 void serialize(ArchiveT &ar, Barry::Task &t, const unsigned int ver)
    00303 {
    00304         ar & make_nvp("RecType", t.RecType);
    00305         ar & make_nvp("RecordId", t.RecordId);
    00306
    00307         ar & make_nvp("Summary", t.Summary);
    00308         ar & make_nvp("Notes", t.Notes);
    00309         ar & make_nvp("Categories", t.Categories);
    00310         ar & make_nvp("UID", t.UID);
    00311
    00312         ar & make_nvp("StartTime", t.StartTime);
    00313         ar & make_nvp("DueTime", t.DueTime);
    00314         ar & make_nvp("AlarmTime", t.AlarmTime);
    00315
    00316         ar & make_nvp("TimeZoneCode", t.TimeZoneCode);
    00317         ar & make_nvp("TimeZoneValid", t.TimeZoneValid);
    00318
    00319         ar & make_nvp("AlarmType", t.AlarmType);
    00320         ar & make_nvp("Interval", t.Interval);
    00321         ar & make_nvp("RecurringType", t.RecurringType);
    00322         ar & make_nvp("RecurringEndTime", t.RecurringEndTime);
    00323         ar & make_nvp("DayOfWeek", t.DayOfWeek);
    00324         ar & make_nvp("WeekOfMonth", t.WeekOfMonth);
    00325         ar & make_nvp("DayOfMonth", t.DayOfMonth);
    00326         ar & make_nvp("MonthOfYear", t.MonthOfYear);
    00327         ar & make_nvp("WeekDays", t.WeekDays);
    00328
    00329         ar & make_nvp("PriorityFlag", t.PriorityFlag);
    00330         ar & make_nvp("StatusFlag", t.StatusFlag);
    00331         ar & make_nvp("Recurring", t.Recurring);
    00332         ar & make_nvp("Perpetual", t.Perpetual);
    00333         ar & make_nvp("DueDateFlag", t.DueDateFlag);
    00334
    00335         if( ver < BARRY_POD_MAP_VERSION ) {
    00336                 ar & make_nvp( "Unknowns", t.Unknowns);
    00337         }
    00338 }
    00339
    00340 template<class ArchiveT>
    00341 void serialize(ArchiveT &ar, Barry::PINMessage &p, const unsigned int ver)
    00342 {
    00343         ar & make_nvp("RecType", p.RecType);
    00344         ar & make_nvp("RecordId", p.RecordId);
    00345
    00346         ar & make_nvp("From", p.From);
    00347         ar & make_nvp("To", p.To);
    00348         ar & make_nvp("Cc", p.Cc);
    00349         ar & make_nvp("Bcc", p.Bcc);
    00350         ar & make_nvp("Subject", p.Subject);
    00351         ar & make_nvp("Body", p.Body);
    00352         ar & make_nvp("MessageRecordId", p.MessageRecordId);
    00353         ar & make_nvp("MessageReplyTo", p.MessageReplyTo);
    00354         ar & make_nvp("MessageDateSent", p.MessageDateSent);
    00355         ar & make_nvp("MessageDateReceived", p.MessageDateReceived);
    00356
    00357         ar & make_nvp("MessageTruncated", p.MessageTruncated);
    00358         ar & make_nvp("MessageRead", p.MessageRead);
    00359         ar & make_nvp("MessageReply", p.MessageReply);
    00360         ar & make_nvp("MessageSaved", p.MessageSaved);
    00361         ar & make_nvp("MessageSavedDeleted", p.MessageSavedDeleted);
    00362
    00363         ar & make_nvp("MessagePriority", p.Priority);
    00364         ar & make_nvp("MessageSensitivity", p.Sensitivity);
    00365
    00366         if(ver < BARRY_POD_MAP_VERSION) {
    00367                 ar & make_nvp("Unknowns", p.Unknowns);
    00368         }
    00369 }
    00370
    00371 template <class ArchiveT>
    00372 void serialize(ArchiveT &ar, Barry::SavedMessage &m, const unsigned int ver)
    00373 {
    00374         ar & make_nvp("RecType", m.RecType);
    00375         ar & make_nvp("RecordId", m.RecordId);
    00376
    00377         ar & make_nvp("From", m.From);
    00378         ar & make_nvp("To", m.To);
    00379         ar & make_nvp("Cc", m.Cc);
    00380         ar & make_nvp("Bcc", m.Bcc);
    00381         ar & make_nvp("Sender", m.Sender);
    00382         ar & make_nvp("ReplyTo", m.ReplyTo);
    00383         ar & make_nvp("Subject", m.Subject);
    00384         ar & make_nvp("Body", m.Body);
    00385         ar & make_nvp("Attachment", m.Attachment);
    00386         ar & make_nvp("MessageRecordId", m.MessageRecordId);
    00387         ar & make_nvp("MessageReplyTo", m.MessageReplyTo);
    00388         ar & make_nvp("MessageDateSent", m.MessageDateSent);
    00389         ar & make_nvp("MessageDateReceived", m.MessageDateReceived);
    00390
    00391         ar & make_nvp("MessageTruncated", m.MessageTruncated);
    00392         ar & make_nvp("MessageRead", m.MessageRead);
    00393         ar & make_nvp("MessageReply", m.MessageReply);
    00394         ar & make_nvp("MessageSaved", m.MessageSaved);
    00395         ar & make_nvp("MessageSavedDeleted", m.MessageSavedDeleted);
    00396
    00397         ar & make_nvp("MessagePriority", m.Priority);
    00398         ar & make_nvp("MessageSensitivity", m.Sensitivity);
    00399
    00400         if( ver < BARRY_POD_MAP_VERSION ) {
    00401                 ar & make_nvp("Unknowns", m.Unknowns);
    00402         }
    00403 }
    00404
    00405 template <class ArchiveT>
    00406 void serialize(ArchiveT &ar, Barry::Sms &m, const unsigned int ver)
    00407 {
    00408         ar & make_nvp("RecType", m.RecType);
    00409         ar & make_nvp("RecordId", m.RecordId);
    00410
    00411         ar & make_nvp("MessageStatus", m.MessageStatus);
    00412         ar & make_nvp("DeliveryStatus", m.DeliveryStatus);
    00413
    00414         ar & make_nvp("IsNew", m.IsNew);
    00415         ar & make_nvp("NewConversation", m.NewConversation);
    00416         ar & make_nvp("Saved", m.Saved);
    00417         ar & make_nvp("Deleted", m.Deleted);
    00418         ar & make_nvp("Opened", m.Opened);
    00419
    00420         ar & make_nvp("Timestamp", m.Timestamp);
    00421         ar & make_nvp("ServiceCenterTimestamp", m.ServiceCenterTimestamp);
    00422
    00423         ar & make_nvp("DataCodingScheme", m.DataCodingScheme);
    00424         ar & make_nvp("ErrorId", m.ErrorId);
    00425
    00426         ar & make_nvp("Addresses", m.Addresses);
    00427         ar & make_nvp("Body", m.Body);
    00428
    00429         if( ver < BARRY_POD_MAP_VERSION ) {
    00430                 ar & make_nvp("Unknowns", m.Unknowns);
    00431         }
    00432 }
    00433
    00434 template <class ArchiveT>
    00435 void serialize(ArchiveT &ar, Barry::Folder &f, const unsigned int ver)
    00436 {
    00437         ar & make_nvp("RecType", f.RecType);
    00438         ar & make_nvp("RecordId", f.RecordId);
    00439
    00440         ar & make_nvp("FolderName", f.Name);
    00441         ar & make_nvp("FolderNumber", f.Number);
    00442         ar & make_nvp("FolderLevel", f.Level);
    00443         ar & make_nvp("FolderType", f.Type);
    00444
    00445         if( ver < BARRY_POD_MAP_VERSION ) {
    00446                 ar & make_nvp( "Unknowns", f.Unknowns);
    00447         }
    00448 }
    00449
    00450 template <class ArchiveT>
    00451 void serialize(ArchiveT &ar, Barry::Timezone &t, const unsigned int ver)
    00452 {
    00453         ar & make_nvp("RecType", t.RecType);
    00454         ar & make_nvp("RecordId", t.RecordId);
    00455
    00456         ar & make_nvp("TZType", t.TZType);
    00457         ar & make_nvp("DSTOffset", t.DSTOffset);
    00458         ar & make_nvp("Index", t.Index);
    00459         ar & make_nvp("Offset", t.Offset);
    00460         ar & make_nvp("OffsetFraction", t.OffsetFraction);
    00461         ar & make_nvp("StartMonth", t.StartMonth);
    00462         ar & make_nvp("EndMonth", t.EndMonth);
    00463         ar & make_nvp("Left", t.Left);
    00464         ar & make_nvp("UseDST", t.UseDST);
    00465
    00466         ar & make_nvp("TimeZoneName", t.TimeZoneName);
    00467
    00468         if( ver < BARRY_POD_MAP_VERSION ) {
    00469                 ar & make_nvp("Unknowns", t.Unknowns);
    00470         }
    00471 }
    00472
    00473 template <class ArchiveT>
    00474 void serialize(ArchiveT &ar, Barry::ContentStore &c, const unsigned int ver)
    00475 {
    00476         ar & make_nvp("RecType", c.RecType);
    00477         ar & make_nvp("RecordId", c.RecordId);
    00478
    00479         ar & make_nvp("Filename", c.Filename);
    00480         ar & make_nvp("FolderFlag", c.FolderFlag);
    00481         ar & make_nvp("FileContent", c.FileContent);
    00482         ar & make_nvp("FileDescriptor", c.FileDescriptor);
    00483
    00484         // FileSize is not used for building, so no need to save it here
    00485
    00486         if( ver < BARRY_POD_MAP_VERSION ) {
    00487                 ar & make_nvp("Unknowns", c.Unknowns);
    00488         }
    00489 }
    00490
    00491 }} // namespace boost::serialization
    00492
    00493
    00494 //////////////////////////////////////////////////////////////////////////////
    00495 // Helper wrapper templates for loading and saving records to an iostream
    00496
    00497 namespace Barry {
    00498
    00499 // Can be used as a Storage class for RecordBuilder<>
    00500 template <class RecordT>
    00501 class BoostLoader
    00502 {
    00503 public:
    00504         typedef RecordT                         rec_type;
    00505         typedef std::vector<rec_type>           list_type;
    00506
    00507 private:
    00508         list_type m_records;
    00509         typename list_type::iterator rec_it;
    00510
    00511 public:
    00512         explicit BoostLoader(std::istream &is)
    00513         {
    00514                 boost::archive::text_iarchive ia(is);
    00515                 ia >> m_records;
    00516                 rec_it = m_records.begin();
    00517         }
    00518
    00519         list_type& GetRecords() { return m_records; }
    00520         const list_type& GetRecords() const { return m_records; }
    00521
    00522         // retrieval operator
    00523         bool operator()(RecordT &rec, Builder &builder)
    00524         {
    00525                 if( rec_it == m_records.end() )
    00526                         return false;
    00527                 rec = *rec_it;
    00528                 ++rec_it;
    00529                 return true;
    00530         }
    00531 };
    00532
    00533 // Can be used as a Storage class for RecordParser<>
    00534 template <class RecordT>
    00535 class BoostSaver
    00536 {
    00537 public:
    00538         typedef RecordT                         rec_type;
    00539         typedef std::vector<rec_type>           list_type;
    00540
    00541 private:
    00542         std::ostream &m_os;
    00543         list_type m_records;
    00544         typename list_type::iterator rec_it;
    00545
    00546 public:
    00547         explicit BoostSaver(std::ostream &os)
    00548                 : m_os(os)
    00549         {
    00550         }
    00551
    00552         ~BoostSaver()
    00553         {
    00554                 WriteArchive();
    00555         }
    00556
    00557         void WriteArchive() const
    00558         {
    00559                 // write dbname first, so parsing is possible
    00560                 m_os << RecordT::GetDBName() << std::endl;
    00561
    00562                 // write boost archive of all records
    00563                 boost::archive::text_oarchive oa(m_os);
    00564
    00565                 // boost is fussy that the vector must be const
    00566                 // we do this explicitly, for documentation's sake
    00567                 const list_type &recs = m_records;
    00568                 oa << recs;
    00569                 m_os << std::endl;
    00570         }
    00571
    00572         list_type& GetRecords() { return m_records; }
    00573         const list_type& GetRecords() const { return m_records; }
    00574
    00575         // storage operator
    00576         void operator()(const RecordT &rec)
    00577         {
    00578                 m_records.push_back(rec);
    00579         }
    00580 };
    00581
    00582 //
    00583 // BoostParser
    00584 //
    00585 /// This Parser turns incoming records (which can be of any record type
    00586 /// included in ALL_KNOWN_PARSER_TYPES) into a Boost Serialization stream
    00587 /// on the given iostream.
    00588 ///
    00589 /// This class is defined completely in the header, so that it is
    00590 /// optional for applications to link against the boost libraries.
    00591 ///
    00592 class BXEXPORT BoostParser : public Barry::Parser
    00593 {
    00594         std::auto_ptr<Barry::Parser> m_parser;
    00595         std::ofstream *m_ofs;
    00596         std::ostream &m_os;     // references either an external object,
    00597                                 // or *m_ifs... this is the reference to
    00598                                 // use in the entire class... the constructor
    00599                                 // sets it up
    00600
    00601         std::string m_current_db;
    00602
    00603 public:
    00604         explicit BoostParser(const std::string &filename)
    00605                 : m_ofs( new std::ofstream(filename.c_str()) )
    00606                 , m_os(*m_ofs)
    00607         {
    00608         }
    00609
    00610         explicit BoostParser(std::ostream &os)
    00611                 : m_ofs(0)
    00612                 , m_os(os)
    00613         {
    00614         }
    00615
    00616         ~BoostParser()
    00617         {
    00618                 // flush any remaining parser output
    00619                 // (note this still potentially uses m_ofs, so do this first)
    00620                 m_parser.reset();
    00621
    00622                 // cleanup the stream
    00623                 delete m_ofs;
    00624         }
    00625
    00626         void StartDB(const std::string &dbname)
    00627         {
    00628                 // done with current parser, flush it's output
    00629                 m_parser.reset();
    00630
    00631 #undef HANDLE_PARSER
    00632 #define HANDLE_PARSER(tname) \
    00633                 if( dbname == tname::GetDBName() ) { \
    00634                         m_parser.reset( \
    00635                                 new RecordParser<tname, BoostSaver<tname> >( \
    00636                                         new BoostSaver<tname>(m_os) ) ); \
    00637                         return; \
    00638                 }
    00639
    00640                 ALL_KNOWN_PARSER_TYPES
    00641
    00642                 // if we make it here, we don't have a record parser
    00643                 // for this dbname, so just dump it to stderr (not stdout,
    00644                 // since the user might be sending normal output there)
    00645                 m_parser.reset( new HexDumpParser(std::cerr) );
    00646         }
    00647
    00648         void ParseRecord(const DBData &data, const IConverter *ic)
    00649         {
    00650                 if( m_current_db != data.GetDBName() ) {
    00651                         StartDB(data.GetDBName());
    00652                         m_current_db = data.GetDBName();
    00653                 }
    00654
    00655                 m_parser->ParseRecord(data, ic);
    00656         }
    00657 };
    00658
    00659 //
    00660 // BoostBuilder
    00661 //
    00662 /// This Builder class reads a boost serialization stream, and converts
    00663 /// them into DBData records.  Can only produce records for record types
    00664 /// in ALL_KNOWN_BUILDER_TYPES.
    00665 ///
    00666 class BXEXPORT BoostBuilder : public Barry::Builder
    00667 {
    00668         std::auto_ptr<Builder> m_builder;
    00669         std::ifstream *m_ifs;
    00670
    00671         std::istream &m_is;     // references either an external object,
    00672                                 // or *m_ifs... this is the reference to
    00673                                 // use in the entire class... the constructor
    00674                                 // sets it up
    00675
    00676 public:
    00677         explicit BoostBuilder(const std::string &filename)
    00678                 : m_ifs( new std::ifstream(filename.c_str()) )
    00679                 , m_is(*m_ifs)
    00680         {
    00681                 FinishDB();
    00682         }
    00683
    00684         explicit BoostBuilder(std::istream &is)
    00685                 : m_ifs(0)
    00686                 , m_is(is)
    00687         {
    00688                 FinishDB();
    00689         }
    00690
    00691         ~BoostBuilder()
    00692         {
    00693                 delete m_ifs;
    00694         }
    00695
    00696         void FinishDB()
    00697         {
    00698                 // done with current builder
    00699                 m_builder.reset();
    00700
    00701                 // read the next DBName
    00702                 std::string dbName;
    00703                 while( getline(m_is, dbName) ) {
    00704
    00705 #undef HANDLE_BUILDER
    00706 #define HANDLE_BUILDER(tname) \
    00707                         if( dbName == tname::GetDBName() ) { \
    00708                                 m_builder.reset( \
    00709                                         new RecordBuilder<tname, BoostLoader<tname> >( \
    00710                                                 new BoostLoader<tname>(m_is) ) ); \
    00711                                 return; \
    00712                         }
    00713
    00714                         ALL_KNOWN_BUILDER_TYPES
    00715                 }
    00716         }
    00717
    00718         bool BuildRecord(DBData &data, size_t &offset, const IConverter *ic)
    00719         {
    00720                 if( !m_builder.get() )
    00721                         return false;
    00722
    00723                 bool ret = m_builder->BuildRecord(data, offset, ic);
    00724                 if( !ret )
    00725                         FinishDB();
    00726                 return ret;
    00727         }
    00728
    00729         bool FetchRecord(DBData &data, const IConverter *ic)
    00730         {
    00731                 if( !m_builder.get() )
    00732                         return false;
    00733
    00734                 bool ret = m_builder->FetchRecord(data, ic);
    00735                 if( !ret )
    00736                         FinishDB();
    00737                 return ret;
    00738         }
    00739
    00740         bool EndOfFile() const
    00741         {
    00742                 return m_builder.get() ? false : true;
    00743         }
    00744 };
    00745
    00746
    00747 } // namespace Barry
    00748
    00749 #endif
    00750