1 #ifndef DATE_TIME_POSIX_TIME_IO_HPP__ 2 #define DATE_TIME_POSIX_TIME_IO_HPP__ 3 4 /* Copyright (c) 2004-2005 CrystalClear Software, Inc. 5 * Use, modification and distribution is subject to the 6 * Boost Software License, Version 1.0. (See accompanying 7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 8 * Author: Jeff Garland, Bart Garst 9 * $Date$ 10 */ 11 12 #include <locale> 13 #include <iostream> 14 #include <iterator> // i/ostreambuf_iterator 15 #include <boost/io/ios_state.hpp> 16 #include <boost/date_time/time_facet.hpp> 17 #include <boost/date_time/period_formatter.hpp> 18 #include <boost/date_time/posix_time/ptime.hpp> 19 #include <boost/date_time/posix_time/time_period.hpp> 20 #include <boost/date_time/posix_time/posix_time_duration.hpp> 21 #include <boost/date_time/posix_time/conversion.hpp> // to_tm will be needed in the facets 22 23 namespace boost { 24 namespace posix_time { 25 26 27 //! wptime_facet is depricated and will be phased out. use wtime_facet instead 28 //typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet; 29 //! ptime_facet is depricated and will be phased out. use time_facet instead 30 //typedef boost::date_time::time_facet<ptime, char> ptime_facet; 31 32 //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead 33 //typedef boost::date_time::time_input_facet<ptime,wchar_t> wptime_input_facet; 34 //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead 35 //typedef boost::date_time::time_input_facet<ptime,char> ptime_input_facet; 36 37 typedef boost::date_time::time_facet<ptime, wchar_t> wtime_facet; 38 typedef boost::date_time::time_facet<ptime, char> time_facet; 39 40 typedef boost::date_time::time_input_facet<ptime, wchar_t> wtime_input_facet; 41 typedef boost::date_time::time_input_facet<ptime, char> time_input_facet; 42 43 template <class CharT, class TraitsT> 44 inline 45 std::basic_ostream<CharT, TraitsT>& operator <<(std::basic_ostream<CharT,TraitsT> & os,const ptime & p)46 operator<<(std::basic_ostream<CharT, TraitsT>& os, 47 const ptime& p) { 48 boost::io::ios_flags_saver iflags(os); 49 typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet; 50 std::ostreambuf_iterator<CharT> oitr(os); 51 if (std::has_facet<custom_ptime_facet>(os.getloc())) 52 std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p); 53 else { 54 //instantiate a custom facet for dealing with times since the user 55 //has not put one in the stream so far. This is for efficiency 56 //since we would always need to reconstruct for every time period 57 //if the locale did not already exist. Of course this will be overridden 58 //if the user imbues as some later point. 59 custom_ptime_facet* f = new custom_ptime_facet(); 60 std::locale l = std::locale(os.getloc(), f); 61 os.imbue(l); 62 f->put(oitr, os, os.fill(), p); 63 } 64 return os; 65 } 66 67 //! input operator for ptime 68 template <class CharT, class Traits> 69 inline 70 std::basic_istream<CharT, Traits>& operator >>(std::basic_istream<CharT,Traits> & is,ptime & pt)71 operator>>(std::basic_istream<CharT, Traits>& is, ptime& pt) 72 { 73 boost::io::ios_flags_saver iflags(is); 74 typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 75 if (strm_sentry) { 76 try { 77 typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local; 78 std::istreambuf_iterator<CharT,Traits> sit(is), str_end; 79 if(std::has_facet<time_input_facet_local>(is.getloc())) { 80 std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, pt); 81 } 82 else { 83 time_input_facet_local* f = new time_input_facet_local(); 84 std::locale l = std::locale(is.getloc(), f); 85 is.imbue(l); 86 f->get(sit, str_end, is, pt); 87 } 88 } 89 catch(...) { 90 // mask tells us what exceptions are turned on 91 std::ios_base::iostate exception_mask = is.exceptions(); 92 // if the user wants exceptions on failbit, we'll rethrow our 93 // date_time exception & set the failbit 94 if(std::ios_base::failbit & exception_mask) { 95 try { is.setstate(std::ios_base::failbit); } 96 catch(std::ios_base::failure&) {} // ignore this one 97 throw; // rethrow original exception 98 } 99 else { 100 // if the user want's to fail quietly, we simply set the failbit 101 is.setstate(std::ios_base::failbit); 102 } 103 } 104 } 105 return is; 106 } 107 108 109 template <class CharT, class TraitsT> 110 inline 111 std::basic_ostream<CharT, TraitsT>& operator <<(std::basic_ostream<CharT,TraitsT> & os,const boost::posix_time::time_period & p)112 operator<<(std::basic_ostream<CharT, TraitsT>& os, 113 const boost::posix_time::time_period& p) { 114 boost::io::ios_flags_saver iflags(os); 115 typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet; 116 std::ostreambuf_iterator<CharT> oitr(os); 117 if (std::has_facet<custom_ptime_facet>(os.getloc())) { 118 std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p); 119 } 120 else { 121 //instantiate a custom facet for dealing with periods since the user 122 //has not put one in the stream so far. This is for efficiency 123 //since we would always need to reconstruct for every time period 124 //if the local did not already exist. Of course this will be overridden 125 //if the user imbues as some later point. 126 custom_ptime_facet* f = new custom_ptime_facet(); 127 std::locale l = std::locale(os.getloc(), f); 128 os.imbue(l); 129 f->put(oitr, os, os.fill(), p); 130 } 131 return os; 132 } 133 134 //! input operator for time_period 135 template <class CharT, class Traits> 136 inline 137 std::basic_istream<CharT, Traits>& operator >>(std::basic_istream<CharT,Traits> & is,time_period & tp)138 operator>>(std::basic_istream<CharT, Traits>& is, time_period& tp) 139 { 140 boost::io::ios_flags_saver iflags(is); 141 typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 142 if (strm_sentry) { 143 try { 144 typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local; 145 std::istreambuf_iterator<CharT,Traits> sit(is), str_end; 146 if(std::has_facet<time_input_facet_local>(is.getloc())) { 147 std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, tp); 148 } 149 else { 150 time_input_facet_local* f = new time_input_facet_local(); 151 std::locale l = std::locale(is.getloc(), f); 152 is.imbue(l); 153 f->get(sit, str_end, is, tp); 154 } 155 } 156 catch(...) { 157 std::ios_base::iostate exception_mask = is.exceptions(); 158 if(std::ios_base::failbit & exception_mask) { 159 try { is.setstate(std::ios_base::failbit); } 160 catch(std::ios_base::failure&) {} 161 throw; // rethrow original exception 162 } 163 else { 164 is.setstate(std::ios_base::failbit); 165 } 166 } 167 } 168 return is; 169 } 170 171 172 //! ostream operator for posix_time::time_duration 173 // todo fix to use facet -- place holder for now... 174 template <class CharT, class Traits> 175 inline 176 std::basic_ostream<CharT, Traits>& operator <<(std::basic_ostream<CharT,Traits> & os,const time_duration & td)177 operator<<(std::basic_ostream<CharT, Traits>& os, const time_duration& td) 178 { 179 boost::io::ios_flags_saver iflags(os); 180 typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet; 181 std::ostreambuf_iterator<CharT> oitr(os); 182 if (std::has_facet<custom_ptime_facet>(os.getloc())) 183 std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td); 184 else { 185 //instantiate a custom facet for dealing with times since the user 186 //has not put one in the stream so far. This is for efficiency 187 //since we would always need to reconstruct for every time period 188 //if the locale did not already exist. Of course this will be overridden 189 //if the user imbues as some later point. 190 custom_ptime_facet* f = new custom_ptime_facet(); 191 std::locale l = std::locale(os.getloc(), f); 192 os.imbue(l); 193 f->put(oitr, os, os.fill(), td); 194 } 195 return os; 196 } 197 198 //! input operator for time_duration 199 template <class CharT, class Traits> 200 inline 201 std::basic_istream<CharT, Traits>& operator >>(std::basic_istream<CharT,Traits> & is,time_duration & td)202 operator>>(std::basic_istream<CharT, Traits>& is, time_duration& td) 203 { 204 boost::io::ios_flags_saver iflags(is); 205 typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 206 if (strm_sentry) { 207 try { 208 typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local; 209 std::istreambuf_iterator<CharT,Traits> sit(is), str_end; 210 if(std::has_facet<time_input_facet_local>(is.getloc())) { 211 std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, td); 212 } 213 else { 214 time_input_facet_local* f = new time_input_facet_local(); 215 std::locale l = std::locale(is.getloc(), f); 216 is.imbue(l); 217 f->get(sit, str_end, is, td); 218 } 219 } 220 catch(...) { 221 std::ios_base::iostate exception_mask = is.exceptions(); 222 if(std::ios_base::failbit & exception_mask) { 223 try { is.setstate(std::ios_base::failbit); } 224 catch(std::ios_base::failure&) {} 225 throw; // rethrow original exception 226 } 227 else { 228 is.setstate(std::ios_base::failbit); 229 } 230 } 231 } 232 return is; 233 } 234 235 } } // namespaces 236 #endif // DATE_TIME_POSIX_TIME_IO_HPP__ 237