added buffering to boost performance
This commit is contained in:
@@ -8,7 +8,11 @@ import java.io.Reader;
|
||||
public class LookAheadTextInputStream extends InputStream {
|
||||
|
||||
private final Reader reader;
|
||||
private int currentByte;
|
||||
private char[] buffer = new char[1024];
|
||||
private int bufferFill = -1;
|
||||
private int cursor = -1;
|
||||
private int currentChar;
|
||||
|
||||
|
||||
public LookAheadTextInputStream(Reader reader) {
|
||||
this.reader = reader;
|
||||
@@ -17,12 +21,21 @@ public class LookAheadTextInputStream extends InputStream {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public int read() {
|
||||
int result = currentByte;
|
||||
currentByte = reader.read();
|
||||
return result;
|
||||
if (cursor > bufferFill) {
|
||||
return -1;
|
||||
} else if (cursor == bufferFill) {
|
||||
do {
|
||||
bufferFill = reader.read(buffer, 0, buffer.length) - 1;
|
||||
cursor = 0;
|
||||
} while(bufferFill == -1);
|
||||
currentChar = bufferFill == -2 ? -1 : buffer[0];
|
||||
} else {
|
||||
currentChar = buffer[++cursor];
|
||||
}
|
||||
return currentChar;
|
||||
}
|
||||
|
||||
public int getCurrentByte(){
|
||||
return currentByte;
|
||||
public int getCurrentByte() {
|
||||
return currentChar;
|
||||
}
|
||||
}
|
||||
|
@@ -27,10 +27,10 @@ public class JSONParser extends ValueParser {
|
||||
return c >= '0' && c <= '9' || c == '+' || c == '-' || c == '.' || c == 'e';
|
||||
}
|
||||
|
||||
private static int parseHex(LookAheadTextInputStream stream) {
|
||||
static int parseHex(LookAheadTextInputStream stream) {
|
||||
int result = 0;
|
||||
while (true) {
|
||||
int c = stream.getCurrentByte();
|
||||
int c = stream.getCurrentByte();
|
||||
while (c != -1) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
result = result << 4;
|
||||
result += (c - '0');
|
||||
@@ -43,7 +43,7 @@ public class JSONParser extends ValueParser {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
stream.read();
|
||||
c = stream.read();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -64,19 +64,19 @@ public class JSONParser extends ValueParser {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private final int parseId(LookAheadTextInputStream stream) {
|
||||
private int parseId(LookAheadTextInputStream stream) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean digitsStarted = false;
|
||||
boolean digitsEnded = false;
|
||||
while (true) {
|
||||
int b = stream.getCurrentByte();
|
||||
if(b == '(' ) {
|
||||
} else if(Character.isWhitespace(b)) {
|
||||
if(digitsStarted) digitsEnded = true;
|
||||
if (b == '(') {
|
||||
} else if (Character.isWhitespace(b)) {
|
||||
if (digitsStarted) digitsEnded = true;
|
||||
} else if (b < 0 || b == ')') {
|
||||
break;
|
||||
} else if (isDecimal(b)) {
|
||||
if(digitsEnded) {
|
||||
if (digitsEnded) {
|
||||
error(ParseException::new, "error parsing id");
|
||||
} else {
|
||||
digitsStarted = true;
|
||||
@@ -85,7 +85,7 @@ public class JSONParser extends ValueParser {
|
||||
}
|
||||
stream.read();
|
||||
}
|
||||
return Integer.valueOf(sb.toString());
|
||||
return Integer.parseInt(sb.toString());
|
||||
}
|
||||
|
||||
private String readString(LookAheadTextInputStream stream) {
|
||||
@@ -151,14 +151,15 @@ public class JSONParser extends ValueParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T extends RuntimeException> T error(Function<String, T> constructor, String fmt, Object ...args) {
|
||||
protected <T extends RuntimeException> T error(Function<String, T> constructor, String fmt, Object... args) {
|
||||
return constructor.apply(String.format("Error at line %d column %d: %s",
|
||||
currentLine, currentColumn, String.format(fmt, args)));
|
||||
currentLine, currentColumn, String.format(fmt, args)));
|
||||
}
|
||||
|
||||
public static Parser newInstance() {
|
||||
return new JSONParser();
|
||||
}
|
||||
|
||||
public static Parser newInstance(Value.Configuration cfg) {
|
||||
return new JSONParser(cfg);
|
||||
}
|
||||
@@ -192,6 +193,7 @@ public class JSONParser extends ValueParser {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
stream.read();
|
||||
|
||||
try {
|
||||
Integer currentId = null;
|
||||
@@ -204,13 +206,13 @@ public class JSONParser extends ValueParser {
|
||||
currentId = parseId(stream);
|
||||
} else if (c == '{') {
|
||||
Value newObject = beginObject();
|
||||
if(currentId != null) valueId(currentId, newObject);
|
||||
if (currentId != null) valueId(currentId, newObject);
|
||||
currentId = null;
|
||||
} else if (c == '}') {
|
||||
endObject();
|
||||
} else if (c == '[') {
|
||||
Value newArray = beginArray();
|
||||
if(currentId != null) valueId(currentId, newArray);
|
||||
if (currentId != null) valueId(currentId, newArray);
|
||||
currentId = null;
|
||||
} else if (c == ']') {
|
||||
endArray();
|
||||
@@ -246,7 +248,7 @@ public class JSONParser extends ValueParser {
|
||||
} else if (idMap != null && c == '$') {
|
||||
stream.read();
|
||||
String text = parseNumber(stream);
|
||||
valueReference(Integer.valueOf(text));
|
||||
valueReference(Integer.parseInt(text));
|
||||
continue;
|
||||
}
|
||||
stream.read();
|
||||
@@ -262,7 +264,7 @@ public class JSONParser extends ValueParser {
|
||||
}
|
||||
throw error(ParseException::new, "Missing '%c' token", c);
|
||||
}
|
||||
return WorthUtils.dynamicCast(stack.getFirst(), ArrayStackLevel.class).value.get(0);
|
||||
return ((ArrayStackLevel) stack.getFirst()).value.get(0);
|
||||
} catch (NumberFormatException e) {
|
||||
throw error(ParseException::new, e.getMessage());
|
||||
} finally {
|
||||
|
@@ -79,18 +79,4 @@ public class JBONTest {
|
||||
Assert.assertEquals(originalValue, binarySerializedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void hexTest() {
|
||||
String hex = "1F608";
|
||||
byte[] buffer = hex.getBytes();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
|
||||
Method method = JSONParser.class.getDeclaredMethod("parseHex", LookAheadTextInputStream.class);
|
||||
method.setAccessible(true);
|
||||
LookAheadTextInputStream ltis = new LookAheadTextInputStream(new InputStreamReader(bais));
|
||||
ltis.read();
|
||||
int result = (int) method.invoke(null, ltis);
|
||||
Assert.assertEquals((int) Integer.valueOf(hex, 16), result);
|
||||
}
|
||||
}
|
||||
|
@@ -228,11 +228,9 @@ public class JSONTest {
|
||||
String hex = "1F608";
|
||||
byte[] buffer = hex.getBytes();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
|
||||
Method method = JSONParser.class.getDeclaredMethod("parseHex", LookAheadTextInputStream.class);
|
||||
method.setAccessible(true);
|
||||
LookAheadTextInputStream ltis = new LookAheadTextInputStream(new InputStreamReader(bais));
|
||||
ltis.read();
|
||||
int result = (int) method.invoke(null, ltis);
|
||||
Assert.assertEquals((int) Integer.valueOf(hex, 16), result);
|
||||
int result = JSONParser.parseHex(ltis);
|
||||
Assert.assertEquals(Integer.parseInt(hex, 16), result);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user