Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:21

0001 #ifndef POSIX_TIME_SERIALIZE_HPP___
0002 #define POSIX_TIME_SERIALIZE_HPP___
0003 
0004 /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
0005  * Use, modification and distribution is subject to the 
0006  * Boost Software License, Version 1.0. (See accompanying
0007  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
0008  * Author: Jeff Garland, Bart Garst
0009  * $Date$
0010  */
0011 
0012 #include "boost/date_time/posix_time/posix_time.hpp"
0013 #include "boost/date_time/gregorian/greg_serialize.hpp"
0014 #include "boost/core/nvp.hpp"
0015 #include "boost/numeric/conversion/cast.hpp"
0016 #include "boost/type_traits/integral_constant.hpp"
0017 
0018 // Define versions for serialization compatibility
0019 // alows the unit tests to make an older version to check compatibility
0020 #ifndef BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION
0021 #define BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION 1
0022 #endif
0023 
0024 namespace boost {
0025 namespace serialization {
0026 
0027 template<typename T>
0028 struct version;
0029 
0030 template<>
0031 struct version<boost::posix_time::time_duration>
0032   : integral_constant<int, BOOST_DATE_TIME_POSIX_TIME_DURATION_VERSION>
0033 {
0034 };
0035 
0036 // A macro to split serialize functions into save & load functions.
0037 // It is here to avoid dependency on Boost.Serialization just for the
0038 // BOOST_SERIALIZATION_SPLIT_FREE macro
0039 #define BOOST_DATE_TIME_SPLIT_FREE(T)                                         \
0040 template<class Archive>                                                       \
0041 inline void serialize(Archive & ar,                                           \
0042                       T & t,                                                  \
0043                       const unsigned int file_version)                        \
0044 {                                                                             \
0045   split_free(ar, t, file_version);                                            \
0046 }
0047 
0048 BOOST_DATE_TIME_SPLIT_FREE(boost::posix_time::ptime)
0049 BOOST_DATE_TIME_SPLIT_FREE(boost::posix_time::time_duration)
0050 BOOST_DATE_TIME_SPLIT_FREE(boost::posix_time::time_period)
0051 
0052 #undef BOOST_DATE_TIME_SPLIT_FREE
0053 
0054 /*** time_duration ***/
0055 
0056 //! Function to save posix_time::time_duration objects using serialization lib
0057 /*! time_duration objects are broken down into 4 parts for serialization:
0058  * types are hour_type, min_type, sec_type, and fractional_seconds_type
0059  * as defined in the time_duration class
0060  */
0061 template<class TimeResTraitsSize, class Archive>
0062 void save_td(Archive& ar, const posix_time::time_duration& td)
0063 {
0064     TimeResTraitsSize h = boost::numeric_cast<TimeResTraitsSize>(td.hours());
0065     TimeResTraitsSize m = boost::numeric_cast<TimeResTraitsSize>(td.minutes());
0066     TimeResTraitsSize s = boost::numeric_cast<TimeResTraitsSize>(td.seconds());
0067     posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
0068     ar & make_nvp("time_duration_hours", h);
0069     ar & make_nvp("time_duration_minutes", m);
0070     ar & make_nvp("time_duration_seconds", s);
0071     ar & make_nvp("time_duration_fractional_seconds", fs);
0072 }
0073 
0074 template<class Archive>
0075 void save(Archive & ar, 
0076           const posix_time::time_duration& td, 
0077           unsigned int version)
0078 {
0079   // serialize a bool so we know how to read this back in later
0080   bool is_special = td.is_special();
0081   ar & make_nvp("is_special", is_special);
0082   if(is_special) {
0083     std::string s = to_simple_string(td);
0084     ar & make_nvp("sv_time_duration", s);
0085   }
0086   else {
0087     // Write support for earlier versions allows for upgrade compatibility testing
0088     // See load comments for version information
0089     if (version == 0) {
0090         save_td<int32_t>(ar, td);
0091     } else {
0092         save_td<int64_t>(ar, td);
0093     }
0094   }
0095 }
0096 
0097 //! Function to load posix_time::time_duration objects using serialization lib
0098 /*! time_duration objects are broken down into 4 parts for serialization:
0099  * types are hour_type, min_type, sec_type, and fractional_seconds_type
0100  * as defined in the time_duration class
0101  */
0102 template<class TimeResTraitsSize, class Archive>
0103 void load_td(Archive& ar, posix_time::time_duration& td)
0104 {
0105     TimeResTraitsSize h(0);
0106     TimeResTraitsSize m(0);
0107     TimeResTraitsSize s(0);
0108     posix_time::time_duration::fractional_seconds_type fs(0);
0109     ar & make_nvp("time_duration_hours", h);
0110     ar & make_nvp("time_duration_minutes", m);
0111     ar & make_nvp("time_duration_seconds", s);
0112     ar & make_nvp("time_duration_fractional_seconds", fs);
0113     td = posix_time::time_duration(h, m, s, fs);
0114 }
0115 
0116 template<class Archive>
0117 void load(Archive & ar, 
0118           posix_time::time_duration & td, 
0119           unsigned int version)
0120 {
0121   bool is_special = false;
0122   ar & make_nvp("is_special", is_special);
0123   if(is_special) {
0124     std::string s;
0125     ar & make_nvp("sv_time_duration", s);
0126     posix_time::special_values sv = gregorian::special_value_from_string(s);
0127     td = posix_time::time_duration(sv);
0128   }
0129   else {
0130     // Version "0"   (Boost 1.65.1 or earlier, which used int32_t for day/hour/minute/second and
0131     //                therefore suffered from the year 2038 issue.)
0132     // Version "0.5" (Boost 1.66.0 changed to std::time_t but did not increase the version;
0133     //                it was missed in the original change, all code reviews, and there were no
0134     //                static assertions to protect the code; further std::time_t can be 32-bit
0135     //                or 64-bit so it reduced portability.  This makes 1.66.0 hard to handle...)
0136     // Version "1"   (Boost 1.67.0 or later uses int64_t and is properly versioned)
0137 
0138     // If the size of any of these items changes, a new version is needed.
0139     BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::hour_type) == sizeof(boost::int64_t));
0140     BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::min_type) == sizeof(boost::int64_t));
0141     BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::sec_type) == sizeof(boost::int64_t));
0142     BOOST_STATIC_ASSERT(sizeof(posix_time::time_duration::fractional_seconds_type) == sizeof(boost::int64_t));
0143 
0144     if (version == 0) {
0145         load_td<int32_t>(ar, td);
0146     } else {
0147         load_td<int64_t>(ar, td);
0148     }
0149   }
0150 }
0151 
0152 // no load_construct_data function provided as time_duration provides a
0153 // default constructor
0154 
0155 /*** ptime ***/
0156 
0157 //! Function to save posix_time::ptime objects using serialization lib
0158 /*! ptime objects are broken down into 2 parts for serialization:
0159  * a date object and a time_duration onject
0160  */
0161 template<class Archive>
0162 void save(Archive & ar, 
0163           const posix_time::ptime& pt, 
0164           unsigned int /*version*/)
0165 {
0166   // from_iso_string does not include fractional seconds
0167   // therefore date and time_duration are used
0168   posix_time::ptime::date_type d = pt.date();
0169   ar & make_nvp("ptime_date", d);
0170   if(!pt.is_special()) {
0171     posix_time::ptime::time_duration_type td = pt.time_of_day();
0172     ar & make_nvp("ptime_time_duration", td);
0173   }
0174 }
0175 
0176 //! Function to load posix_time::ptime objects using serialization lib
0177 /*! ptime objects are broken down into 2 parts for serialization:
0178  * a date object and a time_duration onject
0179  */
0180 template<class Archive>
0181 void load(Archive & ar, 
0182           posix_time::ptime & pt, 
0183           unsigned int /*version*/)
0184 {
0185   // from_iso_string does not include fractional seconds
0186   // therefore date and time_duration are used
0187   posix_time::ptime::date_type d(posix_time::not_a_date_time);
0188   posix_time::ptime::time_duration_type td;
0189   ar & make_nvp("ptime_date", d);
0190   if(!d.is_special()) {
0191     ar & make_nvp("ptime_time_duration", td);
0192     pt = boost::posix_time::ptime(d,td);
0193   }
0194   else {
0195     pt = boost::posix_time::ptime(d.as_special());
0196   }
0197     
0198 }
0199 
0200 //!override needed b/c no default constructor
0201 template<class Archive>
0202 inline void load_construct_data(Archive & /*ar*/, 
0203                                 posix_time::ptime* pt, 
0204                                 const unsigned int /*file_version*/)
0205 {
0206   // retrieve data from archive required to construct new 
0207   // invoke inplace constructor to initialize instance of date
0208   new(pt) boost::posix_time::ptime(boost::posix_time::not_a_date_time);
0209 }
0210 
0211 /*** time_period ***/
0212 
0213 //! Function to save posix_time::time_period objects using serialization lib
0214 /*! time_period objects are broken down into 2 parts for serialization:
0215  * a begining ptime object and an ending ptime object
0216  */
0217 template<class Archive>
0218 void save(Archive & ar, 
0219           const posix_time::time_period& tp, 
0220           unsigned int /*version*/)
0221 {
0222   posix_time::ptime beg(tp.begin().date(), tp.begin().time_of_day());
0223   posix_time::ptime end(tp.end().date(), tp.end().time_of_day());
0224   ar & make_nvp("time_period_begin", beg);
0225   ar & make_nvp("time_period_end", end);
0226 }
0227 
0228 //! Function to load posix_time::time_period objects using serialization lib
0229 /*! time_period objects are broken down into 2 parts for serialization:
0230  * a begining ptime object and an ending ptime object
0231  */
0232 template<class Archive>
0233 void load(Archive & ar, 
0234           boost::posix_time::time_period & tp, 
0235           unsigned int /*version*/)
0236 {
0237   posix_time::time_duration td(1,0,0);
0238   gregorian::date d(gregorian::not_a_date_time);
0239   posix_time::ptime beg(d,td);
0240   posix_time::ptime end(d,td);
0241   ar & make_nvp("time_period_begin", beg);
0242   ar & make_nvp("time_period_end", end);
0243   tp = boost::posix_time::time_period(beg, end);
0244 }
0245 
0246 //!override needed b/c no default constructor
0247 template<class Archive>
0248 inline void load_construct_data(Archive & /*ar*/, 
0249                                 boost::posix_time::time_period* tp, 
0250                                 const unsigned int /*file_version*/)
0251 {
0252   posix_time::time_duration td(1,0,0);
0253   gregorian::date d(gregorian::not_a_date_time);
0254   posix_time::ptime beg(d,td);
0255   posix_time::ptime end(d,td);
0256   new(tp) boost::posix_time::time_period(beg,end);
0257 }
0258 
0259 } // namespace serialization
0260 } // namespace boost
0261 
0262 #endif