Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package io.github.linkedfactory.core.kvin.util;

import com.google.common.math.DoubleMath;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.opencsv.CSVParser;
Expand Down Expand Up @@ -254,26 +253,27 @@ Object parseValue(String valueStr) {
// this is definitely a string
return valueStr.substring(1, valueStr.length() - 1);
}
// handle boolean values
String valueStrLowerCase = valueStr.toLowerCase();
if ("true".equals(valueStrLowerCase)) {
return true;
} else if ("false".equals(valueStrLowerCase)) {
return false;
}
Object value = valueStr;
Double doubleValue = Doubles.tryParse(valueStr);
if (doubleValue == null && valueStr.contains(",")) {
String cleanedValueStr;
if (valueStr.lastIndexOf(',') < valueStr.lastIndexOf('.')) {
// convert numbers like 123,456.78 to 123456.78
cleanedValueStr = valueStr.replace(",", "");
} else {
// convert numbers like 123.456,78 to 123456.78
cleanedValueStr = valueStr.replace(".", "")
.replace(",", ".");
Double doubleValue = tryParseDouble(valueStr);
if (doubleValue == null) {
String valueStrLowerCase = valueStr.toLowerCase();
if ("true".equals(valueStrLowerCase)) {
return true;
} else if ("false".equals(valueStrLowerCase)) {
return false;
}
if (valueStr.contains(",")) {
String cleanedValueStr;
if (valueStr.lastIndexOf(',') < valueStr.lastIndexOf('.')) {
// convert numbers like 123,456.78 to 123456.78
cleanedValueStr = valueStr.replace(",", "");
} else {
// convert numbers like 123.456,78 to 123456.78
cleanedValueStr = valueStr.replace(".", "")
.replace(",", ".");
}
doubleValue = tryParseDouble(cleanedValueStr);
}
doubleValue = Doubles.tryParse(cleanedValueStr);
}
if (doubleValue != null) {
if (DoubleMath.isMathematicalInteger(doubleValue) && !valueStr.contains(".")) {
Expand All @@ -286,6 +286,22 @@ Object parseValue(String valueStr) {
return value;
}

private static Double tryParseDouble(String value) {
if (value.isEmpty() || value.charAt(value.length() - 1) <= ' ') {
return null;
}
char first = value.charAt(0);
if (!((first >= '0' && first <= '9') || first == '+' || first == '-'
|| first == '.' || first == 'N' || first == 'I')) {
return null;
}
try {
return Double.parseDouble(value);
} catch (NumberFormatException ignored) {
return null;
}
}

public CsvFormatParser setContext(URI context) {
this.context = context;
return this;
Expand All @@ -308,4 +324,4 @@ protected static boolean containsWhitespace(String str) {
}
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,28 @@ public void shouldParseCsvDoubleValues() throws IOException {
assertFalse(tuples.hasNext());
}

@Test
public void shouldParseCommonCsvValueForms() throws IOException {
CsvFormatParser parser = new CsvFormatParser(URIs.createURI("urn:base:"), ',',
new ByteArrayInputStream("time,value\n".getBytes(StandardCharsets.UTF_8)));
Object[][] cases = {
{"42", 42L}, {"+42", 42L}, {"-42", -42L},
{"+.5", 0.5d}, {"1.", 1d}, {"3.14", 3.14d}, {"1e3", 1000L},
{"1f", 1L}, {"0x1.8p1", 3d},
{"1,234.56", 1234.56d}, {"1.234,56", 1234.56d},
{"NaN", Double.NaN}, {"-NaN", Double.NaN},
{"Infinity", Double.POSITIVE_INFINITY}, {"-Infinity", Double.NEGATIVE_INFINITY},
{"true", true}, {"FALSE", false}, {"'quoted'", "quoted"},
{"plain text", "plain text"}, {"NAN", "NAN"}, {"infinity", "infinity"},
{"0x1", "0x1"}, {"1e", "1e"}, {"1_0", "1_0"}, {"1x", "1x"},
{" 1", " 1"}, {"1 ", "1 "}, {"\t1", "\t1"}, {"1\u0000", "1\u0000"}
};
for (Object[] testCase : cases) {
assertEquals("Unexpected value for " + testCase[0], testCase[1],
parser.parseValue((String) testCase[0]));
}
}

@Test
public void shouldPreserveSparseRowsAndTupleFields() throws IOException {
String csv = String.join("\n",
Expand Down