private JsonToken nextInObject(boolean firstElement) throws IOException { /* * Read delimiters. Either a comma/semicolon separating this and the * previous name-value pair, or a close brace to denote the end of the * object. */ if (firstElement) { /* Peek to see if this is the empty object. */ switch (nextNonWhitespace()) { case '}': pop(); return token = JsonToken.END_OBJECT; default: pos--; } } else { switch (nextNonWhitespace()) { case '}': pop(); return token = JsonToken.END_OBJECT; case ';': case ',': break; default: throw syntaxError("Unterminated object"); } } /* Read the name. */ int quote = nextNonWhitespace(); switch (quote) { case '\'': checkLenient(); // fall-through case '"': name = nextString((char) quote); break; default: checkLenient(); pos--; name = nextLiteral(false); if (name.isEmpty()) { throw syntaxError("Expected name"); } } replaceTop(JsonScope.DANGLING_NAME); return token = JsonToken.NAME; }
private JsonToken nextInArray(boolean firstElement) throws IOException { if (firstElement) { replaceTop(JsonScope.NONEMPTY_ARRAY); } else { /* Look for a comma before each element after the first element. */ switch (nextNonWhitespace()) { case ']': pop(); return token = JsonToken.END_ARRAY; case ';': checkLenient(); // fall-through case ',': break; default: throw syntaxError("Unterminated array"); } } switch (nextNonWhitespace()) { case ']': if (firstElement) { pop(); return token = JsonToken.END_ARRAY; } // fall-through to handle ",]" case ';': case ',': /* In lenient mode, a 0-length literal means 'null' */ checkLenient(); pos--; value = "null"; return token = JsonToken.NULL; default: pos--; return nextValue(); } }