mirror of
https://github.com/plexusorg/toml4j.git
synced 2024-12-28 03:04:14 +00:00
Streamlined array and inline table converters to re-use other converters
[ci skip]
This commit is contained in:
parent
ddb061b9f9
commit
d1d7145a03
11 changed files with 263 additions and 206 deletions
|
@ -19,7 +19,7 @@ class ArrayConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger sharedIndex = new AtomicInteger(1);
|
||||
AtomicInteger sharedIndex = new AtomicInteger();
|
||||
Object converted = convert(s, sharedIndex);
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
|
@ -39,119 +39,56 @@ class ArrayConverter implements ValueConverter {
|
|||
return converted;
|
||||
}
|
||||
|
||||
Object convert(String s, AtomicInteger sharedIndex) {
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
char[] chars = s.toCharArray();
|
||||
List<Object> arrayItems = new ArrayList<Object>();
|
||||
boolean terminated = false;
|
||||
StringType stringType = StringType.NONE;
|
||||
StringBuilder current = new StringBuilder();
|
||||
|
||||
for (; sharedIndex.get() < chars.length; sharedIndex.incrementAndGet()) {
|
||||
int i = sharedIndex.get();
|
||||
char c = chars[sharedIndex.get()];
|
||||
for (int i = index.incrementAndGet(); i < chars.length; i = index.incrementAndGet()) {
|
||||
|
||||
if (stringType == StringType.NONE) {
|
||||
if (c == ',') {
|
||||
if (current.toString().trim().length() > 0) {
|
||||
arrayItems.add(current.toString());
|
||||
}
|
||||
current = new StringBuilder();
|
||||
continue;
|
||||
}
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '[') {
|
||||
sharedIndex.incrementAndGet();
|
||||
arrayItems.add(convert(s, sharedIndex));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ']') {
|
||||
terminated = true;
|
||||
if (current.toString().trim().length() > 0) {
|
||||
arrayItems.add(current.toString());
|
||||
}
|
||||
current = new StringBuilder();
|
||||
break;
|
||||
}
|
||||
if (Character.isWhitespace(c)) {
|
||||
continue;
|
||||
}
|
||||
if (c == ',') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '"' && chars[i - 1] != '\\' && !stringType.accepts(c)) {
|
||||
if (chars.length > i + 2 && chars[i + 1] == c && chars[i + 2] == c) {
|
||||
stringType = stringType.flip(StringType.MULTILINE);
|
||||
} else {
|
||||
stringType = stringType.flip(StringType.BASIC);
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\'' && !stringType.accepts(c)) {
|
||||
if (chars.length > i + 2 && chars[i + 1] == c && chars[i + 2] == c) {
|
||||
stringType = stringType.flip(StringType.MULTILINE_LITERAL);
|
||||
} else {
|
||||
stringType = stringType.flip(StringType.LITERAL);
|
||||
}
|
||||
if (c == '[') {
|
||||
arrayItems.add(convert(s, index));
|
||||
continue;
|
||||
}
|
||||
|
||||
current.append(c);
|
||||
if (c == ']') {
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
arrayItems.add(VALUE_CONVERTERS.convert(s, index));
|
||||
}
|
||||
|
||||
if (!terminated) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return convertList(arrayItems);
|
||||
}
|
||||
|
||||
private Object convertList(List<Object> tokens) {
|
||||
ArrayList<Object> nestedList = new ArrayList<Object>();
|
||||
|
||||
for (Object token : tokens) {
|
||||
if (token instanceof String) {
|
||||
Object converted = VALUE_CONVERTERS.convert(((String) token).trim());
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
if (isHomogenousArray(converted, nestedList)) {
|
||||
nestedList.add(converted);
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
} else if (token instanceof List) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> convertedList = (List<Object>) token;
|
||||
if (isHomogenousArray(convertedList, nestedList)) {
|
||||
nestedList.add(convertedList);
|
||||
} else {
|
||||
return INVALID;
|
||||
}
|
||||
for (Object arrayItem : arrayItems) {
|
||||
if (arrayItem == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (!isHomogenousArray(arrayItem, arrayItems)) {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return nestedList;
|
||||
|
||||
return arrayItems;
|
||||
}
|
||||
|
||||
private boolean isHomogenousArray(Object o, List<?> values) {
|
||||
return values.isEmpty() || values.get(0).getClass().isAssignableFrom(o.getClass()) || o.getClass().isAssignableFrom(values.get(0).getClass());
|
||||
}
|
||||
|
||||
private static enum StringType {
|
||||
NONE, BASIC, LITERAL, MULTILINE, MULTILINE_LITERAL;
|
||||
|
||||
StringType flip(StringType to) {
|
||||
return this == NONE ? to : NONE;
|
||||
}
|
||||
|
||||
boolean accepts(char c) {
|
||||
if (this == BASIC || this == MULTILINE) {
|
||||
return c != '"';
|
||||
}
|
||||
|
||||
if (this == LITERAL || this == MULTILINE_LITERAL) {
|
||||
return c != '\'';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayConverter() {}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
class BooleanConverter implements ValueConverter {
|
||||
|
@ -14,13 +17,24 @@ class BooleanConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (!isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
s = s.substring(index.get());
|
||||
Boolean b = s.startsWith("true") ? Boolean.TRUE : Boolean.FALSE;
|
||||
|
||||
int endIndex = b == Boolean.TRUE ? 4 : 5;
|
||||
|
||||
if (!ValueConverterUtils.isComment(s.substring(endIndex))) {
|
||||
return INVALID;
|
||||
}
|
||||
index.addAndGet(endIndex - 1);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -15,13 +17,18 @@ class DateConverter implements ValueConverter {
|
|||
public boolean canConvert(String s) {
|
||||
Matcher matcher = DATE_REGEX.matcher(s);
|
||||
|
||||
return matcher.matches() && ValueConverterUtils.isComment(matcher.group(4));
|
||||
return matcher.matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
Matcher matcher = DATE_REGEX.matcher(s);
|
||||
matcher.matches();
|
||||
|
||||
if (!isComment(matcher.group(4))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
s = matcher.group(1);
|
||||
String zone = matcher.group(3);
|
||||
String fractionalSeconds = matcher.group(2);
|
||||
|
@ -36,6 +43,7 @@ class DateConverter implements ValueConverter {
|
|||
} else if (zone.contains(":")) {
|
||||
s += zone.replace(":", "");
|
||||
}
|
||||
|
||||
try {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
|
||||
dateFormat.setLenient(false);
|
||||
|
@ -44,6 +52,37 @@ class DateConverter implements ValueConverter {
|
|||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String original, AtomicInteger index) {
|
||||
String s = original.substring(index.get());
|
||||
Matcher matcher = DATE_REGEX.matcher(s);
|
||||
matcher.matches();
|
||||
String dateString = matcher.group(1);
|
||||
String zone = matcher.group(3);
|
||||
String fractionalSeconds = matcher.group(2);
|
||||
String format = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
if (fractionalSeconds != null && !fractionalSeconds.isEmpty()) {
|
||||
format += ".SSS";
|
||||
dateString += fractionalSeconds;
|
||||
}
|
||||
format += "Z";
|
||||
if ("Z".equals(zone)) {
|
||||
dateString += "+0000";
|
||||
} else if (zone.contains(":")) {
|
||||
dateString += zone.replace(":", "");
|
||||
}
|
||||
|
||||
index.addAndGet(matcher.end(3) - 1);
|
||||
|
||||
try {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
|
||||
dateFormat.setLenient(false);
|
||||
return dateFormat.parse(dateString);
|
||||
} catch (Exception e) {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
private DateConverter() {}
|
||||
}
|
||||
|
|
|
@ -17,55 +17,45 @@ class InlineTableConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger sharedIndex = new AtomicInteger(1);
|
||||
Object converted = convert(s, sharedIndex);
|
||||
char[] chars = s.toCharArray();
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
for (; sharedIndex.get() < s.length(); sharedIndex.incrementAndGet()) {
|
||||
char c = chars[sharedIndex.get()];
|
||||
if (Character.isWhitespace(c)) {
|
||||
continue;
|
||||
}
|
||||
if (c == '#') {
|
||||
break;
|
||||
}
|
||||
|
||||
String substring = s.substring(index.incrementAndGet());
|
||||
if (converted == INVALID || !ValueConverterUtils.isComment(substring)) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
Object convert(String s, AtomicInteger sharedIndex) {
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger sharedIndex) {
|
||||
char[] chars = s.toCharArray();
|
||||
boolean inKey = true;
|
||||
boolean inValue = false;
|
||||
boolean quoted = false;
|
||||
boolean terminated = false;
|
||||
StringBuilder currentKey = new StringBuilder();
|
||||
StringBuilder current = new StringBuilder();
|
||||
HashMap<String, Object> results = new HashMap<String, Object>();
|
||||
|
||||
for (; sharedIndex.get() < chars.length; sharedIndex.incrementAndGet()) {
|
||||
int i = sharedIndex.get();
|
||||
for (int i = sharedIndex.incrementAndGet(); sharedIndex.get() < chars.length; i = sharedIndex.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '"') {
|
||||
if (c == '"' && inKey) {
|
||||
quoted = !quoted;
|
||||
(inValue ? current : currentKey).append(c);
|
||||
currentKey.append(c);
|
||||
} else if (quoted) {
|
||||
(inKey ? currentKey : current).append(c);
|
||||
} else if (c == '[' && inValue) {
|
||||
sharedIndex.incrementAndGet();
|
||||
Object converted = ArrayConverter.ARRAY_PARSER.convert(s, sharedIndex);
|
||||
currentKey.append(c);
|
||||
} else if (inValue && !Character.isWhitespace(c)) {
|
||||
Object converted = CONVERTERS.convert(s, sharedIndex);
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
i = sharedIndex.get();
|
||||
continue;
|
||||
currentKey = new StringBuilder();
|
||||
inValue = false;
|
||||
} else if (c == '{') {
|
||||
sharedIndex.incrementAndGet();
|
||||
Object converted = convert(s, sharedIndex);
|
||||
|
@ -79,43 +69,18 @@ class InlineTableConverter implements ValueConverter {
|
|||
inKey = true;
|
||||
inValue = false;
|
||||
currentKey = new StringBuilder();
|
||||
current = new StringBuilder();
|
||||
} else if (c == ',') {
|
||||
if (!current.toString().trim().isEmpty()) {
|
||||
Object converted = CONVERTERS.convert(current.toString().trim());
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
}
|
||||
|
||||
inKey = true;
|
||||
inValue = false;
|
||||
currentKey = new StringBuilder();
|
||||
current = new StringBuilder();
|
||||
} else if (c == '=') {
|
||||
inKey = false;
|
||||
inValue = true;
|
||||
} else if (c == '}') {
|
||||
terminated = true;
|
||||
|
||||
String trimmed = current.toString().trim();
|
||||
if (!trimmed.isEmpty()) {
|
||||
Object converted = CONVERTERS.convert(trimmed);
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
}
|
||||
|
||||
sharedIndex.incrementAndGet();
|
||||
break;
|
||||
} else {
|
||||
(inKey ? currentKey : current).append(c);
|
||||
} else if (inKey) {
|
||||
currentKey.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
class LiteralStringConverter implements ValueConverter {
|
||||
|
@ -14,31 +17,38 @@ class LiteralStringConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
int endIndex = -1;
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
for (int i = 1; i < chars.length; i++) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '\'') {
|
||||
endIndex = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (endIndex > -1 && c == '#') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (endIndex > -1 && !Character.isWhitespace(c)) {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (endIndex == -1) {
|
||||
if (converted == INVALID || !isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return s.substring(1, endIndex);
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
char[] chars = s.toCharArray();
|
||||
boolean terminated = false;
|
||||
int startIndex = index.incrementAndGet();
|
||||
|
||||
for (int i = index.get(); i < chars.length; i = index.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '\'') {
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!terminated) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
String substring = s.substring(startIndex, index.get());
|
||||
|
||||
return substring;
|
||||
}
|
||||
|
||||
private LiteralStringConverter() {}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class MultilineLiteralStringConverter implements ValueConverter {
|
||||
|
||||
|
@ -13,28 +16,33 @@ class MultilineLiteralStringConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || !isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
char[] chars = s.toCharArray();
|
||||
int startIndex = index.addAndGet(3);
|
||||
int endIndex = -1;
|
||||
|
||||
for (int i = 3; i < chars.length; i++) {
|
||||
for (int i = startIndex; i < chars.length; i = index.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '\'' && chars.length > i + 2 && chars[i + 1] == '\'' && chars[i + 2] == '\'') {
|
||||
endIndex = i;
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (endIndex > -1 && c == '#') {
|
||||
index.addAndGet(2);
|
||||
break;
|
||||
}
|
||||
|
||||
if (endIndex > -1 && !Character.isWhitespace(c)) {
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return s.substring(3, endIndex);
|
||||
return s.substring(startIndex, endIndex);
|
||||
}
|
||||
|
||||
private MultilineLiteralStringConverter() {}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class MultilineStringConverter implements ValueConverter {
|
||||
|
||||
|
||||
static final MultilineStringConverter MULTILINE_STRING_PARSER = new MultilineStringConverter();
|
||||
|
||||
@Override
|
||||
|
@ -13,22 +16,45 @@ class MultilineStringConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
int terminator = s.indexOf("\"\"\"", 3);
|
||||
|
||||
if (terminator == -1) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || !isComment(s.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (!ValueConverterUtils.isComment(s.substring(terminator + 3))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
s = s.substring(2, terminator + 1);
|
||||
s = s.replaceAll("\\\\\\s+", "");
|
||||
|
||||
return StringConverter.STRING_PARSER.convert(s);
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
char[] chars = s.toCharArray();
|
||||
int startIndex = index.addAndGet(3);
|
||||
int endIndex = -1;
|
||||
|
||||
for (int i = startIndex; i < chars.length; i = index.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (c == '"' && chars.length > i + 2 && chars[i + 1] == '"' && chars[i + 2] == '"') {
|
||||
endIndex = i;
|
||||
index.addAndGet(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (endIndex == -1) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
s = s.substring(startIndex, endIndex);
|
||||
s = s.replaceAll("\\\\\\s+", "");
|
||||
s = StringConverter.STRING_PARSER.replaceUnicodeCharacters(s);
|
||||
s = StringConverter.STRING_PARSER.replaceSpecialCharacters(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private MultilineStringConverter() {
|
||||
}
|
||||
|
||||
private MultilineStringConverter() {}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class NumberConverter implements ValueConverter {
|
||||
static final NumberConverter NUMBER_PARSER = new NumberConverter();
|
||||
|
@ -14,20 +17,33 @@ class NumberConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String s) {
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(s, index);
|
||||
|
||||
if (converted == INVALID || (s.length() > index.get() + 1 && !isComment(s.substring(index.incrementAndGet())))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String s, AtomicInteger index) {
|
||||
char[] chars = s.toCharArray();
|
||||
boolean whitespace = false;
|
||||
boolean signable = true;
|
||||
boolean dottable = false;
|
||||
boolean exponentable = false;
|
||||
boolean terminatable = false;
|
||||
String type = "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
for (int i = index.get(); i < chars.length; i = index.incrementAndGet()) {
|
||||
char c = chars[i];
|
||||
|
||||
if (Character.isDigit(c)) {
|
||||
sb.append(c);
|
||||
signable = false;
|
||||
terminatable = true;
|
||||
if (type.isEmpty()) {
|
||||
type = "integer";
|
||||
dottable = true;
|
||||
|
@ -35,26 +51,28 @@ class NumberConverter implements ValueConverter {
|
|||
exponentable = !type.equals("exponent");
|
||||
} else if ((c == '+' || c == '-') && signable && chars.length > i + 1) {
|
||||
signable = false;
|
||||
terminatable = false;
|
||||
if (c == '-') {
|
||||
sb.append('-');
|
||||
}
|
||||
} else if (c == '.' && dottable && chars.length > i + 1) {
|
||||
sb.append('.');
|
||||
type = "float";
|
||||
terminatable = false;
|
||||
dottable = false;
|
||||
exponentable = false;
|
||||
} else if ((c == 'E' || c == 'e') && exponentable && chars.length > i + 1) {
|
||||
sb.append('E');
|
||||
type = "exponent";
|
||||
terminatable = false;
|
||||
signable = true;
|
||||
dottable = false;
|
||||
exponentable = false;
|
||||
} else if (Character.isWhitespace(c)) {
|
||||
whitespace = true;
|
||||
} else if (whitespace && c == '#') {
|
||||
break;
|
||||
} else {
|
||||
type = "";
|
||||
if (!terminatable) {
|
||||
type = "";
|
||||
}
|
||||
index.decrementAndGet();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.moandjiezana.toml;
|
|||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.isComment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -18,22 +19,35 @@ class StringConverter implements ValueConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(String value) {
|
||||
int stringTerminator = -1;
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
Object converted = convert(value, index);
|
||||
|
||||
if (converted == INVALID || !isComment(value.substring(index.incrementAndGet()))) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(String value, AtomicInteger sharedIndex) {
|
||||
int startIndex = sharedIndex.incrementAndGet();
|
||||
int endIndex = -1;
|
||||
char[] chars = value.toCharArray();
|
||||
|
||||
for (int i = 1; i < chars.length; i++) {
|
||||
for (int i = sharedIndex.get(); i < chars.length; i = sharedIndex.incrementAndGet()) {
|
||||
char ch = chars[i];
|
||||
if (ch == '"' && chars[i - 1] != '\\') {
|
||||
stringTerminator = i;
|
||||
endIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stringTerminator == -1 || !isComment(value.substring(stringTerminator + 1))) {
|
||||
if (endIndex == -1) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
value = value.substring(1, stringTerminator);
|
||||
value = value.substring(startIndex, endIndex);
|
||||
value = replaceUnicodeCharacters(value);
|
||||
value = replaceSpecialCharacters(value);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
interface ValueConverter {
|
||||
|
||||
/**
|
||||
|
@ -9,6 +11,16 @@ interface ValueConverter {
|
|||
|
||||
/**
|
||||
* @param s must already have been validated by {@link #canConvert(String)}
|
||||
* @return a value or {@link ValueConverterUtils#INVALID}
|
||||
*/
|
||||
Object convert(String s);
|
||||
|
||||
/**
|
||||
* Partial validation. Stops after type terminator, rather than at EOI.
|
||||
*
|
||||
* @param s must already have been validated by {@link #canConvert(String)}
|
||||
* @param index where to start in s
|
||||
* @return a value or {@link ValueConverterUtils#INVALID}
|
||||
*/
|
||||
Object convert(String s, AtomicInteger index);
|
||||
}
|
||||
|
|
|
@ -11,13 +11,15 @@ import static com.moandjiezana.toml.NumberConverter.NUMBER_PARSER;
|
|||
import static com.moandjiezana.toml.StringConverter.STRING_PARSER;
|
||||
import static com.moandjiezana.toml.ValueConverterUtils.INVALID;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
class ValueConverters {
|
||||
|
||||
private static final ValueConverter[] PARSERS = {
|
||||
MULTILINE_STRING_PARSER, MULTILINE_LITERAL_STRING_CONVERTER, LITERAL_STRING_PARSER, STRING_PARSER, DATE_PARSER, NUMBER_PARSER, BOOLEAN_PARSER, ARRAY_PARSER, INLINE_TABLE_PARSER
|
||||
};
|
||||
|
||||
public Object convert(String value) {
|
||||
Object convert(String value) {
|
||||
for (ValueConverter valueParser : PARSERS) {
|
||||
if (valueParser.canConvert(value)) {
|
||||
return valueParser.convert(value);
|
||||
|
@ -26,4 +28,16 @@ class ValueConverters {
|
|||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
|
||||
Object convert(String value, AtomicInteger index) {
|
||||
String substring = value.substring(index.get());
|
||||
for (ValueConverter valueParser : PARSERS) {
|
||||
if (valueParser.canConvert(substring)) {
|
||||
return valueParser.convert(value, index);
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue