mirror of
https://github.com/plexusorg/toml4j.git
synced 2024-12-28 19:24:15 +00:00
Added support for nested inline tables
This commit is contained in:
parent
5bd87a6b56
commit
ddb061b9f9
3 changed files with 67 additions and 34 deletions
|
@ -17,39 +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();
|
||||
|
||||
for (; sharedIndex.get() < s.length(); sharedIndex.incrementAndGet()) {
|
||||
char c = chars[sharedIndex.get()];
|
||||
if (Character.isWhitespace(c)) {
|
||||
continue;
|
||||
}
|
||||
if (c == '#') {
|
||||
break;
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
Object convert(String s, AtomicInteger sharedIndex) {
|
||||
char[] chars = s.toCharArray();
|
||||
boolean inKey = true;
|
||||
boolean pairHasKey = false;
|
||||
boolean inValue = false;
|
||||
boolean quoted = false;
|
||||
boolean inArray = false;
|
||||
boolean inString = false;
|
||||
boolean terminated = false;
|
||||
StringBuilder currentKey = new StringBuilder();
|
||||
StringBuilder current = new StringBuilder();
|
||||
HashMap<String, Object> results = new HashMap<String, Object>();
|
||||
|
||||
for (int i = 1; i < chars.length; i++) {
|
||||
for (; sharedIndex.get() < chars.length; sharedIndex.incrementAndGet()) {
|
||||
int i = sharedIndex.get();
|
||||
char c = chars[i];
|
||||
|
||||
if (terminated) {
|
||||
if (Character.isWhitespace(c)) {
|
||||
continue;
|
||||
}
|
||||
if (c == '#') {
|
||||
break;
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (c == '"') {
|
||||
quoted = !quoted;
|
||||
(inValue ? current : currentKey).append(c);
|
||||
} else if (quoted) {
|
||||
(inKey ? currentKey : current).append(c);
|
||||
} else if (c == '[' && inValue) {
|
||||
AtomicInteger sharedIndex = new AtomicInteger(i);
|
||||
sharedIndex.incrementAndGet();
|
||||
Object converted = ArrayConverter.ARRAY_PARSER.convert(s, sharedIndex);
|
||||
|
||||
|
@ -59,15 +65,23 @@ class InlineTableConverter implements ValueConverter {
|
|||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
i = sharedIndex.get();
|
||||
inArray = true;
|
||||
continue;
|
||||
} else if (c == ']' && inArray) {
|
||||
current.append(']');
|
||||
inArray = false;
|
||||
} else if (c == '{') {
|
||||
sharedIndex.incrementAndGet();
|
||||
Object converted = convert(s, sharedIndex);
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
|
||||
inKey = true;
|
||||
inValue = false;
|
||||
currentKey = new StringBuilder();
|
||||
current = new StringBuilder();
|
||||
} else if (c == ',') {
|
||||
if (inArray) {
|
||||
inArray = false;
|
||||
} else {
|
||||
if (!current.toString().trim().isEmpty()) {
|
||||
Object converted = CONVERTERS.convert(current.toString().trim());
|
||||
|
||||
if (converted == INVALID) {
|
||||
|
@ -78,28 +92,28 @@ class InlineTableConverter implements ValueConverter {
|
|||
}
|
||||
|
||||
inKey = true;
|
||||
pairHasKey = false;
|
||||
inValue = false;
|
||||
currentKey = new StringBuilder();
|
||||
current = new StringBuilder();
|
||||
} else if (c == '=') {
|
||||
inKey = false;
|
||||
pairHasKey = true;
|
||||
inValue = true;
|
||||
} else if (c == '}') {
|
||||
terminated = true;
|
||||
|
||||
if (current.toString().trim().length() == 0) {
|
||||
continue;
|
||||
String trimmed = current.toString().trim();
|
||||
if (!trimmed.isEmpty()) {
|
||||
Object converted = CONVERTERS.convert(trimmed);
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
}
|
||||
|
||||
Object converted = CONVERTERS.convert(current.toString().trim());
|
||||
|
||||
if (converted == INVALID) {
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
results.put(currentKey.toString().trim(), converted);
|
||||
sharedIndex.incrementAndGet();
|
||||
break;
|
||||
} else {
|
||||
(inKey ? currentKey : current).append(c);
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ class Results {
|
|||
for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
|
||||
addValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
stack.pop();
|
||||
} else if (currentTable.accepts(key)) {
|
||||
currentTable.put(key, value);
|
||||
} else {
|
||||
|
|
|
@ -107,4 +107,22 @@ public class InlineTableTest {
|
|||
assertEquals("abc", toml.getString("string"));
|
||||
assertThat(toml.<Long>getList("list"), contains(5L, 6L, 7L, 8L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_read_nested_inline_tables() throws Exception {
|
||||
Toml tables = new Toml().parse("tables = { t1 = { t1_1 = 1, t1_2 = 2}, t2 = { t2_1 = \"a\"} }").getTable("tables");
|
||||
|
||||
assertEquals(1L, tables.getLong("t1.t1_1").longValue());
|
||||
assertEquals(2L, tables.getLong("t1.t1_2").longValue());
|
||||
assertEquals("a", tables.getString("t2.t2_1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_read_all_string_types() throws Exception {
|
||||
Toml strings = new Toml().parse("strings = { literal = 'ab]\"c', multiline = \"\"\"de]\"f\"\"\", multiline_literal = '''gh]\"i''' }").getTable("strings");
|
||||
|
||||
assertEquals("ab]\"c", strings.getString("literal"));
|
||||
assertEquals("de]\"f", strings.getString("multiline"));
|
||||
assertEquals("gh]\"i", strings.getString("multiline_literal"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue