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