00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00031 #include <config.h>
00032
00033 #include <boost/foreach.hpp>
00034 #include <drizzled/temporal_format.h>
00035 #include <drizzled/temporal.h>
00036
00037 #include <string.h>
00038 #include PCRE_HEADER
00039
00040 #include <string>
00041 #include <vector>
00042
00043 using namespace std;
00044
00045 namespace drizzled {
00046
00047 TemporalFormat::TemporalFormat(const char *pattern) :
00048 _pattern(pattern)
00049 , _error_offset(0)
00050 , _error(NULL)
00051 , _year_part_index(0)
00052 , _month_part_index(0)
00053 , _day_part_index(0)
00054 , _hour_part_index(0)
00055 , _minute_part_index(0)
00056 , _second_part_index(0)
00057 , _usecond_part_index(0)
00058 , _nsecond_part_index(0)
00059 {
00060
00061 _re= pcre_compile(pattern
00062 , 0
00063 , &_error
00064 , &_error_offset
00065 , NULL
00066 );
00067 }
00068
00069 TemporalFormat::~TemporalFormat()
00070 {
00071 pcre_free(_re);
00072 }
00073
00074 bool TemporalFormat::matches(const char *data, size_t data_len, Temporal *to)
00075 {
00076 if (! is_valid())
00077 return false;
00078
00079 int32_t match_vector[OUT_VECTOR_SIZE];
00081
00082 memset(match_vector, 0, sizeof(match_vector));
00083
00084
00085 int32_t result= pcre_exec(_re
00086 , NULL
00087 , data
00088 , data_len
00089 , 0
00090 , 0
00091 , match_vector
00092 , OUT_VECTOR_SIZE
00093 );
00094 if (result < 0)
00095 {
00096 switch (result)
00097 {
00098 case PCRE_ERROR_NOMATCH:
00099 return false;
00100 default:
00101 return false;
00102 }
00103 return false;
00104 }
00105
00106 int32_t expected_match_count= (_year_part_index > 1 ? 1 : 0)
00107 + (_month_part_index > 1 ? 1 : 0)
00108 + (_day_part_index > 1 ? 1 : 0)
00109 + (_hour_part_index > 1 ? 1 : 0)
00110 + (_minute_part_index > 1 ? 1 : 0)
00111 + (_second_part_index > 1 ? 1 : 0)
00112 + (_usecond_part_index > 1 ? 1 : 0)
00113 + (_nsecond_part_index > 1 ? 1 : 0)
00114 + 1;
00115 if (result != expected_match_count)
00116 return false;
00117
00118
00119 string copy_data(data, data_len);
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 if (_year_part_index > 1)
00130 {
00131 size_t year_start= match_vector[_year_part_index];
00132 size_t year_len= match_vector[_year_part_index + 1] - match_vector[_year_part_index];
00133 to->_years= atoi(copy_data.substr(year_start, year_len).c_str());
00134 if (year_len == 2)
00135 to->_years+= (to->_years >= DRIZZLE_YY_PART_YEAR ? 1900 : 2000);
00136 }
00137 if (_month_part_index > 1)
00138 {
00139 size_t month_start= match_vector[_month_part_index];
00140 size_t month_len= match_vector[_month_part_index + 1] - match_vector[_month_part_index];
00141 to->_months= atoi(copy_data.substr(month_start, month_len).c_str());
00142 }
00143 if (_day_part_index > 1)
00144 {
00145 size_t day_start= match_vector[_day_part_index];
00146 size_t day_len= match_vector[_day_part_index + 1] - match_vector[_day_part_index];
00147 to->_days= atoi(copy_data.substr(day_start, day_len).c_str());
00148 }
00149 if (_hour_part_index > 1)
00150 {
00151 size_t hour_start= match_vector[_hour_part_index];
00152 size_t hour_len= match_vector[_hour_part_index + 1] - match_vector[_hour_part_index];
00153 to->_hours= atoi(copy_data.substr(hour_start, hour_len).c_str());
00154 }
00155 if (_minute_part_index > 1)
00156 {
00157 size_t minute_start= match_vector[_minute_part_index];
00158 size_t minute_len= match_vector[_minute_part_index + 1] - match_vector[_minute_part_index];
00159 to->_minutes= atoi(copy_data.substr(minute_start, minute_len).c_str());
00160 }
00161 if (_second_part_index > 1)
00162 {
00163 size_t second_start= match_vector[_second_part_index];
00164 size_t second_len= match_vector[_second_part_index + 1] - match_vector[_second_part_index];
00165 to->_seconds= atoi(copy_data.substr(second_start, second_len).c_str());
00166 }
00167 if (_usecond_part_index > 1)
00168 {
00169 size_t usecond_start= match_vector[_usecond_part_index];
00170 size_t usecond_len= match_vector[_usecond_part_index + 1] - match_vector[_usecond_part_index];
00171
00172
00173
00174
00175
00176
00177 uint32_t multiplier= 1;
00178 int32_t x= usecond_len;
00179 while (x < 6)
00180 {
00181 multiplier*= 10;
00182 ++x;
00183 }
00184 to->_useconds= atoi(copy_data.substr(usecond_start, usecond_len).c_str()) * multiplier;
00185 }
00186 if (_nsecond_part_index > 1)
00187 {
00188 size_t nsecond_start= match_vector[_nsecond_part_index];
00189 size_t nsecond_len= match_vector[_nsecond_part_index + 1] - match_vector[_nsecond_part_index];
00190
00191
00192
00193
00194
00195
00196 uint32_t multiplier= 1;
00197 int32_t x= nsecond_len;
00198 while (x < 9)
00199 {
00200 multiplier*= 10;
00201 ++x;
00202 }
00203 to->_nseconds= atoi(copy_data.substr(nsecond_start, nsecond_len).c_str()) * multiplier;
00204 }
00205 return true;
00206 }
00207
00208
00209 #define COUNT_KNOWN_FORMATS 19
00210
00211 struct temporal_format_args
00212 {
00213 const char *pattern;
00214 int32_t year_part_index;
00215 int32_t month_part_index;
00216 int32_t day_part_index;
00217 int32_t hour_part_index;
00218 int32_t minute_part_index;
00219 int32_t second_part_index;
00220 int32_t usecond_part_index;
00221 int32_t nsecond_part_index;
00222 };
00223
00236 static struct temporal_format_args __format_args[COUNT_KNOWN_FORMATS]=
00237 {
00238 {"^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})\\.(\\d{1,6})$", 1, 2, 3, 4, 5, 6, 7, 0}
00239 , {"^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})$", 1, 2, 3, 4, 5, 6, 0, 0}
00240 , {"^(\\d{4})[-/.](\\d{1,2})[-/.](\\d{1,2})[T|\\s+](\\d{2}):(\\d{2}):(\\d{2})\\.(\\d{1,6})$", 1, 2, 3, 4, 5, 6, 7, 0}
00241 , {"^(\\d{4})[-/.](\\d{1,2})[-/.](\\d{1,2})[T|\\s+](\\d{2}):(\\d{2}):(\\d{2})$", 1, 2, 3, 4, 5, 6, 0, 0}
00242 , {"^(\\d{2})[-/.](\\d{1,2})[-/.](\\d{1,2})[\\s+](\\d{2}):(\\d{2}):(\\d{2})$", 1, 2, 3, 4, 5, 6, 0, 0}
00243 , {"^(\\d{2})[-/.](\\d{1,2})[-/.](\\d{1,2})[\\s+](\\d{2}):(\\d{2})$", 1, 2, 3, 4, 5, 0, 0, 0}
00244 , {"^(\\d{4})[-/.](\\d{1,2})[-/.](\\d{1,2})[\\s+](\\d{2}):(\\d{2})$", 1, 2, 3, 4, 5, 0, 0, 0}
00245 , {"^(\\d{4})[-/.](\\d{1,2})[-/.](\\d{1,2})$", 1, 2, 3, 0, 0, 0, 0, 0}
00246 , {"^(\\d{4})(\\d{2})(\\d{2})$", 1, 2, 3, 0, 0, 0, 0, 0}
00247 , {"^(\\d{2})[-/.]*(\\d{2})[-/.]*(\\d{4})$", 3, 1, 2, 0, 0, 0, 0, 0}
00248 , {"^(\\d{2})[-/.]*(\\d{2})[-/.]*(\\d{2})$", 1, 2, 3, 0, 0, 0, 0, 0}
00249 , {"^(\\d{2})[-/.]*(\\d{1,2})[-/.]*(\\d{1,2})$", 1, 2, 3, 0, 0, 0, 0, 0}
00250 , {"^(\\d{4})[-/.]*(\\d{1,2})[-/.]*(\\d{1,2})$", 1, 2, 3, 0, 0, 0, 0, 0}
00251 , {"^(\\d{2}):*(\\d{2}):*(\\d{2})\\.(\\d{1,6})$", 0, 0, 0, 1, 2, 3, 4, 0}
00252 , {"^(\\d{1,2}):*(\\d{2}):*(\\d{2})$", 0, 0, 0, 1, 2, 3, 0, 0}
00253 , {"^(\\d{1,2}):(\\d{1,2}):(\\d{1,2})$", 0, 0, 0, 1, 2, 3, 0, 0}
00254 , {"^(\\d{1,2}):*(\\d{2})$", 0, 0, 0, 0, 1, 2, 0, 0}
00255 , {"^(\\d{1,2})$", 0, 0, 0, 0, 0, 1, 0, 0}
00256 , {"^(\\d{1,2})\\.(\\d{1,6})$", 0, 0, 0, 0, 0, 1, 2, 0}
00257 };
00258
00259 vector<TemporalFormat *> known_datetime_formats;
00260 vector<TemporalFormat *> known_date_formats;
00261 vector<TemporalFormat *> known_time_formats;
00262 vector<TemporalFormat *> all_temporal_formats;
00263
00269 bool init_temporal_formats()
00270 {
00271
00272 TemporalFormat *tmp;
00273 struct temporal_format_args current_format_args;
00274
00275 for (int32_t x= 0; x < COUNT_KNOWN_FORMATS; ++x)
00276 {
00277 current_format_args= __format_args[x];
00278 tmp= new TemporalFormat(current_format_args.pattern);
00279 tmp->set_year_part_index(current_format_args.year_part_index);
00280 tmp->set_month_part_index(current_format_args.month_part_index);
00281 tmp->set_day_part_index(current_format_args.day_part_index);
00282 tmp->set_hour_part_index(current_format_args.hour_part_index);
00283 tmp->set_minute_part_index(current_format_args.minute_part_index);
00284 tmp->set_second_part_index(current_format_args.second_part_index);
00285 tmp->set_usecond_part_index(current_format_args.usecond_part_index);
00286 tmp->set_nsecond_part_index(current_format_args.nsecond_part_index);
00287
00288
00289
00290
00291
00292 all_temporal_formats.push_back(tmp);
00293
00294 if (current_format_args.year_part_index > 0)
00295 {
00296 known_datetime_formats.push_back(tmp);
00297 if (current_format_args.second_part_index == 0)
00298 known_date_formats.push_back(tmp);
00299 }
00300
00301 if (current_format_args.second_part_index > 0)
00302 known_time_formats.push_back(tmp);
00303 }
00304 return true;
00305 }
00306
00308 void deinit_temporal_formats()
00309 {
00310 BOOST_FOREACH(TemporalFormat* it, all_temporal_formats)
00311 delete it;
00312 known_date_formats.clear();
00313 known_datetime_formats.clear();
00314 known_time_formats.clear();
00315 all_temporal_formats.clear();
00316 }
00317
00318 }