Inline character unescaping. This saves ~10% on the READER_LONG benchmark.

This commit is contained in:
Jesse Wilson 2011-12-25 07:09:46 +00:00
parent d7fbac0384
commit 8d5de3136c
2 changed files with 38 additions and 2 deletions

View File

@ -1145,9 +1145,23 @@ public class JsonReader implements Closeable {
if (pos + 4 > limit && !fillBuffer(4)) {
throw syntaxError("Unterminated escape sequence");
}
String hex = stringPool.get(buffer, pos, 4);
// Equivalent to Integer.parseInt(stringPool.get(buffer, pos, 4), 16);
char result = 0;
for (int i = pos, end = i + 4; i < end; i++) {
char c = buffer[i];
result <<= 4;
if (c >= '0' && c <= '9') {
result += (c - '0');
} else if (c >= 'a' && c <= 'f') {
result += (c - 'a' + 10);
} else if (c >= 'A' && c <= 'F') {
result += (c - 'A' + 10);
} else {
throw new NumberFormatException("\\u" + stringPool.get(buffer, pos, 4));
}
}
pos += 4;
return (char) Integer.parseInt(hex, 16);
return result;
case 't':
return '\t';

View File

@ -161,6 +161,28 @@ public final class JsonReaderTest extends TestCase {
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testUnescapingInvalidCharacters() throws IOException {
String json = "[\"\\u000g\"]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
try {
reader.nextString();
fail();
} catch (NumberFormatException expected) {
}
}
public void testUnescapingTruncatedCharacters() throws IOException {
String json = "[\"\\u000";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
try {
reader.nextString();
fail();
} catch (IOException expected) {
}
}
public void testIntegersWithFractionalPartSpecified() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[1.0,1.0,1.0]"));
reader.beginArray();