Skip to content

Commit b12a480

Browse files
committed
Polish BasicJsonParser
1 parent 8d0cfdf commit b12a480

File tree

1 file changed

+49
-21
lines changed

1 file changed

+49
-21
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/BasicJsonParser.java

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.json;
1818

1919
import java.util.ArrayList;
20+
import java.util.Arrays;
2021
import java.util.LinkedHashMap;
2122
import java.util.List;
2223
import java.util.Map;
@@ -123,38 +124,33 @@ private static String trimEdges(String string, char leadingChar, char trailingCh
123124

124125
private List<String> tokenize(String json) {
125126
List<String> list = new ArrayList<>();
126-
int index = 0;
127-
int inObject = 0;
128-
int inList = 0;
129-
boolean inValue = false;
130-
boolean inEscape = false;
127+
Tracking tracking = new Tracking();
131128
StringBuilder build = new StringBuilder();
129+
int index = 0;
132130
while (index < json.length()) {
133-
char current = json.charAt(index);
134-
if (inEscape) {
135-
build.append(current);
131+
char ch = json.charAt(index);
132+
if (tracking.in(Tracked.ESCAPE)) {
133+
build.append(ch);
136134
index++;
137-
inEscape = false;
135+
tracking.set(Tracked.ESCAPE, 0);
138136
continue;
139137
}
140-
switch (current) {
141-
case '{' -> inObject++;
142-
case '}' -> inObject--;
143-
case '[' -> inList++;
144-
case ']' -> inList--;
145-
}
146-
if (current == '"') {
147-
inValue = !inValue;
138+
switch (ch) {
139+
case '{' -> tracking.update(Tracked.OBJECT, +1);
140+
case '}' -> tracking.update(Tracked.OBJECT, -1);
141+
case '[' -> tracking.update(Tracked.LIST, +1);
142+
case ']' -> tracking.update(Tracked.LIST, -1);
143+
case '"' -> tracking.toggle(Tracked.VALUE);
148144
}
149-
if (current == ',' && inObject == 0 && inList == 0 && !inValue) {
145+
if (ch == ',' && !tracking.in(Tracked.OBJECT, Tracked.LIST, Tracked.VALUE)) {
150146
list.add(build.toString());
151147
build.setLength(0);
152148
}
153-
else if (current == '\\') {
154-
inEscape = true;
149+
else if (ch == '\\') {
150+
tracking.set(Tracked.ESCAPE, 1);
155151
}
156152
else {
157-
build.append(current);
153+
build.append(ch);
158154
}
159155
index++;
160156
}
@@ -164,4 +160,36 @@ else if (current == '\\') {
164160
return list;
165161
}
166162

163+
private static final class Tracking {
164+
165+
private final int[] counts = new int[Tracked.values().length];
166+
167+
boolean in(Tracked... tracked) {
168+
return Arrays.stream(tracked).mapToInt(this::get).anyMatch((i) -> i > 0);
169+
}
170+
171+
void toggle(Tracked tracked) {
172+
set(tracked, (get(tracked) != 0) ? 0 : 1);
173+
}
174+
175+
void update(Tracked tracked, int delta) {
176+
set(tracked, get(tracked) + delta);
177+
}
178+
179+
private int get(Tracked tracked) {
180+
return this.counts[tracked.ordinal()];
181+
}
182+
183+
void set(Tracked tracked, int count) {
184+
this.counts[tracked.ordinal()] = count;
185+
}
186+
187+
}
188+
189+
private enum Tracked {
190+
191+
OBJECT, LIST, VALUE, ESCAPE
192+
193+
}
194+
167195
}

0 commit comments

Comments
 (0)