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;
}