| 28 | namespace datetime_parse_util { |
| 29 | |
| 30 | bool IsoSqlFormatParser::ParseDateTime(const char* input_str, int input_len, |
| 31 | const DateTimeFormatContext& dt_ctx, DateTimeParseResult* result) { |
| 32 | DCHECK(dt_ctx.toks.size() > 0); |
| 33 | DCHECK(dt_ctx.current_time != nullptr); |
| 34 | DCHECK(dt_ctx.current_time->HasDateAndTime()); |
| 35 | DCHECK(result != nullptr); |
| 36 | DCHECK(result->hour == 0); |
| 37 | if (input_str == nullptr || input_len <= 0) return false; |
| 38 | |
| 39 | int day_in_year = -1; |
| 40 | Iso8601WeekBasedDateParseResult iso8601_week_based_date_values; |
| 41 | |
| 42 | const char* current_pos = input_str; |
| 43 | const char* end_pos = input_str + input_len; |
| 44 | for (int i = 0; i < dt_ctx.toks.size(); ++i) { |
| 45 | const DateTimeFormatToken* tok = &dt_ctx.toks[i]; |
| 46 | if (current_pos >= end_pos) { |
| 47 | // Accept empty text tokens at the end of the format. |
| 48 | if (tok->type == TEXT && tok->len == 0) continue; |
| 49 | return false; |
| 50 | } |
| 51 | |
| 52 | if (tok->type == SEPARATOR) { |
| 53 | if (dt_ctx.fx_modifier) { |
| 54 | DCHECK(tok->len == 1); |
| 55 | if (*current_pos != *tok->val) return false; |
| 56 | ++current_pos; |
| 57 | continue; |
| 58 | } else { |
| 59 | bool res = ProcessSeparatorSequence(¤t_pos, end_pos, dt_ctx, &i); |
| 60 | if (!res || current_pos >= end_pos) return res; |
| 61 | DCHECK(i < dt_ctx.toks.size()); |
| 62 | // Next token, following the separator sequence. |
| 63 | tok = &dt_ctx.toks[i]; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | if (tok->type == TEXT) { |
| 68 | const char* format_it = tok->val; |
| 69 | const char* format_end = tok->val + tok->len; |
| 70 | while (format_it < format_end && current_pos < end_pos) { |
| 71 | char format_char_to_compare = GetNextCharFromTextToken(&format_it, tok); |
| 72 | if (format_char_to_compare != *current_pos) return false; |
| 73 | ++format_it; |
| 74 | ++current_pos; |
| 75 | } |
| 76 | if (format_it < format_end) return false; |
| 77 | continue; |
| 78 | } |
| 79 | |
| 80 | const char* token_end_pos = |
| 81 | FindEndOfToken(current_pos, end_pos - current_pos, *tok, dt_ctx.fx_modifier); |
| 82 | if (token_end_pos == nullptr) return false; |
| 83 | int token_len = token_end_pos - current_pos; |
| 84 | |
| 85 | if (dt_ctx.fx_modifier && !tok->fm_modifier && token_len != tok->len) return false; |
| 86 | |
| 87 | switch(tok->type) { |
nothing calls this directly
no test coverage detected