JsonParser::Token JsonParser::tryNumber()

in lang/c++/impl/json/JsonIO.cc [145:272]


JsonParser::Token JsonParser::tryNumber(char ch) {
    sv.clear();
    sv.push_back(ch);

    hasNext = false;
    int state = (ch == '-') ? 0 : (ch == '0') ? 1
                                              : 2;
    for (;;) {
        switch (state) {
            case 0:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (isdigit(ch)) {
                        state = (ch == '0') ? 1 : 2;
                        sv.push_back(ch);
                        continue;
                    }
                    hasNext = true;
                }
                break;
            case 1:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (ch == '.') {
                        state = 3;
                        sv.push_back(ch);
                        continue;
                    } else if (ch == 'e' || ch == 'E') {
                        sv.push_back(ch);
                        state = 5;
                        continue;
                    }
                    hasNext = true;
                }
                break;
            case 2:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (isdigit(ch)) {
                        sv.push_back(ch);
                        continue;
                    } else if (ch == '.') {
                        state = 3;
                        sv.push_back(ch);
                        continue;
                    } else if (ch == 'e' || ch == 'E') {
                        sv.push_back(ch);
                        state = 5;
                        continue;
                    }
                    hasNext = true;
                }
                break;
            case 3:
            case 6:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (isdigit(ch)) {
                        sv.push_back(ch);
                        state++;
                        continue;
                    }
                    hasNext = true;
                }
                break;
            case 4:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (isdigit(ch)) {
                        sv.push_back(ch);
                        continue;
                    } else if (ch == 'e' || ch == 'E') {
                        sv.push_back(ch);
                        state = 5;
                        continue;
                    }
                    hasNext = true;
                }
                break;
            case 5:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (ch == '+' || ch == '-') {
                        sv.push_back(ch);
                        state = 6;
                        continue;
                    } else if (isdigit(ch)) {
                        sv.push_back(ch);
                        state = 7;
                        continue;
                    }
                    hasNext = true;
                }
                break;
            case 7:
                if (in_.hasMore()) {
                    ch = in_.read();
                    if (isdigit(ch)) {
                        sv.push_back(ch);
                        continue;
                    }
                    hasNext = true;
                }
                break;
            default:
                throw Exception("Unexpected JSON parse state");
        }
        if (state == 1 || state == 2 || state == 4 || state == 7) {
            if (hasNext) {
                nextChar = ch;
            }
            std::istringstream iss(sv);
            if (state == 1 || state == 2) {
                iss >> lv;
                return Token::Long;
            } else {
                iss >> dv;
                return Token::Double;
            }
        } else {
            if (hasNext) {
                throw unexpected(ch);
            } else {
                throw Exception("Unexpected EOF");
            }
        }
    }
}