sbuild  1.5.3
sbuild-types.h
00001 /* Copyright © 2005-2008  Roger Leigh <rleigh@debian.org>
00002  *
00003  * schroot is free software: you can redistribute it and/or modify it
00004  * under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  *
00008  * schroot is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see
00015  * <http://www.gnu.org/licenses/>.
00016  *
00017  *********************************************************************/
00018 
00019 #ifndef SBUILD_TYPES_H
00020 #define SBUILD_TYPES_H
00021 
00022 #include <cassert>
00023 #include <ctime>
00024 #include <ios>
00025 #include <locale>
00026 #include <map>
00027 #include <set>
00028 #include <string>
00029 #include <vector>
00030 
00034 namespace sbuild
00035 {
00036 
00038   typedef std::vector<std::string> string_list;
00039 
00041   typedef std::set<std::string> string_set;
00042 
00044   typedef std::map<std::string, std::string> string_map;
00045 
00049   class date_base
00050   {
00051   public:
00053     typedef std::tm *(*break_time_func)(const time_t *timep, std:: tm *result);
00054 
00061     date_base (time_t          unix_time,
00062                break_time_func break_time):
00063       unix_time(unix_time),
00064       break_time(break_time)
00065     {}
00066 
00068     virtual ~date_base ()
00069     {}
00070 
00078     template <class charT, class traits>
00079     friend
00080     std::basic_ostream<charT,traits>&
00081     operator << (std::basic_ostream<charT,traits>& stream,
00082                  date_base const&                  dt)
00083     {
00084       std::ios_base::iostate err = std::ios_base::goodbit;
00085 
00086       std::tm dtm;
00087       if ((dt.break_time(&dt.unix_time, &dtm)) == 0)
00088         {
00089           err = std::ios_base::badbit;
00090         }
00091       else
00092         {
00093           try
00094             {
00095               typename std::basic_ostream<charT, traits>::sentry sentry(stream);
00096               if (sentry)
00097                 {
00098                   const std::basic_string<char>
00099                     nfmt(dt.get_date_format());
00100                   std::basic_string<charT> wfmt(nfmt.size(), 0);
00101                   assert(nfmt.size() == wfmt.size());
00102                   const char *nptr = nfmt.c_str();
00103                   charT *wptr = const_cast<charT *>(wfmt.c_str());
00104 
00105                   std::use_facet<std::ctype<charT> >(stream.getloc())
00106                     .widen(nptr, nptr + nfmt.size(), wptr);
00107 
00108                   typedef std::time_put<charT,std::ostreambuf_iterator<charT,traits> >
00109                     time_type;
00110                   if (std::use_facet<time_type>(stream.getloc())
00111                       .put(stream, stream, stream.fill(),
00112                            &dtm,
00113                            wptr, wptr + wfmt.size())
00114                       .failed())
00115                     {
00116                       err = std::ios_base::badbit;
00117                     }
00118                   stream.width(0);
00119                 }
00120             }
00121           catch (...)
00122             {
00123               bool flag = false;
00124               try
00125                 {
00126                   stream.setstate(std::ios::failbit);
00127                 }
00128               catch (std::ios_base::failure const& discard)
00129                 {
00130                   flag = true;
00131                 }
00132               if (flag)
00133                 throw;
00134             }
00135         }
00136 
00137       if (err)
00138         stream.setstate(err);
00139 
00140       return stream;
00141     }
00142 
00143   private:
00150     virtual const char *
00151     get_date_format () const;
00152 
00154     time_t          unix_time;
00156     break_time_func break_time;
00157   };
00158 
00162   class gmdate : public date_base
00163   {
00164   public:
00170     gmdate (time_t          unix_time):
00171       date_base(unix_time, gmtime_r)
00172     {}
00173 
00175     virtual ~gmdate ()
00176     {}
00177   };
00178 
00182   class date : public date_base
00183   {
00184   public:
00190     date (time_t           unix_time):
00191       date_base(unix_time, localtime_r)
00192     {}
00193 
00195     virtual ~date ()
00196     {}
00197   };
00198 
00202   class isodate : public date_base
00203   {
00204   public:
00210     isodate (time_t        unix_time):
00211       date_base(unix_time, gmtime_r)
00212     {}
00213 
00215     virtual ~isodate ()
00216     {}
00217 
00218   private:
00219     virtual const char *
00220     get_date_format () const;
00221   };
00222 
00223 }
00224 
00225 #endif /* SBUILD_TYPES_H */
00226 
00227 /*
00228  * Local Variables:
00229  * mode:C++
00230  * End:
00231  */