Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:20

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   date_time_format_parser.hpp
0009  * \author Andrey Semashev
0010  * \date   16.09.2012
0011  *
0012  * The header contains a parser for date and time format strings.
0013  */
0014 
0015 #ifndef BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
0016 #define BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
0017 
0018 #include <string>
0019 #include <boost/range/as_literal.hpp>
0020 #include <boost/range/iterator_range_core.hpp>
0021 #include <boost/log/detail/config.hpp>
0022 #include <boost/log/detail/header.hpp>
0023 
0024 #ifdef BOOST_HAS_PRAGMA_ONCE
0025 #pragma once
0026 #endif
0027 
0028 namespace boost {
0029 
0030 BOOST_LOG_OPEN_NAMESPACE
0031 
0032 namespace aux {
0033 
0034 /*!
0035  * This is the interface the parser will use to notify the caller about various components of date in the format string.
0036  */
0037 template< typename CharT >
0038 struct date_format_parser_callback
0039 {
0040     //! Character type used by the parser
0041     typedef CharT char_type;
0042 
0043     //! Destructor
0044     virtual ~date_format_parser_callback() {}
0045 
0046     /*!
0047      * \brief The function is called when the parser discovers a string literal in the format string
0048      *
0049      * \param lit The string of characters not interpreted as a placeholder
0050      */
0051     virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
0052 
0053     /*!
0054      * \brief The method is called when an unknown placeholder is found in the format string
0055      *
0056      * \param ph The placeholder with the leading percent sign
0057      */
0058     virtual void on_placeholder(iterator_range< const char_type* > const& ph)
0059     {
0060         // By default interpret all unrecognized placeholders as literals
0061         on_literal(ph);
0062     }
0063 
0064     /*!
0065      * \brief The function is called when the short year placeholder is found in the format string
0066      */
0067     virtual void on_short_year()
0068     {
0069         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('y'), static_cast< char_type >('\0') };
0070         on_placeholder(boost::as_literal(placeholder));
0071     }
0072 
0073     /*!
0074      * \brief The function is called when the full year placeholder is found in the format string
0075      */
0076     virtual void on_full_year()
0077     {
0078         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('Y'), static_cast< char_type >('\0') };
0079         on_placeholder(boost::as_literal(placeholder));
0080     }
0081 
0082     /*!
0083      * \brief The function is called when the numeric month placeholder is found in the format string
0084      */
0085     virtual void on_numeric_month()
0086     {
0087         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('m'), static_cast< char_type >('\0') };
0088         on_placeholder(boost::as_literal(placeholder));
0089     }
0090 
0091     /*!
0092      * \brief The function is called when the short alphabetic month placeholder is found in the format string
0093      */
0094     virtual void on_short_month()
0095     {
0096         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('b'), static_cast< char_type >('\0') };
0097         on_placeholder(boost::as_literal(placeholder));
0098     }
0099 
0100     /*!
0101      * \brief The function is called when the full alphabetic month placeholder is found in the format string
0102      */
0103     virtual void on_full_month()
0104     {
0105         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('B'), static_cast< char_type >('\0') };
0106         on_placeholder(boost::as_literal(placeholder));
0107     }
0108 
0109     /*!
0110      * \brief The function is called when the numeric day of month placeholder is found in the format string
0111      *
0112      * \param leading_zero If \c true, the day should be formatted with leading zero, otherwise with leading space
0113      */
0114     virtual void on_month_day(bool leading_zero)
0115     {
0116         const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('d') : static_cast< char_type >('e')), static_cast< char_type >('\0') };
0117         on_placeholder(boost::as_literal(placeholder));
0118     }
0119 
0120     /*!
0121      * \brief The function is called when the numeric day of week placeholder is found in the format string
0122      */
0123     virtual void on_numeric_week_day()
0124     {
0125         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('w'), static_cast< char_type >('\0') };
0126         on_placeholder(boost::as_literal(placeholder));
0127     }
0128 
0129     /*!
0130      * \brief The function is called when the short alphabetic day of week placeholder is found in the format string
0131      */
0132     virtual void on_short_week_day()
0133     {
0134         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('a'), static_cast< char_type >('\0') };
0135         on_placeholder(boost::as_literal(placeholder));
0136     }
0137 
0138     /*!
0139      * \brief The function is called when the full alphabetic day of week placeholder is found in the format string
0140      */
0141     virtual void on_full_week_day()
0142     {
0143         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('A'), static_cast< char_type >('\0') };
0144         on_placeholder(boost::as_literal(placeholder));
0145     }
0146 
0147     /*!
0148      * \brief The function is called when the ISO-formatted date is found in the format string
0149      */
0150     virtual void on_iso_date()
0151     {
0152         on_full_year();
0153         on_numeric_month();
0154         on_month_day(true);
0155     }
0156 
0157     /*!
0158      * \brief The function is called when the extended ISO-formatted date is found in the format string
0159      */
0160     virtual void on_extended_iso_date()
0161     {
0162         const char_type delimiter[2] = { static_cast< char_type >('-'), static_cast< char_type >('\0') };
0163         on_full_year();
0164         on_literal(boost::as_literal(delimiter));
0165         on_numeric_month();
0166         on_literal(boost::as_literal(delimiter));
0167         on_month_day(true);
0168     }
0169 };
0170 
0171 /*!
0172  * This is the interface the parser will use to notify the caller about various components of date in the format string.
0173  */
0174 template< typename CharT >
0175 struct time_format_parser_callback
0176 {
0177     //! Character type used by the parser
0178     typedef CharT char_type;
0179 
0180     //! Destructor
0181     virtual ~time_format_parser_callback() {}
0182 
0183     /*!
0184      * \brief The function is called when the parser discovers a string literal in the format string
0185      *
0186      * \param lit The string of characters not interpreted as a placeholder
0187      */
0188     virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
0189 
0190     /*!
0191      * \brief The method is called when an unknown placeholder is found in the format string
0192      *
0193      * \param ph The placeholder with the leading percent sign
0194      */
0195     virtual void on_placeholder(iterator_range< const char_type* > const& ph)
0196     {
0197         // By default interpret all unrecognized placeholders as literals
0198         on_literal(ph);
0199     }
0200 
0201     /*!
0202      * \brief The function is called when the hours placeholder is found in the format string
0203      *
0204      * The placeholder is used for 24-hour clock and duration formatting.
0205      *
0206      * \param leading_zero If \c true, the one-digit number of hours should be formatted with leading zero, otherwise with leading space
0207      */
0208     virtual void on_hours(bool leading_zero)
0209     {
0210         const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('O') : static_cast< char_type >('k')), static_cast< char_type >('\0') };
0211         on_placeholder(boost::as_literal(placeholder));
0212     }
0213 
0214     /*!
0215      * \brief The function is called when the hours placeholder is found in the format string
0216      *
0217      * The placeholder is used for 12-hour clock formatting. It should not be used for duration formatting.
0218      *
0219      * \param leading_zero If \c true, the one-digit number of hours should be formatted with leading zero, otherwise with leading space
0220      */
0221     virtual void on_hours_12(bool leading_zero)
0222     {
0223         const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('I') : static_cast< char_type >('l')), static_cast< char_type >('\0') };
0224         on_placeholder(boost::as_literal(placeholder));
0225     }
0226 
0227     /*!
0228      * \brief The function is called when the minutes placeholder is found in the format string
0229      */
0230     virtual void on_minutes()
0231     {
0232         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('M'), static_cast< char_type >('\0') };
0233         on_placeholder(boost::as_literal(placeholder));
0234     }
0235 
0236     /*!
0237      * \brief The function is called when the seconds placeholder is found in the format string
0238      */
0239     virtual void on_seconds()
0240     {
0241         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('S'), static_cast< char_type >('\0') };
0242         on_placeholder(boost::as_literal(placeholder));
0243     }
0244 
0245     /*!
0246      * \brief The function is called when the fractional seconds placeholder is found in the format string
0247      */
0248     virtual void on_fractional_seconds()
0249     {
0250         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('f'), static_cast< char_type >('\0') };
0251         on_placeholder(boost::as_literal(placeholder));
0252     }
0253 
0254     /*!
0255      * \brief The function is called when the day period (AM/PM) placeholder is found in the format string
0256      *
0257      * The placeholder is used for 12-hour clock formatting. It should not be used for duration formatting.
0258      *
0259      * \param upper_case If \c true, the day period will be upper case, and lower case otherwise
0260      */
0261     virtual void on_am_pm(bool upper_case)
0262     {
0263         const char_type placeholder[3] = { static_cast< char_type >('%'), (upper_case ? static_cast< char_type >('p') : static_cast< char_type >('P')), static_cast< char_type >('\0') };
0264         on_placeholder(boost::as_literal(placeholder));
0265     }
0266 
0267     /*!
0268      * \brief The function is called when the time duration sign placeholder is found in the format string
0269      *
0270      * The placeholder is used for duration formatting. It should not be used for time point formatting.
0271      *
0272      * \param display_positive If \c true, the positive sign will be explicitly displayed, otherwise only negative sign will be displayed
0273      */
0274     virtual void on_duration_sign(bool display_positive)
0275     {
0276         const char_type placeholder[3] = { static_cast< char_type >('%'), (display_positive ? static_cast< char_type >('+') : static_cast< char_type >('-')), static_cast< char_type >('\0') };
0277         on_placeholder(boost::as_literal(placeholder));
0278     }
0279 
0280     /*!
0281      * \brief The function is called when the ISO time zone placeholder is found in the format string
0282      */
0283     virtual void on_iso_time_zone()
0284     {
0285         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('q'), static_cast< char_type >('\0') };
0286         on_placeholder(boost::as_literal(placeholder));
0287     }
0288 
0289     /*!
0290      * \brief The function is called when the extended ISO time zone placeholder is found in the format string
0291      */
0292     virtual void on_extended_iso_time_zone()
0293     {
0294         const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('Q'), static_cast< char_type >('\0') };
0295         on_placeholder(boost::as_literal(placeholder));
0296     }
0297 
0298     /*!
0299      * \brief The function is called when the ISO-formatted time is found in the format string
0300      */
0301     virtual void on_iso_time()
0302     {
0303         on_hours(true);
0304         on_minutes();
0305         on_seconds();
0306     }
0307 
0308     /*!
0309      * \brief The function is called when the extended ISO-formatted time is found in the format string
0310      */
0311     virtual void on_extended_iso_time()
0312     {
0313         const char_type delimiter[2] = { static_cast< char_type >(':'), static_cast< char_type >('\0') };
0314         on_hours(true);
0315         on_literal(boost::as_literal(delimiter));
0316         on_minutes();
0317         on_literal(boost::as_literal(delimiter));
0318         on_seconds();
0319     }
0320 
0321     /*!
0322      * \brief The function is called when the extended ISO-formatted time with fractional seconds is found in the format string
0323      */
0324     virtual void on_default_time()
0325     {
0326         on_extended_iso_time();
0327 
0328         const char_type delimiter[2] = { static_cast< char_type >('.'), static_cast< char_type >('\0') };
0329         on_literal(boost::as_literal(delimiter));
0330         on_fractional_seconds();
0331     }
0332 };
0333 
0334 /*!
0335  * This is the interface the parser will use to notify the caller about various components of date in the format string.
0336  */
0337 template< typename CharT >
0338 struct date_time_format_parser_callback :
0339     public date_format_parser_callback< CharT >,
0340     public time_format_parser_callback< CharT >
0341 {
0342     //! Character type used by the parser
0343     typedef CharT char_type;
0344 
0345     //! Destructor
0346     ~date_time_format_parser_callback() BOOST_OVERRIDE {}
0347 
0348     /*!
0349      * \brief The function is called when the parser discovers a string literal in the format string
0350      *
0351      * \param lit The string of characters not interpreted as a placeholder
0352      */
0353     void on_literal(iterator_range< const char_type* > const& lit) BOOST_OVERRIDE = 0;
0354 
0355     /*!
0356      * \brief The method is called when an unknown placeholder is found in the format string
0357      *
0358      * \param ph The placeholder with the leading percent sign
0359      */
0360     void on_placeholder(iterator_range< const char_type* > const& ph) BOOST_OVERRIDE
0361     {
0362         // By default interpret all unrecognized placeholders as literals
0363         on_literal(ph);
0364     }
0365 };
0366 
0367 /*!
0368  * \brief Parses the date format string and invokes the callback object
0369  *
0370  * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
0371  * \param begin Pointer to the first character of the sequence
0372  * \param end Pointer to the after-the-last character of the sequence
0373  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0374  */
0375 template< typename CharT >
0376 BOOST_LOG_API void parse_date_format(const CharT* begin, const CharT* end, date_format_parser_callback< CharT >& callback);
0377 
0378 /*!
0379  * \brief Parses the date format string and invokes the callback object
0380  *
0381  * \param str The format string to parse
0382  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0383  */
0384 template< typename CharT, typename TraitsT, typename AllocatorT >
0385 inline void parse_date_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, date_format_parser_callback< CharT >& callback)
0386 {
0387     const CharT* p = str.c_str();
0388     return parse_date_format(p, p + str.size(), callback);
0389 }
0390 
0391 /*!
0392  * \brief Parses the date format string and invokes the callback object
0393  *
0394  * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
0395  * \param str The format string to parse
0396  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0397  */
0398 template< typename CharT >
0399 inline void parse_date_format(const CharT* str, date_format_parser_callback< CharT >& callback)
0400 {
0401     return parse_date_format(str, str + std::char_traits< CharT >::length(str), callback);
0402 }
0403 
0404 /*!
0405  * \brief Parses the time format string and invokes the callback object
0406  *
0407  * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
0408  * \param begin Pointer to the first character of the sequence
0409  * \param end Pointer to the after-the-last character of the sequence
0410  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0411  */
0412 template< typename CharT >
0413 BOOST_LOG_API void parse_time_format(const CharT* begin, const CharT* end, time_format_parser_callback< CharT >& callback);
0414 
0415 /*!
0416  * \brief Parses the time format string and invokes the callback object
0417  *
0418  * \param str The format string to parse
0419  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0420  */
0421 template< typename CharT, typename TraitsT, typename AllocatorT >
0422 inline void parse_time_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, time_format_parser_callback< CharT >& callback)
0423 {
0424     const CharT* p = str.c_str();
0425     return parse_time_format(p, p + str.size(), callback);
0426 }
0427 
0428 /*!
0429  * \brief Parses the time format string and invokes the callback object
0430  *
0431  * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
0432  * \param str The format string to parse
0433  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0434  */
0435 template< typename CharT >
0436 inline void parse_time_format(const CharT* str, time_format_parser_callback< CharT >& callback)
0437 {
0438     return parse_time_format(str, str + std::char_traits< CharT >::length(str), callback);
0439 }
0440 
0441 /*!
0442  * \brief Parses the date and time format string and invokes the callback object
0443  *
0444  * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
0445  * \param begin Pointer to the first character of the sequence
0446  * \param end Pointer to the after-the-last character of the sequence
0447  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0448  */
0449 template< typename CharT >
0450 BOOST_LOG_API void parse_date_time_format(const CharT* begin, const CharT* end, date_time_format_parser_callback< CharT >& callback);
0451 
0452 /*!
0453  * \brief Parses the date and time format string and invokes the callback object
0454  *
0455  * \param str The format string to parse
0456  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0457  */
0458 template< typename CharT, typename TraitsT, typename AllocatorT >
0459 inline void parse_date_time_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, date_time_format_parser_callback< CharT >& callback)
0460 {
0461     const CharT* p = str.c_str();
0462     return parse_date_time_format(p, p + str.size(), callback);
0463 }
0464 
0465 /*!
0466  * \brief Parses the date and time format string and invokes the callback object
0467  *
0468  * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
0469  * \param str The format string to parse
0470  * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
0471  */
0472 template< typename CharT >
0473 inline void parse_date_time_format(const CharT* str, date_time_format_parser_callback< CharT >& callback)
0474 {
0475     return parse_date_time_format(str, str + std::char_traits< CharT >::length(str), callback);
0476 }
0477 
0478 } // namespace aux
0479 
0480 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0481 
0482 } // namespace boost
0483 
0484 #include <boost/log/detail/footer.hpp>
0485 
0486 #endif // BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_