Line data Source code
1 :
2 : #ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
3 : #define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
4 :
5 : /* Copyright (c) 2005 CrystalClear Software, Inc.
6 : * Use, modification and distribution is subject to the
7 : * Boost Software License, Version 1.0. (See accompanying
8 : * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
9 : * Author: Jeff Garland, Bart Garst
10 : * $Date:
11 : */
12 :
13 :
14 : #include "boost/date_time/string_parse_tree.hpp"
15 : #include "boost/date_time/special_defs.hpp"
16 : #include <string>
17 : #include <vector>
18 :
19 : namespace boost { namespace date_time {
20 :
21 : //! Class for special_value parsing
22 : /*!
23 : * TODO: add doc-comments for which elements can be changed
24 : * Parses input stream for strings representing special_values.
25 : * Special values parsed are:
26 : * - not_a_date_time
27 : * - neg_infin
28 : * - pod_infin
29 : * - min_date_time
30 : * - max_date_time
31 : */
32 : template<class date_type, typename charT>
33 : class special_values_parser
34 : {
35 : public:
36 : typedef std::basic_string<charT> string_type;
37 : typedef std::basic_stringstream<charT> stringstream_type;
38 : typedef std::istreambuf_iterator<charT> stream_itr_type;
39 : typedef typename date_type::duration_type duration_type;
40 : typedef string_parse_tree<charT> parse_tree_type;
41 : typedef typename parse_tree_type::parse_match_result_type match_results;
42 : typedef std::vector<std::basic_string<charT> > collection_type;
43 :
44 : typedef charT char_type;
45 : static const char_type nadt_string[16];
46 : static const char_type neg_inf_string[10];
47 : static const char_type pos_inf_string[10];
48 : static const char_type min_date_time_string[18];
49 : static const char_type max_date_time_string[18];
50 :
51 : //! Creates a special_values_parser with the default set of "sv_strings"
52 28 : special_values_parser()
53 14 : {
54 28 : sv_strings(string_type(nadt_string),
55 14 : string_type(neg_inf_string),
56 14 : string_type(pos_inf_string),
57 14 : string_type(min_date_time_string),
58 14 : string_type(max_date_time_string));
59 28 : }
60 :
61 : //! Creates a special_values_parser using a user defined set of element strings
62 : special_values_parser(const string_type& nadt_str,
63 : const string_type& neg_inf_str,
64 : const string_type& pos_inf_str,
65 : const string_type& min_dt_str,
66 : const string_type& max_dt_str)
67 : {
68 : sv_strings(nadt_str, neg_inf_str, pos_inf_str, min_dt_str, max_dt_str);
69 : }
70 :
71 : special_values_parser(typename collection_type::iterator beg, typename collection_type::iterator end)
72 : {
73 : collection_type phrases;
74 : std::copy(beg, end, std::back_inserter(phrases));
75 : m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
76 : }
77 :
78 : //! Replace special value strings
79 14 : void sv_strings(const string_type& nadt_str,
80 : const string_type& neg_inf_str,
81 : const string_type& pos_inf_str,
82 : const string_type& min_dt_str,
83 : const string_type& max_dt_str)
84 : {
85 14 : collection_type phrases;
86 14 : phrases.push_back(nadt_str);
87 14 : phrases.push_back(neg_inf_str);
88 14 : phrases.push_back(pos_inf_str);
89 14 : phrases.push_back(min_dt_str);
90 14 : phrases.push_back(max_dt_str);
91 14 : m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
92 14 : }
93 :
94 : //! The parser is expensive to create, and not thread-safe so it cannot be static
95 : //! therefore given a string, determine if it is likely to be a special value.
96 : //! A negative response is a definite no, whereas a positive is only likely and
97 : //! match() should be called and return value checked.
98 : //! \param[in] str the string to check
99 : //! \returns false if it is definitely not a special value
100 : static bool should_call_match(const string_type& str)
101 : {
102 : if (!str.empty()) {
103 : switch (str[0]) {
104 : // See string definitions at the end of this class..
105 : case '+':
106 : case '-':
107 : case 'n':
108 : case 'm':
109 : return true;
110 :
111 : default:
112 : break;
113 : }
114 : }
115 :
116 : return false;
117 : }
118 :
119 : //! Given an input iterator, attempt to match it to a known special value
120 : //! \param[in] sitr the start iterator
121 : //! \param[in] str_end the end iterator
122 : //! \param[out] mr the match result:
123 : //! mr.current_match is set to the corresponding special_value or -1
124 : //! \returns whether something matched
125 6 : bool match(stream_itr_type& sitr,
126 : stream_itr_type& str_end,
127 : match_results& mr) const
128 : {
129 6 : unsigned int level = 0;
130 6 : m_sv_strings.match(sitr, str_end, mr, level);
131 6 : return (mr.current_match != match_results::PARSE_ERROR);
132 : }
133 :
134 : private:
135 : parse_tree_type m_sv_strings;
136 :
137 : };
138 :
139 : template<class date_type, class CharT>
140 : const typename special_values_parser<date_type, CharT>::char_type
141 : special_values_parser<date_type, CharT>::nadt_string[16] =
142 : {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'};
143 : template<class date_type, class CharT>
144 : const typename special_values_parser<date_type, CharT>::char_type
145 : special_values_parser<date_type, CharT>::neg_inf_string[10] =
146 : {'-','i','n','f','i','n','i','t','y'};
147 : template<class date_type, class CharT>
148 : const typename special_values_parser<date_type, CharT>::char_type
149 : special_values_parser<date_type, CharT>::pos_inf_string[10] =
150 : {'+','i','n','f','i','n','i','t','y'};
151 : template<class date_type, class CharT>
152 : const typename special_values_parser<date_type, CharT>::char_type
153 : special_values_parser<date_type, CharT>::min_date_time_string[18] =
154 : {'m','i','n','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
155 : template<class date_type, class CharT>
156 : const typename special_values_parser<date_type, CharT>::char_type
157 : special_values_parser<date_type, CharT>::max_date_time_string[18] =
158 : {'m','a','x','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
159 :
160 : } } //namespace
161 :
162 : #endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
163 :
|