static int s_parse_iso_8601_basic()

in source/date_time.c [210:313]


static int s_parse_iso_8601_basic(const struct aws_byte_cursor *date_str_cursor, struct tm *parsed_time) {
    size_t index = 0;
    size_t state_start_index = 0;
    enum parser_state state = ON_YEAR;
    bool error = false;

    AWS_ZERO_STRUCT(*parsed_time);

    while (state < FINISHED && !error && index < date_str_cursor->len) {
        char c = date_str_cursor->ptr[index];
        size_t sub_index = index - state_start_index;
        switch (state) {
            case ON_YEAR:
                if (aws_isdigit(c)) {
                    parsed_time->tm_year = parsed_time->tm_year * 10 + (c - '0');
                    if (sub_index == 3) {
                        state = ON_MONTH;
                        state_start_index = index + 1;
                        parsed_time->tm_year -= 1900;
                    }
                } else {
                    error = true;
                }
                break;

            case ON_MONTH:
                if (aws_isdigit(c)) {
                    parsed_time->tm_mon = parsed_time->tm_mon * 10 + (c - '0');
                    if (sub_index == 1) {
                        state = ON_MONTH_DAY;
                        state_start_index = index + 1;
                        parsed_time->tm_mon -= 1;
                    }
                } else {
                    error = true;
                }
                break;

            case ON_MONTH_DAY:
                if (c == 'T' && sub_index == 2) {
                    state = ON_HOUR;
                    state_start_index = index + 1;
                } else if (aws_isdigit(c)) {
                    parsed_time->tm_mday = parsed_time->tm_mday * 10 + (c - '0');
                } else {
                    error = true;
                }
                break;

            case ON_HOUR:
                if (aws_isdigit(c)) {
                    parsed_time->tm_hour = parsed_time->tm_hour * 10 + (c - '0');
                    if (sub_index == 1) {
                        state = ON_MINUTE;
                        state_start_index = index + 1;
                    }
                } else {
                    error = true;
                }
                break;

            case ON_MINUTE:
                if (aws_isdigit(c)) {
                    parsed_time->tm_min = parsed_time->tm_min * 10 + (c - '0');
                    if (sub_index == 1) {
                        state = ON_SECOND;
                        state_start_index = index + 1;
                    }
                } else {
                    error = true;
                }
                break;

            case ON_SECOND:
                if (aws_isdigit(c)) {
                    parsed_time->tm_sec = parsed_time->tm_sec * 10 + (c - '0');
                    if (sub_index == 1) {
                        state = ON_TZ;
                        state_start_index = index + 1;
                    }
                } else {
                    error = true;
                }
                break;

            case ON_TZ:
                if (c == 'Z' && (sub_index == 0 || sub_index == 3)) {
                    state = FINISHED;
                } else if (!aws_isdigit(c) || sub_index > 3) {
                    error = true;
                }
                break;

            default:
                error = true;
                break;
        }

        index++;
    }

    /* ISO8601 supports date only with no time portion. state ==ON_MONTH_DAY catches this case. */
    return (state == FINISHED || state == ON_MONTH_DAY) && !error ? AWS_OP_SUCCESS : AWS_OP_ERR;
}