Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a11c2f86 authored by Jesse Wilson's avatar Jesse Wilson Committed by Android (Google) Code Review
Browse files

Merge "Track line and column when parsing JSON."

parents 1a1d731c febae4ed
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -196,6 +196,12 @@ public final class JsonReader implements Closeable {
    private int pos = 0;
    private int limit = 0;

    /*
     * The offset of the first character in the buffer.
     */
    private int bufferStartLine = 1;
    private int bufferStartColumn = 1;

    private final List<JsonScope> stack = new ArrayList<JsonScope>();
    {
        push(JsonScope.EMPTY_DOCUMENT);
@@ -711,6 +717,16 @@ public final class JsonReader implements Closeable {
     * false.
     */
    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 = 1;
            } else {
                bufferStartColumn++;
            }
        }

        if (limit != pos) {
            limit -= pos;
            System.arraycopy(buffer, pos, buffer, 0, limit);
@@ -729,6 +745,28 @@ public final class JsonReader implements Closeable {
        return false;
    }

    private int getLineNumber() {
        int result = bufferStartLine;
        for (int i = 0; i < pos; i++) {
            if (buffer[i] == '\n') {
                result++;
            }
        }
        return result;
    }

    private int getColumnNumber() {
        int result = bufferStartColumn;
        for (int i = 0; i < pos; i++) {
            if (buffer[i] == '\n') {
                result = 1;
            } else {
                result++;
            }
        }
        return result;
    }

    private int nextNonWhitespace() throws IOException {
        while (pos < limit || fillBuffer(1)) {
            int c = buffer[pos++];
@@ -1107,7 +1145,8 @@ public final class JsonReader implements Closeable {
     * with this reader's content.
     */
    private IOException syntaxError(String message) throws IOException {
        throw new MalformedJsonException(message + " near " + getSnippet());
        throw new MalformedJsonException(message
                + " at line " + getLineNumber() + " column " + getColumnNumber());
    }

    private CharSequence getSnippet() {
+29 −0
Original line number Diff line number Diff line
@@ -856,4 +856,33 @@ public final class JsonReaderTest extends TestCase {
        } catch (IOException expected) {
        }
    }

    public void testFailWithPosition() throws IOException {
        testFailWithPosition("Expected literal value at line 6 column   3",
                "[\n\n\n\n\n0,}]");
    }

    public void testFailWithPositionGreaterThanBufferSize() throws IOException {
        String spaces = repeat(' ', 8192);
        testFailWithPosition("Expected literal value at line 6 column 3",
                "[\n\n" + spaces + "\n\n\n0,}]");
    }

    private void testFailWithPosition(String message, String json) throws IOException {
        JsonReader reader = new JsonReader(new StringReader(json));
        reader.beginArray();
        reader.nextInt();
        try {
            reader.peek();
            fail();
        } catch (IOException expected) {
            assertEquals(message, expected.getMessage());
        }
    }

    private String repeat(char c, int count) {
        char[] array = new char[count];
        Arrays.fill(array, c);
        return new String(array);
    }
}