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