Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Morten Haraldsen committed Feb 19, 2025
1 parent 35a5077 commit 82f97e3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 35 deletions.
72 changes: 39 additions & 33 deletions src/main/java/com/ethlo/time/internal/ItuDurationParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import static com.ethlo.time.internal.fixed.ITUParser.DIGITS_IN_NANO;
import static com.ethlo.time.internal.fixed.ITUParser.sanityCheckInputParams;
import static com.ethlo.time.internal.util.LimitedCharArrayIntegerUtil.ZERO;

import java.time.format.DateTimeParseException;

Expand All @@ -44,7 +43,17 @@
public class ItuDurationParser

Check warning on line 43 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L43

Added line #L43 was not covered by tests
{
public static final int NANOS_IN_SECOND = 1_000_000_000;
public static final char SEP_T = 'T';
public static final char UNIT_WEEK = 'W';
public static final char UNIT_DAY = 'D';
public static final char UNIT_HOUR = 'H';
public static final char UNIT_MINUTE = 'M';
public static final char UNIT_SECOND = 'S';
public static final char DOT = '.';
public static final char DIGIT_ZERO = '0';
public static final char DIGIT_NINE = '9';
private static final int[] POW10_TABLE = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
private static final int MAX_DIGITS = 19;

public static Duration parse(final String chars)
{
Expand Down Expand Up @@ -84,48 +93,45 @@ public static Duration parse(final String text, final int offset)
private static int readUntilNonDigit(final String text, final int offset, final DurationPartsConsumer consumer)
{
int unit = 0;
int idx = offset;
int value = 0;
final int len = text.length();
while (idx < len)
int index = offset;
long value = 0;
int startIndex = index;
while (index < text.length())
{
final char c = text.charAt(idx);
int isDigit = (c - '0') >>> 31 | ('9' - c) >>> 31;
final char c = text.charAt(index);
int isDigit = (c - DIGIT_ZERO) >>> 31 | (DIGIT_NINE - c) >>> 31;
if (isDigit != 0)
{
unit = c;
break;
}
else
{
int digit = c - ZERO;

// Correct overflow check
if (value > 214748364 || (value == 214748364 && digit > 7))
{
error("Numeric overflow while parsing value", text, idx);
}

value = (value << 3) + (value << 1) + (c - '0');
//value = value * RADIX + digit;
idx++;
int digit = c - DIGIT_ZERO;
value = (value << 3) + (value << 1) + digit;
index++;
}
}

if (index - startIndex > MAX_DIGITS || value > Integer.MAX_VALUE)
{
error("Value too large for unit '" + (char) unit + "'", text, index);

Check warning on line 118 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L118

Added line #L118 was not covered by tests
}

if (unit == 0)
{
error("No unit defined for value " + value, text, idx);
error("No unit defined for value " + value, text, index);

Check warning on line 123 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L123

Added line #L123 was not covered by tests
}

final int length = idx - offset;
if (length == 0 && (unit == 'W' || unit == 'D' || unit == 'H' || unit == 'M' || unit == 'S' || unit == '.'))
final int length = index - offset;
if (length == 0 && (unit == UNIT_WEEK || unit == UNIT_DAY || unit == UNIT_HOUR || unit == UNIT_MINUTE || unit == UNIT_SECOND || unit == DOT))
{
error("Zero-length value prior to " + ((char) unit), text, idx);
error("Zero-length value prior to unit '" + ((char) unit) + "'", text, index);

Check warning on line 129 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L129

Added line #L129 was not covered by tests
}

consumer.accept(text, idx, length, (char) unit, value);
consumer.accept(text, index, length, (char) unit, (int) value);

return idx + 1;
return index + 1;
}

private static void error(final String errorMessage, final String text, int index)
Expand Down Expand Up @@ -184,7 +190,7 @@ public final void accept(final String chars, final int index, final int length,

switch (unit)
{
case 'T':
case SEP_T:

if (length != 0)
{
Expand All @@ -200,8 +206,8 @@ public final void accept(final String chars, final int index, final int length,
afterT = true;
break;

case 'W':
assertNonFractional('W', chars, index);
case UNIT_WEEK:
assertNonFractional(UNIT_WEEK, chars, index);
if (wFound > 0)
{
error("'W' (week) can only appear once", chars, index);

Check warning on line 213 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L213

Added line #L213 was not covered by tests
Expand All @@ -215,7 +221,7 @@ public final void accept(final String chars, final int index, final int length,
wFound = index;
break;

case 'D':
case UNIT_DAY:
assertNonFractional('D', chars, index);
if (dFound > 0)
{
Expand All @@ -229,7 +235,7 @@ public final void accept(final String chars, final int index, final int length,
dFound = index;
break;

case 'H':
case UNIT_HOUR:
assertNonFractional('H', chars, index);
if (hFound > 0)
{
Expand All @@ -243,8 +249,8 @@ public final void accept(final String chars, final int index, final int length,
hFound = index;
break;

case 'M':
assertNonFractional('M', chars, index);
case UNIT_MINUTE:
assertNonFractional(UNIT_MINUTE, chars, index);
if (mFound > 0)
{
error("'M' (minutes) can only appear once", chars, index);

Check warning on line 256 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L256

Added line #L256 was not covered by tests
Expand All @@ -257,7 +263,7 @@ public final void accept(final String chars, final int index, final int length,
mFound = index;
break;

case 'S':
case UNIT_SECOND:
if (sFound > 0)
{
error("'S' (seconds) can only appear once", chars, index);

Check warning on line 269 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L269

Added line #L269 was not covered by tests
Expand Down Expand Up @@ -301,7 +307,7 @@ public final void accept(final String chars, final int index, final int length,
}
break;

case '.':
case DOT:
if (dotFound)
{
error("'.' can only appear once", chars, index);

Check warning on line 313 in src/main/java/com/ethlo/time/internal/ItuDurationParser.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/ethlo/time/internal/ItuDurationParser.java#L313

Added line #L313 was not covered by tests
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/ethlo/time/ItuDurationParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ void shouldParseDurationWithNoTimeSection()
@Test
void shouldThrowDateTimeParseExceptionForOverflow()
{
final String input = "P999999999999D";
final String input = "P20D9999999999999999H";
assertThatThrownBy(() -> ItuDurationParser.parse(input))
.isInstanceOf(DateTimeParseException.class)
.hasMessageContaining("Numeric overflow while parsing value");
.hasMessageContaining("Value too large for unit 'H': " + input);
}

@Test
Expand Down

0 comments on commit 82f97e3

Please sign in to comment.