Include line and column position in error messages.
This commit is contained in:
parent
4b042671af
commit
415437810a
|
@ -204,6 +204,14 @@ public final class JsonReader implements Closeable {
|
||||||
private int pos = 0;
|
private int pos = 0;
|
||||||
private int limit = 0;
|
private int limit = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Track the number of newlines and columns preceding the current buffer. To
|
||||||
|
* compute the line and column of a position in the buffer, compute the line
|
||||||
|
* and column in the buffer and add the preceding values.
|
||||||
|
*/
|
||||||
|
private int bufferStartLine;
|
||||||
|
private int bufferStartColumn;
|
||||||
|
|
||||||
private final List<JsonScope> stack = new ArrayList<JsonScope>();
|
private final List<JsonScope> stack = new ArrayList<JsonScope>();
|
||||||
{
|
{
|
||||||
push(JsonScope.EMPTY_DOCUMENT);
|
push(JsonScope.EMPTY_DOCUMENT);
|
||||||
|
@ -817,6 +825,16 @@ public final class JsonReader implements Closeable {
|
||||||
* false.
|
* false.
|
||||||
*/
|
*/
|
||||||
private boolean fillBuffer(int minimum) throws IOException {
|
private boolean fillBuffer(int minimum) throws IOException {
|
||||||
|
// Before clobbering the old characters, update where buffer starts
|
||||||
|
for (int i = 0; i < pos; i++) {
|
||||||
|
if (buffer[i] == '\n') {
|
||||||
|
bufferStartLine++;
|
||||||
|
bufferStartColumn = 0;
|
||||||
|
} else {
|
||||||
|
bufferStartColumn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (limit != pos) {
|
if (limit != pos) {
|
||||||
limit -= pos;
|
limit -= pos;
|
||||||
System.arraycopy(buffer, pos, buffer, 0, limit);
|
System.arraycopy(buffer, pos, buffer, 0, limit);
|
||||||
|
@ -835,6 +853,28 @@ public final class JsonReader implements Closeable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getLineNumber() {
|
||||||
|
int result = bufferStartLine;
|
||||||
|
for (int i = 0; i < pos; i++) {
|
||||||
|
if (buffer[i] == '\n') {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result + 1; // the first line is '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getColumnNumber() {
|
||||||
|
int result = bufferStartColumn;
|
||||||
|
for (int i = 0; i < pos; i++) {
|
||||||
|
if (buffer[i] == '\n') {
|
||||||
|
result = 0;
|
||||||
|
} else {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result + 1; // the first column is '1'
|
||||||
|
}
|
||||||
|
|
||||||
private int nextNonWhitespace() throws IOException {
|
private int nextNonWhitespace() throws IOException {
|
||||||
while (pos < limit || fillBuffer(1)) {
|
while (pos < limit || fillBuffer(1)) {
|
||||||
int c = buffer[pos++];
|
int c = buffer[pos++];
|
||||||
|
@ -1110,7 +1150,7 @@ public final class JsonReader implements Closeable {
|
||||||
* with this reader's content.
|
* with this reader's content.
|
||||||
*/
|
*/
|
||||||
private IOException syntaxError(String message) throws IOException {
|
private IOException syntaxError(String message) throws IOException {
|
||||||
throw new MalformedJsonException(message + " near " + getSnippet());
|
throw new MalformedJsonException(message + " @" + getLineNumber() + ":" + getColumnNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence getSnippet() {
|
private CharSequence getSnippet() {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.gson.stream;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.util.Arrays;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
public final class JsonReaderTest extends TestCase {
|
public final class JsonReaderTest extends TestCase {
|
||||||
|
@ -763,4 +764,35 @@ public final class JsonReaderTest extends TestCase {
|
||||||
} catch (IOException expected) {
|
} catch (IOException expected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testFailWithPosition() throws IOException {
|
||||||
|
JsonReader reader = new JsonReader(new StringReader("[\n\n\n\n\n0,}]"));
|
||||||
|
reader.beginArray();
|
||||||
|
reader.nextInt();
|
||||||
|
try {
|
||||||
|
reader.peek();
|
||||||
|
fail();
|
||||||
|
} catch (IOException expected) {
|
||||||
|
assertEquals("Expected literal value @6:3", expected.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFailWithPositionGreaterThanBufferSize() throws IOException {
|
||||||
|
String spaces = repeat(' ', 8192);
|
||||||
|
JsonReader reader = new JsonReader(new StringReader("[\n\n" + spaces + "\n\n\n0,}]"));
|
||||||
|
reader.beginArray();
|
||||||
|
reader.nextInt();
|
||||||
|
try {
|
||||||
|
reader.peek();
|
||||||
|
fail();
|
||||||
|
} catch (IOException expected) {
|
||||||
|
assertEquals("Expected literal value @6:3", expected.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String repeat(char c, int count) {
|
||||||
|
char[] array = new char[count];
|
||||||
|
Arrays.fill(array, c);
|
||||||
|
return new String(array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user