Skip to content

Commit 51ad480

Browse files
committed
update: 使用Peekable接口代替原来的PashbackReader
1 parent 635410a commit 51ad480

File tree

7 files changed

+57
-44
lines changed

7 files changed

+57
-44
lines changed

src/main/java/top/nintha/json/JsonNumber.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package top.nintha.json;
22

3-
import java.util.HashMap;
4-
53
public class JsonNumber implements JsonValue {
64
private double value = 0.0;
75

src/main/java/top/nintha/json/Parser.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
package top.nintha.json;
22

3-
import java.io.IOException;
4-
import java.io.PushbackReader;
5-
import java.io.StringReader;
6-
73
public class Parser {
84
private final Tokenizer tokenizer;
95

106
public Parser(String json) {
11-
StringReader reader = new StringReader(json);
12-
this.tokenizer = new Tokenizer(new PushbackReader(reader));
7+
this.tokenizer = new Tokenizer(json);
138
}
149

1510
public JsonValue parse() {
1611
return parseToken(step());
1712
}
1813

1914
private Token step() {
20-
Token token = null;
21-
try {
22-
token = tokenizer.next();
23-
} catch (IOException e) {
24-
throw new RuntimeException(e);
25-
}
15+
Token token = tokenizer.next();
2616
if (token == null) {
2717
throw new RuntimeException("Unexpected end of JSON");
2818
}

src/main/java/top/nintha/json/TokenType.java

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/main/java/top/nintha/json/Tokenizer.java

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
package top.nintha.json;
22

3-
import java.io.IOException;
4-
import java.io.PushbackReader;
3+
import top.nintha.json.util.TextCharIterator;
54

65
public class Tokenizer {
76

8-
private final PushbackReader reader;
7+
private final TextCharIterator iterator;
98

10-
public Tokenizer(PushbackReader reader) {
11-
this.reader = reader;
9+
public Tokenizer(String text) {
10+
this.iterator = new TextCharIterator(text);
1211
}
1312

14-
public Token next() throws IOException {
15-
int v;
16-
while ((v = reader.read()) != -1) {
17-
char c = (char) v;
13+
public Token next() {
14+
while (iterator.hasNext()) {
15+
char c = iterator.next();
1816
if (Character.isWhitespace(c)) {
1917
continue;
2018
}
@@ -23,7 +21,7 @@ public Token next() throws IOException {
2321
return null;
2422
}
2523

26-
private Token charToToken(char c) throws IOException {
24+
private Token charToToken(char c) {
2725
switch (c) {
2826
case ',':
2927
return new Token.Comma();
@@ -54,12 +52,11 @@ private Token charToToken(char c) throws IOException {
5452
}
5553
}
5654

57-
private String readText(char first) throws IOException {
55+
private String readText(char first) {
5856
StringBuilder sb = new StringBuilder();
5957
boolean escape = false;
60-
int v;
61-
while ((v = reader.read()) != -1) {
62-
char c = (char) v;
58+
while (iterator.hasNext()) {
59+
char c = iterator.next();
6360
if (c == first && !escape) {
6461
return sb.toString();
6562
}
@@ -77,44 +74,42 @@ private String readText(char first) throws IOException {
7774
return sb.toString();
7875
}
7976

80-
private double readNum(char first) throws IOException {
77+
private double readNum(char first) {
8178
StringBuilder sb = new StringBuilder(String.valueOf(first));
8279
boolean point = false;
83-
int v;
84-
while ((v = reader.read()) != -1) {
85-
char c = (char) v;
80+
while (iterator.hasNext()) {
81+
char c = iterator.peek();
8682
// number
8783
if (c >= '0' && c <= '9') {
8884
sb.append(c);
85+
iterator.next();
8986
}
9087
// point
9188
else if (c == '.') {
9289
if (point) {
93-
reader.unread(c);
9490
return Double.parseDouble(sb.toString());
9591
} else {
9692
point = true;
9793
sb.append(c);
94+
iterator.next();
9895
}
9996
}
10097
// other char
10198
else {
102-
reader.unread(c);
10399
return Double.parseDouble(sb.toString());
104100
}
105101
}
106102
return Double.parseDouble(sb.toString());
107103
}
108104

109-
private Token readSymbol(char first) throws IOException {
105+
private Token readSymbol(char first) {
110106
StringBuilder sb = new StringBuilder(String.valueOf(first));
111-
int v;
112-
while ((v = reader.read()) != -1) {
113-
char c = (char) v;
107+
while (iterator.hasNext()) {
108+
char c = iterator.peek();
114109
if (c >= 'a' && c <= 'z') {
115110
sb.append(c);
111+
iterator.next();
116112
} else {
117-
reader.unread(c);
118113
break;
119114
}
120115
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package top.nintha.json.util;
2+
3+
public interface Peekable<T> {
4+
/**
5+
* get an element, but not consume it.
6+
*/
7+
T peek();
8+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package top.nintha.json.util;
2+
3+
import java.util.Iterator;
4+
5+
public class TextCharIterator implements Peekable<Character>, Iterator<Character> {
6+
private final char[] chars;
7+
private int readIndex = 0;
8+
9+
public TextCharIterator(String text) {
10+
this.chars = text.toCharArray();
11+
}
12+
13+
@Override
14+
public boolean hasNext() {
15+
return readIndex < chars.length;
16+
}
17+
18+
@Override
19+
public Character next() {
20+
return hasNext() ? chars[readIndex++] : null;
21+
}
22+
23+
@Override
24+
public Character peek() {
25+
return chars[readIndex];
26+
}
27+
}

src/test/java/top/nintha/json/ParserTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,5 @@ void parseObject() {
8282
Assertions.assertEquals(0.0, object.get("number").asNumber());
8383
Assertions.assertTrue(object.get("array").asJsonArray().isEmpty());
8484
Assertions.assertEquals("hello", object.get("string").asString());
85-
86-
// System.out.println(object.toJson());
8785
}
8886
}

0 commit comments

Comments
 (0)