public static int parseDurationInSeconds()

in util/src/main/java/com/epam/deltix/util/time/TimeFormatter.java [212:353]


    public static int parseDurationInSeconds (String text)
        throws DurationParseException
    {
        /// See test.td.util.time.Test_SimpleDurationFormat for JUnit test of this method

        final int len = (text != null) ? text.length() : 0;

        if (len == 0)
            throw new DurationParseException ("Cannot parse empty string as duration", text, 0);

        int pos = 0;
        int result = 0;
        int group = 0;

        // BEGIN(Good old C mode)
        final int TERMINAL_STATE_MASK                 = 0x100;
        final int STATE_EXPECT_FIRST_DIGITS_GROUP      = 0x001; // non terminal
        final int STATE_INSIDE_FIRST_DIGITS_GROUP      = 0x102;
        final int STATE_EXPECT_SECOND_DIGITS_GROUP     = 0x003; // non terminal
        final int STATE_INSIDE_SECOND_DIGITS_GROUP     = 0x104;
        final int STATE_PARSED_SECOND_DIGITS_GROUP     = 0x105;
        final int STATE_EXPECT_THIRD_DIGITS_GROUP      = 0x006;
        final int STATE_INSIDE_THIRD_DIGITS_GROUP      = 0x107;
        final int STATE_PARSED_THIRD_DIGITS_GROUP      = 0x108;

        int state = STATE_EXPECT_FIRST_DIGITS_GROUP;

        while (pos < len) {
            final char ch = text.charAt (pos);

            switch (state) {
                // initial state
                case STATE_EXPECT_FIRST_DIGITS_GROUP:
                    if (ch >= '0' && ch <= '9') {
                        group = (ch - '0');
                        state = STATE_INSIDE_FIRST_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Expecting digit", text, pos);
                    }
                    break;

                // we parsed first digit (can be hours or minutes)
                case STATE_INSIDE_FIRST_DIGITS_GROUP:
                    if (ch >= '0' && ch <= '9') {
                        group = group * 10 + (ch - '0');
                        state = STATE_INSIDE_FIRST_DIGITS_GROUP;
                    } else if (ch == ':') {
                        state = STATE_EXPECT_SECOND_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Unexpected digits separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed first ':' symbol
                case STATE_EXPECT_SECOND_DIGITS_GROUP:
                    result = group*60;
                    if (ch >= '0' && ch <= '9') {
                        group = (ch - '0');
                        state = STATE_INSIDE_SECOND_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Expecting digit", text, pos);
                    }
                    break;

                // we parsed first digit of second group
                case STATE_INSIDE_SECOND_DIGITS_GROUP:
                    if (ch >= '0' && ch <= '9') {
                        group = group * 10 + (ch - '0');
                        if (group > 59)
                            throw new DurationParseException ("Minutes or seconds group exceed 59", text, pos);
                        state = STATE_PARSED_SECOND_DIGITS_GROUP;
                    } else if (ch == ':') {
                        state = STATE_EXPECT_THIRD_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Unexpected minutes separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed two digits of minutes value
                case STATE_PARSED_SECOND_DIGITS_GROUP:
                    if (ch == ':') {
                        state = STATE_EXPECT_THIRD_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Unexpected minutes separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed second ':' symbol
                case STATE_EXPECT_THIRD_DIGITS_GROUP:
                    result = (result + group)*60;
                    if (ch >= '0' && ch <= '9') {
                        group = (ch - '0');
                        state = STATE_INSIDE_THIRD_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Expecting first seconds digit", text, pos);
                    }
                    break;

                // we parsed first digit of seconds value
                case STATE_INSIDE_THIRD_DIGITS_GROUP:
                    if (ch >= '0' && ch <= '9') {
                        group = group * 10 + (ch - '0');
                        if (group > 59)
                            throw new DurationParseException ("Seconds value exceed 59", text, pos);
                        state = STATE_PARSED_THIRD_DIGITS_GROUP;
                    } else {
                        throw new DurationParseException ("Unexpected character after seconds group '" + ch + "'", text, pos);
                    }
                    break;

                case STATE_PARSED_THIRD_DIGITS_GROUP:
                    throw new DurationParseException ("Unexpected tail symbol '" + ch + "'", text, pos);

                default:
                    throw new IllegalStateException ("Unexpected state: " + state);

            }
            pos++;
        }

        if ((state & TERMINAL_STATE_MASK) == 0)
            throw new DurationParseException ("Unexpected end of string (state:" + state +')', text, pos);

        switch (state) {
            case STATE_INSIDE_FIRST_DIGITS_GROUP:
                result = group*60; break; // group contains minutes MM

            case STATE_INSIDE_SECOND_DIGITS_GROUP:
            case STATE_PARSED_SECOND_DIGITS_GROUP:
            case STATE_INSIDE_THIRD_DIGITS_GROUP:
            case STATE_PARSED_THIRD_DIGITS_GROUP:
                result += group; break;  // group contains seconds MM:SS
            default:
                throw new IllegalStateException ("Unexpected final state: " + state);
        }

//        if (result >= DurationFormat.MAX_DURATION_IN_SEC)
//            throw new DurationParseException ("Duration " + result + " exceed maximum of " + DurationFormat.MAX_DURATION_IN_SEC, text, pos);

        // END(Good old C mode)
        return result;
    }