Skip to content

Commit 15ecaa6

Browse files
committed
ANOTHER JUAN
1 parent 6b9d658 commit 15ecaa6

File tree

1 file changed

+207
-1
lines changed

1 file changed

+207
-1
lines changed

src/main/java/org/omegaconfig/impl/formats/JSONFormat.java

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public class JSONFormat implements IFormatCodec {
1616
private static final char JSON_CONTINUE = ',';
1717
private static final char JSON_STRING_LINE = '"';
1818
private static final char JSON_ENTRY_SPLIT = ':';
19+
private static final char JSON_ARRAY_START = '[';
20+
private static final char JSON_ARRAY_END = ']';
1921
private static final char JSON_ESCAPED = '\\';
2022

2123
@Override public String id() { return OmegaConfig.FORMAT_JSON; }
@@ -24,14 +26,218 @@ public class JSONFormat implements IFormatCodec {
2426

2527
@Override
2628
public IFormatReader createReader(Path filePath) throws IOException {
27-
return new FormatReader(filePath);
29+
return new AnotherFormatReader(filePath);
2830
}
2931

3032
@Override
3133
public IFormatWriter createWritter(Path filePath) throws IOException {
3234
return null;
3335
}
3436

37+
private record NextChar(char[] expected, char[] allowed) {
38+
39+
public boolean isExpected(char c) {
40+
return Tools.contains(c, expected);
41+
}
42+
43+
public boolean isAllowed(char c) {
44+
if (allowed == null) return false;
45+
return Tools.contains(c, allowed);
46+
}
47+
}
48+
49+
public enum CapturingMode {
50+
NONE,
51+
KEY,
52+
PRIMITIVE_VALUE,
53+
STRING_VALUE,
54+
ARRAY,
55+
ARRAY_PRIMITIVE_VALUE,
56+
ARRAY_STRING_VALUE;
57+
58+
public boolean value() {
59+
return this == PRIMITIVE_VALUE || this == STRING_VALUE;
60+
}
61+
62+
public boolean string() {
63+
return this == STRING_VALUE || this == KEY;
64+
}
65+
}
66+
67+
public static class AnotherFormatReader implements IFormatReader {
68+
public final LinkedHashMap<String, String> values = new LinkedHashMap<>();
69+
70+
@Override
71+
public String read(String fieldName) {
72+
return "";
73+
}
74+
75+
@Override
76+
public void push(String group) {
77+
78+
}
79+
80+
@Override
81+
public void pop() {
82+
83+
}
84+
85+
@Override
86+
public void close() throws IOException {
87+
88+
}
89+
90+
public AnotherFormatReader(Path path) throws IOException {
91+
// READ JSON STRING
92+
var in = new FileInputStream(path.toFile());
93+
char[] data = new String(in.readAllBytes()).toCharArray();
94+
in.close();
95+
96+
NextChar nextChars = new NextChar(new char[] { JSON_OBJECT_START }, null);
97+
CapturingMode capturing = CapturingMode.NONE;
98+
final LinkedHashSet<String> group = new LinkedHashSet<>();
99+
StringBuilder key = new StringBuilder();
100+
StringBuilder value = new StringBuilder();
101+
List<String> valueArray = new ArrayList<>();
102+
boolean escaped = false;
103+
boolean finished = false;
104+
105+
for (char c: data) {
106+
// SKIP WHITESPACE PROCESING WHEN IS NOT CAPTURING NON-STRING-VALUES
107+
if (Character.isWhitespace(c) && (capturing != CapturingMode.STRING_VALUE)) continue;
108+
109+
// THROW WHEN JSON SPEC IS FINISHED BUT STILL CONTAINS DATA (WTF)
110+
if (finished) {
111+
throw new EOFException("Reached end of JSON spec but file still contains data");
112+
}
113+
114+
// VALIDATE CHARS
115+
if (nextChars != null && !nextChars.isExpected(c)) {
116+
if (nextChars.isAllowed(c)) {
117+
// TODO: handle permisive chars
118+
}
119+
120+
throw new IllegalStateException("Expected char(s) " + Arrays.toString(nextChars.expected) + " but received " + c);
121+
}
122+
123+
// CHAR DETECTION
124+
switch (c) {
125+
case JSON_OBJECT_START -> {
126+
if (capturing == CapturingMode.PRIMITIVE_VALUE) {
127+
group.add(key.toString());
128+
key = new StringBuilder();
129+
capturing = CapturingMode.NONE;
130+
}
131+
132+
nextChars = new NextChar(new char[] { JSON_STRING_LINE, JSON_OBJECT_END }, null);
133+
continue;
134+
}
135+
136+
case JSON_ARRAY_START -> {
137+
if (capturing.string()) {
138+
break;
139+
}
140+
capturing = CapturingMode.ARRAY_PRIMITIVE_VALUE;
141+
continue;
142+
}
143+
144+
case JSON_STRING_LINE -> {
145+
// IF IS CAPTURING AND KEY IS ESCAPED THEN SKIP PROCESING
146+
if (escaped && (capturing == CapturingMode.KEY || capturing == CapturingMode.STRING_VALUE)) {
147+
break;
148+
}
149+
150+
if (capturing == CapturingMode.ARRAY_PRIMITIVE_VALUE) {
151+
capturing = CapturingMode.ARRAY_STRING_VALUE;
152+
continue;
153+
}
154+
155+
// FINISHED CAPTURING
156+
if (capturing == CapturingMode.STRING_VALUE) {
157+
capturing = CapturingMode.NONE;
158+
values.put(Tools.concat("", key.toString(), '.', group), value.toString());
159+
key = new StringBuilder();
160+
value = new StringBuilder();
161+
162+
nextChars = new NextChar(new char[] { JSON_CONTINUE, JSON_OBJECT_END }, null);
163+
continue;
164+
}
165+
166+
// IS NOT A STRING VALUE
167+
if (capturing == CapturingMode.PRIMITIVE_VALUE) {
168+
capturing = CapturingMode.STRING_VALUE;
169+
nextChars = null;
170+
continue;
171+
}
172+
173+
// KEY CAPTURING FINISHED
174+
if (capturing == CapturingMode.KEY) {
175+
capturing = CapturingMode.NONE;
176+
nextChars = new NextChar(new char[] { JSON_ENTRY_SPLIT }, null);
177+
continue;
178+
}
179+
180+
capturing = CapturingMode.KEY;
181+
nextChars = null;
182+
continue;
183+
}
184+
185+
case JSON_ESCAPED -> {
186+
escaped = true;
187+
continue;
188+
}
189+
190+
case JSON_ENTRY_SPLIT -> {
191+
if (capturing.string()) {
192+
break;
193+
}
194+
capturing = CapturingMode.PRIMITIVE_VALUE;
195+
nextChars = null;
196+
continue;
197+
}
198+
199+
case JSON_CONTINUE -> {
200+
// DO NOT CAPTURE WHEN IS CAPTURING A KEY
201+
if (capturing.string()) {
202+
break;
203+
}
204+
if (capturing == CapturingMode.PRIMITIVE_VALUE) {
205+
values.put(Tools.concat("", key.toString(), '.', group), value.toString());
206+
capturing = CapturingMode.NONE;
207+
key = new StringBuilder();
208+
value = new StringBuilder();
209+
}
210+
211+
nextChars = new NextChar(new char[] { JSON_STRING_LINE, JSON_OBJECT_END }, null);
212+
continue;
213+
}
214+
215+
case JSON_OBJECT_END -> {
216+
if (group.isEmpty()) {
217+
finished = true;
218+
capturing = CapturingMode.NONE;
219+
nextChars = null;
220+
continue;
221+
}
222+
group.removeLast();
223+
nextChars = new NextChar(new char[]{ JSON_CONTINUE, JSON_OBJECT_END }, null);
224+
continue;
225+
}
226+
}
227+
228+
// OR BY DEFAULT, CAPTURE
229+
switch (capturing) {
230+
case KEY -> key.append(c);
231+
case STRING_VALUE, PRIMITIVE_VALUE -> value.append(c);
232+
case NONE -> throw new IllegalStateException("Not capturing values");
233+
}
234+
235+
escaped = false;
236+
}
237+
}
238+
}
239+
240+
35241
public static class FormatReader implements IFormatReader {
36242
public final LinkedHashMap<String, String> values = new LinkedHashMap<>();
37243

0 commit comments

Comments
 (0)