From 5d17559728ed10c1473d9dc8a3b18a8265ab2730 Mon Sep 17 00:00:00 2001 From: "moandji.ezana" Date: Sun, 8 Feb 2015 22:54:28 +0200 Subject: [PATCH] Consolidated all number parsing into NumberConverter --- .../moandjiezana/toml/ExponentConverter.java | 70 ----------------- .../com/moandjiezana/toml/FloatConverter.java | 28 ------- .../moandjiezana/toml/IntegerConverter.java | 53 ------------- .../moandjiezana/toml/NumberConverter.java | 78 +++++++++++++++++++ .../moandjiezana/toml/ValueConverters.java | 6 +- .../com/moandjiezana/toml/NumberTest.java | 36 +++++++++ 6 files changed, 116 insertions(+), 155 deletions(-) delete mode 100644 src/main/java/com/moandjiezana/toml/ExponentConverter.java delete mode 100644 src/main/java/com/moandjiezana/toml/FloatConverter.java delete mode 100644 src/main/java/com/moandjiezana/toml/IntegerConverter.java create mode 100644 src/main/java/com/moandjiezana/toml/NumberConverter.java diff --git a/src/main/java/com/moandjiezana/toml/ExponentConverter.java b/src/main/java/com/moandjiezana/toml/ExponentConverter.java deleted file mode 100644 index 327067a..0000000 --- a/src/main/java/com/moandjiezana/toml/ExponentConverter.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.moandjiezana.toml; - - -class ExponentConverter implements ValueConverter { - - public static final ExponentConverter EXPONENT_PARSER = new ExponentConverter(); - - @Override - public boolean canConvert(String s) { - char[] chars = s.toCharArray(); - boolean whitespace = false; - boolean exponent = false; - boolean signable = true; - boolean decimal = false; - - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - - if (Character.isDigit(c)) { - signable = false; - continue; - } - - if (signable && (c == '+' || c == '-') && chars.length > i + 1 && Character.isDigit(chars[i + 1])) { - signable = false; - continue; - } - - if (i > 0 && (c == 'E' || c == 'e')) { - signable = true; - exponent = true; - continue; - } - - if (i > 0 && c == '.' && !decimal && !exponent) { - decimal = true; - continue; - } - - if (Character.isWhitespace(c)) { - whitespace = true; - continue; - } - - if (whitespace && c == '#') { - break; - } - - return false; - } - - return exponent && !signable; - } - - @Override - public Object convert(String s) { - if (s.startsWith("+")) { - s = s.substring(1); - } - - int startOfComment = s.indexOf('#'); - if (startOfComment > -1) { - s = s.substring(0, startOfComment).trim(); - } - - String[] exponentString = s.split("[eE]"); - - return Double.parseDouble(exponentString[0]) * Math.pow(10, Double.parseDouble(exponentString[1])); - } -} diff --git a/src/main/java/com/moandjiezana/toml/FloatConverter.java b/src/main/java/com/moandjiezana/toml/FloatConverter.java deleted file mode 100644 index 47c75c5..0000000 --- a/src/main/java/com/moandjiezana/toml/FloatConverter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.moandjiezana.toml; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -class FloatConverter implements ValueConverter { - - public static final FloatConverter FLOAT_PARSER = new FloatConverter(); - private static final Pattern FLOAT_REGEX = Pattern.compile("([+-]?\\d+\\.\\d+)(.*)"); - - @Override - public boolean canConvert(String s) { - Matcher matcher = FLOAT_REGEX.matcher(s); - - return matcher.matches() && ValueConverterUtils.isComment(matcher.group(2)); - } - - @Override - public Object convert(String s) { - Matcher matcher = FLOAT_REGEX.matcher(s); - matcher.matches(); - - return Double.valueOf(matcher.group(1)); - } - - private FloatConverter() {} - -} diff --git a/src/main/java/com/moandjiezana/toml/IntegerConverter.java b/src/main/java/com/moandjiezana/toml/IntegerConverter.java deleted file mode 100644 index 13d5aec..0000000 --- a/src/main/java/com/moandjiezana/toml/IntegerConverter.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.moandjiezana.toml; - - -class IntegerConverter implements ValueConverter { - static final IntegerConverter INTEGER_PARSER = new IntegerConverter(); - - @Override - public boolean canConvert(String s) { - char[] chars = s.toCharArray(); - boolean whitespace = false; - - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - - if (Character.isDigit(c)) { - continue; - } - - if (i == 0 && (c == '+' || c == '-')) { - continue; - } - - if (Character.isWhitespace(c)) { - whitespace = true; - continue; - } - - if (whitespace && c == '#') { - return true; - } - - return false; - } - - return true; - } - - @Override - public Object convert(String s) { - if (s.startsWith("+")) { - s = s.substring(1); - } - - int startOfComment = s.indexOf('#'); - if (startOfComment > -1) { - s = s.substring(0, startOfComment).trim(); - } - - return Long.valueOf(s); - } - - private IntegerConverter() {} -} diff --git a/src/main/java/com/moandjiezana/toml/NumberConverter.java b/src/main/java/com/moandjiezana/toml/NumberConverter.java new file mode 100644 index 0000000..07557a3 --- /dev/null +++ b/src/main/java/com/moandjiezana/toml/NumberConverter.java @@ -0,0 +1,78 @@ +package com.moandjiezana.toml; + +import static com.moandjiezana.toml.ValueConverterUtils.INVALID; + +class NumberConverter implements ValueConverter { + static final NumberConverter NUMBER_PARSER = new NumberConverter(); + + @Override + public boolean canConvert(String s) { + char firstChar = s.charAt(0); + + return firstChar == '+' || firstChar == '-' || Character.isDigit(firstChar); + } + + public static void main(String[] args) { + new NumberConverter().convert("5e+22"); + } + + @Override + public Object convert(String s) { + char[] chars = s.toCharArray(); + boolean whitespace = false; + boolean signable = true; + boolean dottable = false; + boolean exponentable = false; + String type = ""; + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + + if (Character.isDigit(c)) { + sb.append(c); + signable = false; + if (type.isEmpty()) { + type = "integer"; + dottable = true; + } + exponentable = !type.equals("exponent"); + } else if ((c == '+' || c == '-') && signable && chars.length > i + 1) { + signable = false; + if (c == '-') { + sb.append('-'); + } + } else if (c == '.' && dottable && chars.length > i + 1) { + sb.append('.'); + type = "float"; + dottable = false; + exponentable = false; + } else if ((c == 'E' || c == 'e') && exponentable && chars.length > i + 1) { + sb.append('E'); + type = "exponent"; + signable = true; + dottable = false; + exponentable = false; + } else if (Character.isWhitespace(c)) { + whitespace = true; + } else if (whitespace && c == '#') { + break; + } else { + type = ""; + break; + } + } + + if (type.equals("integer")) { + return Long.valueOf(sb.toString()); + } else if (type.equals("float")) { + return Double.valueOf(sb.toString()); + } else if (type.equals("exponent")) { + String[] exponentString = sb.toString().split("E"); + + return Double.parseDouble(exponentString[0]) * Math.pow(10, Double.parseDouble(exponentString[1])); + } else { + return INVALID; + } + } +} diff --git a/src/main/java/com/moandjiezana/toml/ValueConverters.java b/src/main/java/com/moandjiezana/toml/ValueConverters.java index de23fa6..d4b8a96 100644 --- a/src/main/java/com/moandjiezana/toml/ValueConverters.java +++ b/src/main/java/com/moandjiezana/toml/ValueConverters.java @@ -3,19 +3,17 @@ package com.moandjiezana.toml; import static com.moandjiezana.toml.ArrayConverter.ARRAY_PARSER; import static com.moandjiezana.toml.BooleanConverter.BOOLEAN_PARSER; import static com.moandjiezana.toml.DateConverter.DATE_PARSER; -import static com.moandjiezana.toml.ExponentConverter.EXPONENT_PARSER; -import static com.moandjiezana.toml.FloatConverter.FLOAT_PARSER; -import static com.moandjiezana.toml.IntegerConverter.INTEGER_PARSER; import static com.moandjiezana.toml.LiteralStringConverter.LITERAL_STRING_PARSER; import static com.moandjiezana.toml.MultilineLiteralStringConverter.MULTILINE_LITERAL_STRING_CONVERTER; import static com.moandjiezana.toml.MultilineStringConverter.MULTILINE_STRING_PARSER; +import static com.moandjiezana.toml.NumberConverter.NUMBER_PARSER; import static com.moandjiezana.toml.StringConverter.STRING_PARSER; import static com.moandjiezana.toml.ValueConverterUtils.INVALID; class ValueConverters { private static final ValueConverter[] PARSERS = { - MULTILINE_STRING_PARSER, MULTILINE_LITERAL_STRING_CONVERTER, LITERAL_STRING_PARSER, STRING_PARSER, DATE_PARSER, EXPONENT_PARSER, INTEGER_PARSER, FLOAT_PARSER, BOOLEAN_PARSER, ARRAY_PARSER + MULTILINE_STRING_PARSER, MULTILINE_LITERAL_STRING_CONVERTER, LITERAL_STRING_PARSER, STRING_PARSER, DATE_PARSER, NUMBER_PARSER, BOOLEAN_PARSER, ARRAY_PARSER }; public Object convert(String value) { diff --git a/src/test/java/com/moandjiezana/toml/NumberTest.java b/src/test/java/com/moandjiezana/toml/NumberTest.java index 16b2009..4c0ab9d 100644 --- a/src/test/java/com/moandjiezana/toml/NumberTest.java +++ b/src/test/java/com/moandjiezana/toml/NumberTest.java @@ -84,6 +84,12 @@ public class NumberTest { new Toml().parse("answer = -.12345"); } + @Test(expected = IllegalStateException.class) + public void should_fail_on_float_with_sign_after_dot() { + new Toml().parse("answer = 1.-1"); + new Toml().parse("answer = 1.+1"); + } + @Test(expected = IllegalStateException.class) public void should_fail_on_float_without_digits_after_dot() { new Toml().parse("answer = 1."); @@ -93,4 +99,34 @@ public class NumberTest { public void should_fail_on_negative_float_without_digits_after_dot() { new Toml().parse("answer = -1."); } + + @Test(expected = IllegalStateException.class) + public void should_fail_on_exponent_without_digits_after_dot() { + new Toml().parse("answer = 1.E1"); + } + + @Test(expected = IllegalStateException.class) + public void should_fail_on_negative_exponent_without_digits_after_dot() { + new Toml().parse("answer = -1.E1"); + } + + @Test(expected = IllegalStateException.class) + public void should_fail_on_exponent_with_dot_in_exponent_part() { + new Toml().parse("answer = -1E1.0"); + } + + @Test(expected = IllegalStateException.class) + public void should_fail_on_exponent_without_numbers_after_E() { + new Toml().parse("answer = -1E"); + } + + @Test(expected = IllegalStateException.class) + public void should_fail_on_exponent_with_two_E() { + new Toml().parse("answer = -1E1E1"); + } + + @Test(expected = IllegalStateException.class) + public void should_fail_on_float_with_two_dots() { + new Toml().parse("answer = 1.1.1"); + } }