/** * Overridden to provide developer readable "JsonPath" representation * of the context. */ @Override public String toString() { StringBuilder sb = new StringBuilder(64); switch (_type) { case TYPE_ROOT: sb.append("/"); break; case TYPE_ARRAY: sb.append('['); sb.append(getCurrentIndex()); sb.append(']'); break; case TYPE_OBJECT: default: sb.append('{'); String currentName = currentName(); if (currentName != null) { sb.append('"'); CharTypes.appendQuoted(sb, currentName); sb.append('"'); } else { sb.append('?'); } sb.append('}'); break; } return sb.toString(); }
/** * Method for skipping contents of an input line; usually for CPP * and YAML style comments. */ private final void _skipLine() throws IOException { // Ok: need to find EOF or linefeed final int[] codes = CharTypes.getInputCodeComment(); while ((_inputPtr < _inputEnd) || _loadMore()) { int i = (int) _inputBuffer[_inputPtr++] & 0xFF; int code = codes[i]; if (code != 0) { switch (code) { case INT_LF: ++_currInputRow; _currInputRowStart = _inputPtr; return; case INT_CR: _skipCR(); return; case '*': // nop for these comments break; case 2: // 2-byte UTF _skipUtf8_2(); break; case 3: // 3-byte UTF _skipUtf8_3(); break; case 4: // 4-byte UTF _skipUtf8_4(i); break; default: // e.g. -1 if (code < 0) { // Is this good enough error message? _reportInvalidChar(i); } } } } }
private final void _skipCComment() throws IOException { // Need to be UTF-8 aware here to decode content (for skipping) final int[] codes = CharTypes.getInputCodeComment(); int i = _inputData.readUnsignedByte(); // Ok: need the matching '*/' main_loop: while (true) { int code = codes[i]; if (code != 0) { switch (code) { case '*': i = _inputData.readUnsignedByte(); if (i == INT_SLASH) { return; } continue main_loop; case INT_LF: case INT_CR: ++_currInputRow; break; case 2: // 2-byte UTF _skipUtf8_2(); break; case 3: // 3-byte UTF _skipUtf8_3(); break; case 4: // 4-byte UTF _skipUtf8_4(); break; default: // e.g. -1 // Is this good enough error message? _reportInvalidChar(i); } } i = _inputData.readUnsignedByte(); } }
/** * Method for skipping contents of an input line; usually for CPP * and YAML style comments. */ private final void _skipLine() throws IOException { // Ok: need to find EOF or linefeed final int[] codes = CharTypes.getInputCodeComment(); while (true) { int i = _inputData.readUnsignedByte(); int code = codes[i]; if (code != 0) { switch (code) { case INT_LF: case INT_CR: ++_currInputRow; return; case '*': // nop for these comments break; case 2: // 2-byte UTF _skipUtf8_2(); break; case 3: // 3-byte UTF _skipUtf8_3(); break; case 4: // 4-byte UTF _skipUtf8_4(); break; default: // e.g. -1 if (code < 0) { // Is this good enough error message? _reportInvalidChar(i); } } } } }
/** * Method called when we see non-white space character other * than double quote, when expecting a field name. * In standard mode will just throw an exception; but * in non-standard modes may be able to parse name. */ private JsonToken _handleOddName(int ch) throws IOException { // First: may allow single quotes switch (ch) { case '#': // Careful, since this may alternatively be leading char of // unquoted name... if (JsonParser.Feature.ALLOW_YAML_COMMENTS.enabledIn(_features)) { return _finishHashComment(MINOR_FIELD_LEADING_WS); } break; case '/': return _startSlashComment(MINOR_FIELD_LEADING_WS); case '\'': if (isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { return _finishAposName(0, 0, 0); } break; case ']': // for better error reporting... return _closeArrayScope(); } // allow unquoted names if feature enabled: if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { // !!! TODO: Decode UTF-8 characters properly... // char c = (char) _decodeCharForError(ch); char c = (char) ch; _reportUnexpectedChar(c, "was expecting double-quote to start field name"); } // Also: note that although we use a different table here, it does NOT handle UTF-8 // decoding. It'll just pass those high-bit codes as acceptable for later decoding. final int[] codes = CharTypes.getInputCodeUtf8JsNames(); // Also: must start with a valid character... if (codes[ch] != 0) { _reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); } return _finishUnquotedName(0, ch, 1); }
public void testQuoting() { StringBuilder sb = new StringBuilder(); CharTypes.appendQuoted(sb, "\n"); assertEquals("\\n", sb.toString()); sb = new StringBuilder(); CharTypes.appendQuoted(sb, "\u0000"); assertEquals("\\u0000", sb.toString()); }
private void _skipCppComment() { int[] arrayOfInt = CharTypes.getInputCodeComment(); while ((this._inputPtr < this._inputEnd) || (loadMore())) { byte[] arrayOfByte = this._inputBuffer; int i = this._inputPtr; this._inputPtr = (i + 1); int j = 0xFF & arrayOfByte[i]; int k = arrayOfInt[j]; if (k != 0) switch (k) { default: break; case 10: _skipLF(); return; case 13: _skipCR(); return; case 42: break; case 2: _skipUtf8_2(j); break; case 3: _skipUtf8_3(j); break; case 4: _skipUtf8_4(j); continue; _reportInvalidChar(j); } } }
public final String toString() { StringBuilder localStringBuilder = new StringBuilder(64); switch (this._type) { default: break; case 0: localStringBuilder.append("/"); break; case 1: localStringBuilder.append('['); localStringBuilder.append(getCurrentIndex()); localStringBuilder.append(']'); break; case 2: localStringBuilder.append('{'); if (this._currentName != null) { localStringBuilder.append('"'); CharTypes.appendQuoted(localStringBuilder, this._currentName); localStringBuilder.append('"'); } else { localStringBuilder.append('?'); } localStringBuilder.append('}'); } return localStringBuilder.toString(); }
protected final void _finishString() { int i = this._inputPtr; int j = this._inputEnd; if (i < j) { int[] arrayOfInt = CharTypes.getInputCodeLatin1(); int m = arrayOfInt.length; do { int n = this._inputBuffer[i]; if ((n < m) && (arrayOfInt[n] != 0)) { if (n != 34) break; TextBuffer localTextBuffer2 = this._textBuffer; char[] arrayOfChar2 = this._inputBuffer; int i1 = this._inputPtr; localTextBuffer2.resetWithShared(arrayOfChar2, i1, i - i1); this._inputPtr = (i + 1); return; } i++; } while (i < j); } TextBuffer localTextBuffer1 = this._textBuffer; char[] arrayOfChar1 = this._inputBuffer; int k = this._inputPtr; localTextBuffer1.resetWithCopy(arrayOfChar1, k, i - k); this._inputPtr = i; _finishString2(); }
protected final String _parseApostropheFieldName() { int i = this._inputPtr; int j = this._hashSeed; int k = this._inputEnd; if (i < k) { int[] arrayOfInt = CharTypes.getInputCodeLatin1(); int n = arrayOfInt.length; do { int i1 = this._inputBuffer[i]; if (i1 == 39) { int i2 = this._inputPtr; this._inputPtr = (i + 1); return this._symbols.findSymbol(this._inputBuffer, i2, i - i2, j); } if ((i1 < n) && (arrayOfInt[i1] != 0)) break; j = i1 + j * 33; i++; } while (i < k); } int m = this._inputPtr; this._inputPtr = i; return _parseFieldName2(m, j, 39); }
protected final String _parseFieldName(int paramInt) { if (paramInt != 34) return _handleUnusualFieldName(paramInt); int i = this._inputPtr; int j = this._hashSeed; int k = this._inputEnd; if (i < k) { int[] arrayOfInt = CharTypes.getInputCodeLatin1(); int n = arrayOfInt.length; do { int i1 = this._inputBuffer[i]; if ((i1 < n) && (arrayOfInt[i1] != 0)) { if (i1 != 34) break; int i2 = this._inputPtr; this._inputPtr = (i + 1); return this._symbols.findSymbol(this._inputBuffer, i2, i - i2, j); } j = i1 + j * 33; i++; } while (i < k); } int m = this._inputPtr; this._inputPtr = i; return _parseFieldName2(m, j, 34); }
/** * Method for skipping contents of an input line; usually for CPP * and YAML style comments. */ private final void _skipLine() throws IOException { // Ok: need to find EOF or linefeed final int[] codes = CharTypes.getInputCodeComment(); while ((_inputPtr < _inputEnd) || loadMore()) { int i = (int) _inputBuffer[_inputPtr++] & 0xFF; int code = codes[i]; if (code != 0) { switch (code) { case INT_LF: ++_currInputRow; _currInputRowStart = _inputPtr; return; case INT_CR: _skipCR(); return; case '*': // nop for these comments break; case 2: // 2-byte UTF _skipUtf8_2(i); break; case 3: // 3-byte UTF _skipUtf8_3(i); break; case 4: // 4-byte UTF _skipUtf8_4(i); break; default: // e.g. -1 if (code < 0) { // Is this good enough error message? _reportInvalidChar(i); } } } } }
/** * Overridden to provide developer readable "JsonPath" representation * of the context. */ @Override public String toString() { StringBuilder sb = new StringBuilder(64); switch (_type) { case TYPE_ROOT: sb.append("/"); break; case TYPE_ARRAY: sb.append('['); sb.append(getCurrentIndex()); sb.append(']'); break; case TYPE_OBJECT: sb.append('{'); if (_currentName != null) { sb.append('"'); CharTypes.appendQuoted(sb, _currentName); sb.append('"'); } else { sb.append('?'); } sb.append('}'); break; } return sb.toString(); }
private void _skipCppComment() throws IOException, JsonParseException { // Ok: need to find EOF or linefeed final int[] codes = CharTypes.getInputCodeComment(); while ((_inputPtr < _inputEnd) || loadMore()) { int i = (int) _inputBuffer[_inputPtr++] & 0xFF; int code = codes[i]; if (code != 0) { switch (code) { case INT_LF: _skipLF(); return; case INT_CR: _skipCR(); return; case INT_ASTERISK: // nop for these comments break; case 2: // 2-byte UTF _skipUtf8_2(i); break; case 3: // 3-byte UTF _skipUtf8_3(i); break; case 4: // 4-byte UTF _skipUtf8_4(i); break; default: // e.g. -1 // Is this good enough error message? _reportInvalidChar(i); } } } }
@Override protected void _finishString() throws IOException, JsonParseException { /* First: let's try to see if we have simple String value: one * that does not cross input buffer boundary, and does not * contain escape sequences. */ int ptr = _inputPtr; final int inputLen = _inputEnd; if (ptr < inputLen) { final int[] codes = CharTypes.getInputCodeLatin1(); final int maxCode = codes.length; do { int ch = _inputBuffer[ptr]; if (ch < maxCode && codes[ch] != 0) { if (ch == '"') { _textBuffer.resetWithShared(_inputBuffer, _inputPtr, (ptr-_inputPtr)); _inputPtr = ptr+1; // Yes, we got it all return; } break; } ++ptr; } while (ptr < inputLen); } /* Either ran out of input, or bumped into an escape * sequence... */ _textBuffer.resetWithCopy(_inputBuffer, _inputPtr, (ptr-_inputPtr)); _inputPtr = ptr; _finishString2(); }
/** * Method called when we see non-white space character other * than double quote, when expecting a field name. * In standard mode will just throw an exception; but * in non-standard modes may be able to parse name. */ protected String _handleOddName(int ch) throws IOException { // First: may allow single quotes if (ch == INT_APOS && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { return _parseAposName(); } // Allow unquoted names if feature enabled: if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { char c = (char) _decodeCharForError(ch); _reportUnexpectedChar(c, "was expecting double-quote to start field name"); } /* Also: note that although we use a different table here, * it does NOT handle UTF-8 decoding. It'll just pass those * high-bit codes as acceptable for later decoding. */ final int[] codes = CharTypes.getInputCodeUtf8JsNames(); // Also: must start with a valid character... if (codes[ch] != 0) { _reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); } // Ok, now; instead of ultra-optimizing parsing here (as with regular // JSON names), let's just use the generic "slow" variant. // Can measure its impact later on if need be. int[] quads = _quadBuffer; int qlen = 0; int currQuad = 0; int currQuadBytes = 0; while (true) { // Ok, we have one more byte to add at any rate: if (currQuadBytes < 4) { ++currQuadBytes; currQuad = (currQuad << 8) | ch; } else { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; currQuad = ch; currQuadBytes = 1; } if (_inputPtr >= _inputEnd) { if (!_loadMore()) { _reportInvalidEOF(" in field name", JsonToken.FIELD_NAME); } } ch = _inputBuffer[_inputPtr] & 0xFF; if (codes[ch] != 0) { break; } ++_inputPtr; } if (currQuadBytes > 0) { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; } String name = _symbols.findName(quads, qlen); if (name == null) { name = addName(quads, qlen, currQuadBytes); } return name; }
private final void _skipCComment() throws IOException { // Need to be UTF-8 aware here to decode content (for skipping) final int[] codes = CharTypes.getInputCodeComment(); // Ok: need the matching '*/' main_loop: while ((_inputPtr < _inputEnd) || _loadMore()) { int i = (int) _inputBuffer[_inputPtr++] & 0xFF; int code = codes[i]; if (code != 0) { switch (code) { case '*': if (_inputPtr >= _inputEnd && !_loadMore()) { break main_loop; } if (_inputBuffer[_inputPtr] == INT_SLASH) { ++_inputPtr; return; } break; case INT_LF: ++_currInputRow; _currInputRowStart = _inputPtr; break; case INT_CR: _skipCR(); break; case 2: // 2-byte UTF _skipUtf8_2(); break; case 3: // 3-byte UTF _skipUtf8_3(); break; case 4: // 4-byte UTF _skipUtf8_4(i); break; default: // e.g. -1 // Is this good enough error message? _reportInvalidChar(i); } } } _reportInvalidEOF(" in a comment", null); }
@Override protected char _decodeEscaped() throws IOException { if (_inputPtr >= _inputEnd) { if (!_loadMore()) { _reportInvalidEOF(" in character escape sequence", JsonToken.VALUE_STRING); } } int c = (int) _inputBuffer[_inputPtr++]; switch (c) { // First, ones that are mapped case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; // And these are to be returned as they are case '"': case '/': case '\\': return (char) c; case 'u': // and finally hex-escaped break; default: return _handleUnrecognizedCharacterEscape((char) _decodeCharForError(c)); } // Ok, a hex escape. Need 4 characters int value = 0; for (int i = 0; i < 4; ++i) { if (_inputPtr >= _inputEnd) { if (!_loadMore()) { _reportInvalidEOF(" in character escape sequence", JsonToken.VALUE_STRING); } } int ch = (int) _inputBuffer[_inputPtr++]; int digit = CharTypes.charToHex(ch); if (digit < 0) { _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; } return (char) value; }
/** * Method called when we see non-white space character other * than double quote, when expecting a field name. * In standard mode will just throw an exception; but * in non-standard modes may be able to parse name. */ protected String _handleOddName(int ch) throws IOException { if (ch == '\'' && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { return _parseAposName(); } if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { char c = (char) _decodeCharForError(ch); _reportUnexpectedChar(c, "was expecting double-quote to start field name"); } /* Also: note that although we use a different table here, * it does NOT handle UTF-8 decoding. It'll just pass those * high-bit codes as acceptable for later decoding. */ final int[] codes = CharTypes.getInputCodeUtf8JsNames(); // Also: must start with a valid character... if (codes[ch] != 0) { _reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); } /* Ok, now; instead of ultra-optimizing parsing here (as with * regular JSON names), let's just use the generic "slow" * variant. Can measure its impact later on if need be */ int[] quads = _quadBuffer; int qlen = 0; int currQuad = 0; int currQuadBytes = 0; while (true) { // Ok, we have one more byte to add at any rate: if (currQuadBytes < 4) { ++currQuadBytes; currQuad = (currQuad << 8) | ch; } else { if (qlen >= quads.length) { _quadBuffer = quads = _growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; currQuad = ch; currQuadBytes = 1; } ch = _inputData.readUnsignedByte(); if (codes[ch] != 0) { break; } } // Note: we must "push back" character read here for future consumption _nextByte = ch; if (currQuadBytes > 0) { if (qlen >= quads.length) { _quadBuffer = quads = _growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; } String name = _symbols.findName(quads, qlen); if (name == null) { name = addName(quads, qlen, currQuadBytes); } return name; }
@Override protected char _decodeEscaped() throws IOException { int c = _inputData.readUnsignedByte(); switch (c) { // First, ones that are mapped case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; // And these are to be returned as they are case '"': case '/': case '\\': return (char) c; case 'u': // and finally hex-escaped break; default: return _handleUnrecognizedCharacterEscape((char) _decodeCharForError(c)); } // Ok, a hex escape. Need 4 characters int value = 0; for (int i = 0; i < 4; ++i) { int ch = _inputData.readUnsignedByte(); int digit = CharTypes.charToHex(ch); if (digit < 0) { _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; } return (char) value; }
@Override protected char _decodeEscaped() throws IOException { if (_inputPtr >= _inputEnd) { if (!_loadMore()) { _reportInvalidEOF(" in character escape sequence", JsonToken.VALUE_STRING); } } char c = _inputBuffer[_inputPtr++]; switch ((int) c) { // First, ones that are mapped case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; // And these are to be returned as they are case '"': case '/': case '\\': return c; case 'u': // and finally hex-escaped break; default: return _handleUnrecognizedCharacterEscape(c); } // Ok, a hex escape. Need 4 characters int value = 0; for (int i = 0; i < 4; ++i) { if (_inputPtr >= _inputEnd) { if (!_loadMore()) { _reportInvalidEOF(" in character escape sequence", JsonToken.VALUE_STRING); } } int ch = (int) _inputBuffer[_inputPtr++]; int digit = CharTypes.charToHex(ch); if (digit < 0) { _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; } return (char) value; }
/** * Parsing of optionally supported non-standard "unquoted" names: names without * either double-quotes or apostrophes surrounding them. * Unlike other */ private JsonToken _finishUnquotedName(int qlen, int currQuad, int currQuadBytes) throws IOException { int[] quads = _quadBuffer; final int[] codes = CharTypes.getInputCodeUtf8JsNames(); // Ok, now; instead of ultra-optimizing parsing here (as with regular JSON names), // let's just use the generic "slow" variant. Can measure its impact later on if need be. while (true) { if (_inputPtr >= _inputEnd) { _quadLength = qlen; _pending32 = currQuad; _pendingBytes = currQuadBytes; _minorState = MINOR_FIELD_UNQUOTED_NAME; return (_currToken = JsonToken.NOT_AVAILABLE); } int ch = _inputBuffer[_inputPtr] & 0xFF; if (codes[ch] != 0) { break; } ++_inputPtr; // Ok, we have one more byte to add at any rate: if (currQuadBytes < 4) { ++currQuadBytes; currQuad = (currQuad << 8) | ch; } else { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; currQuad = ch; currQuadBytes = 1; } } if (currQuadBytes > 0) { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; } String name = _symbols.findName(quads, qlen); if (name == null) { name = _addName(quads, qlen, currQuadBytes); } return _fieldComplete(name); }
private int _decodeSplitEscaped(int value, int bytesRead) throws IOException { if (_inputPtr >= _inputEnd) { _quoted32 = value; _quotedDigits = bytesRead; return -1; } int c = _inputBuffer[_inputPtr++]; if (bytesRead == -1) { // expecting first char after backslash switch (c) { // First, ones that are mapped case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; // And these are to be returned as they are case '"': case '/': case '\\': return c; case 'u': // and finally hex-escaped break; default: { // !!! TODO: Decode UTF-8 characters properly... // char ch = (char) _decodeCharForError(c); char ch = (char) c; return _handleUnrecognizedCharacterEscape(ch); } } if (_inputPtr >= _inputEnd) { _quotedDigits = 0; _quoted32 = 0; return -1; } c = _inputBuffer[_inputPtr++]; bytesRead = 0; } c &= 0xFF; while (true) { int digit = CharTypes.charToHex(c); if (digit < 0) { _reportUnexpectedChar(c, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; if (++bytesRead == 4) { return value; } if (_inputPtr >= _inputEnd) { _quotedDigits = bytesRead; _quoted32 = value; return -1; } c = _inputBuffer[_inputPtr++] & 0xFF; } }
protected static void appendQuoted(StringBuilder paramStringBuilder, String paramString) { paramStringBuilder.append('"'); CharTypes.appendQuoted(paramStringBuilder, paramString); paramStringBuilder.append('"'); }
private void _skipCComment() { int[] arrayOfInt = CharTypes.getInputCodeComment(); while ((this._inputPtr < this._inputEnd) || (loadMore())) { byte[] arrayOfByte = this._inputBuffer; int i = this._inputPtr; this._inputPtr = (i + 1); int j = 0xFF & arrayOfByte[i]; int k = arrayOfInt[j]; if (k != 0) switch (k) { default: break; case 42: if ((this._inputPtr >= this._inputEnd) && (!loadMore())) break label216; if (this._inputBuffer[this._inputPtr] == 47) { this._inputPtr = (1 + this._inputPtr); return; } break; case 10: _skipLF(); break; case 13: _skipCR(); break; case 2: _skipUtf8_2(j); break; case 3: _skipUtf8_3(j); break; case 4: _skipUtf8_4(j); continue; _reportInvalidChar(j); } } label216: _reportInvalidEOF(" in a comment"); }
protected final char _decodeEscaped() { if ((this._inputPtr >= this._inputEnd) && (!loadMore())) _reportInvalidEOF(" in character escape sequence"); byte[] arrayOfByte1 = this._inputBuffer; int i = this._inputPtr; this._inputPtr = (i + 1); int j = arrayOfByte1[i]; switch (j) { default: break; case 98: return '\b'; case 116: return '\t'; case 110: return '\n'; case 102: return '\f'; case 114: return '\r'; case 34: case 47: case 92: return (char)j; case 117: break; } return _handleUnrecognizedCharacterEscape((char)_decodeCharForError(j)); int k = 0; for (int m = 0; m < 4; m++) { if ((this._inputPtr >= this._inputEnd) && (!loadMore())) _reportInvalidEOF(" in character escape sequence"); byte[] arrayOfByte2 = this._inputBuffer; int n = this._inputPtr; this._inputPtr = (n + 1); int i1 = arrayOfByte2[n]; int i2 = CharTypes.charToHex(i1); if (i2 < 0) _reportUnexpectedChar(i1, "expected a hex-digit for character escape sequence"); k = i2 | k << 4; } return (char)k; }
protected final Name _handleUnusualFieldName(int paramInt) { if ((paramInt == 39) && (isEnabled(JsonParser.Feature.ALLOW_SINGLE_QUOTES))) return _parseApostropheFieldName(); if (!isEnabled(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)) _reportUnexpectedChar(paramInt, "was expecting double-quote to start field name"); int[] arrayOfInt1 = CharTypes.getInputCodeUtf8JsNames(); if (arrayOfInt1[paramInt] != 0) _reportUnexpectedChar(paramInt, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); Object localObject = this._quadBuffer; int i = 0; int j = 0; int k = 0; while (true) { if (k < 4) { k++; j = paramInt | j << 8; } else { if (i >= localObject.length) { int[] arrayOfInt3 = growArrayBy((int[])localObject, localObject.length); localObject = arrayOfInt3; this._quadBuffer = arrayOfInt3; } int m = i; i++; localObject[m] = j; j = paramInt; k = 1; } if ((this._inputPtr >= this._inputEnd) && (!loadMore())) _reportInvalidEOF(" in field name"); paramInt = 0xFF & this._inputBuffer[this._inputPtr]; if (arrayOfInt1[paramInt] != 0) break; this._inputPtr = (1 + this._inputPtr); } if (k > 0) { if (i >= localObject.length) { int[] arrayOfInt2 = growArrayBy((int[])localObject, localObject.length); localObject = arrayOfInt2; this._quadBuffer = arrayOfInt2; } int n = i; i++; localObject[n] = j; } Name localName1 = this._symbols.findName((int[])localObject, i); Name localName2 = localName1; if (localName1 == null) localName2 = addName((int[])localObject, i, k); return localName2; }
protected final char _decodeEscaped() { if ((this._inputPtr >= this._inputEnd) && (!loadMore())) _reportInvalidEOF(" in character escape sequence"); char[] arrayOfChar1 = this._inputBuffer; int i = this._inputPtr; this._inputPtr = (i + 1); char c = arrayOfChar1[i]; switch (c) { default: break; case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; case '"': case '/': case '\\': return c; case 'u': break; } return _handleUnrecognizedCharacterEscape(c); int j = 0; for (int k = 0; k < 4; k++) { if ((this._inputPtr >= this._inputEnd) && (!loadMore())) _reportInvalidEOF(" in character escape sequence"); char[] arrayOfChar2 = this._inputBuffer; int m = this._inputPtr; this._inputPtr = (m + 1); int n = arrayOfChar2[m]; int i1 = CharTypes.charToHex(n); if (i1 < 0) _reportUnexpectedChar(n, "expected a hex-digit for character escape sequence"); j = i1 | j << 4; } return (char)j; }
protected final String _handleUnusualFieldName(int paramInt) { if ((paramInt == 39) && (isEnabled(JsonParser.Feature.ALLOW_SINGLE_QUOTES))) return _parseApostropheFieldName(); if (!isEnabled(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)) _reportUnexpectedChar(paramInt, "was expecting double-quote to start field name"); int[] arrayOfInt = CharTypes.getInputCodeLatin1JsNames(); int i = arrayOfInt.length; boolean bool; if (paramInt < i) { if ((arrayOfInt[paramInt] == 0) && ((paramInt < 48) || (paramInt > 57))) bool = true; else bool = false; } else bool = Character.isJavaIdentifierPart((char)paramInt); if (!bool) _reportUnexpectedChar(paramInt, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); int j = this._inputPtr; int k = this._hashSeed; int m = this._inputEnd; if (j < m) do { int i1 = this._inputBuffer[j]; if (i1 < i) { if (arrayOfInt[i1] != 0) { int i3 = -1 + this._inputPtr; this._inputPtr = j; return this._symbols.findSymbol(this._inputBuffer, i3, j - i3, k); } } else if (!Character.isJavaIdentifierPart(i1)) { int i2 = -1 + this._inputPtr; this._inputPtr = j; return this._symbols.findSymbol(this._inputBuffer, i2, j - i2, k); } k = i1 + k * 33; j++; } while (j < m); int n = -1 + this._inputPtr; this._inputPtr = j; return _parseUnusualFieldName2(n, k, arrayOfInt); }
/** * Method called when we see non-white space character other * than double quote, when expecting a field name. * In standard mode will just throw an expection; but * in non-standard modes may be able to parse name. */ protected Name _handleOddName(int ch) throws IOException { // [JACKSON-173]: allow single quotes if (ch == '\'' && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { return _parseAposName(); } // [JACKSON-69]: allow unquoted names if feature enabled: if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { _reportUnexpectedChar(ch, "was expecting double-quote to start field name"); } /* Also: note that although we use a different table here, * it does NOT handle UTF-8 decoding. It'll just pass those * high-bit codes as acceptable for later decoding. */ final int[] codes = CharTypes.getInputCodeUtf8JsNames(); // Also: must start with a valid character... if (codes[ch] != 0) { _reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); } /* Ok, now; instead of ultra-optimizing parsing here (as with * regular JSON names), let's just use the generic "slow" * variant. Can measure its impact later on if need be */ int[] quads = _quadBuffer; int qlen = 0; int currQuad = 0; int currQuadBytes = 0; while (true) { // Ok, we have one more byte to add at any rate: if (currQuadBytes < 4) { ++currQuadBytes; currQuad = (currQuad << 8) | ch; } else { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; currQuad = ch; currQuadBytes = 1; } if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in field name"); } } ch = _inputBuffer[_inputPtr] & 0xFF; if (codes[ch] != 0) { break; } ++_inputPtr; } if (currQuadBytes > 0) { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; } Name name = _symbols.findName(quads, qlen); if (name == null) { name = addName(quads, qlen, currQuadBytes); } return name; }
private final void _skipCComment() throws IOException { // Need to be UTF-8 aware here to decode content (for skipping) final int[] codes = CharTypes.getInputCodeComment(); // Ok: need the matching '*/' main_loop: while ((_inputPtr < _inputEnd) || loadMore()) { int i = (int) _inputBuffer[_inputPtr++] & 0xFF; int code = codes[i]; if (code != 0) { switch (code) { case '*': if (_inputPtr >= _inputEnd && !loadMore()) { break main_loop; } if (_inputBuffer[_inputPtr] == INT_SLASH) { ++_inputPtr; return; } break; case INT_LF: ++_currInputRow; _currInputRowStart = _inputPtr; break; case INT_CR: _skipCR(); break; case 2: // 2-byte UTF _skipUtf8_2(i); break; case 3: // 3-byte UTF _skipUtf8_3(i); break; case 4: // 4-byte UTF _skipUtf8_4(i); break; default: // e.g. -1 // Is this good enough error message? _reportInvalidChar(i); } } } _reportInvalidEOF(" in a comment"); }
@Override protected char _decodeEscaped() throws IOException { if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in character escape sequence"); } } int c = (int) _inputBuffer[_inputPtr++]; switch ((int) c) { // First, ones that are mapped case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; // And these are to be returned as they are case '"': case '/': case '\\': return (char) c; case 'u': // and finally hex-escaped break; default: return _handleUnrecognizedCharacterEscape((char) _decodeCharForError(c)); } // Ok, a hex escape. Need 4 characters int value = 0; for (int i = 0; i < 4; ++i) { if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in character escape sequence"); } } int ch = (int) _inputBuffer[_inputPtr++]; int digit = CharTypes.charToHex(ch); if (digit < 0) { _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; } return (char) value; }
@Override protected char _decodeEscaped() throws IOException { if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in character escape sequence"); } } char c = _inputBuffer[_inputPtr++]; switch ((int) c) { // First, ones that are mapped case 'b': return '\b'; case 't': return '\t'; case 'n': return '\n'; case 'f': return '\f'; case 'r': return '\r'; // And these are to be returned as they are case '"': case '/': case '\\': return c; case 'u': // and finally hex-escaped break; default: return _handleUnrecognizedCharacterEscape(c); } // Ok, a hex escape. Need 4 characters int value = 0; for (int i = 0; i < 4; ++i) { if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in character escape sequence"); } } int ch = (int) _inputBuffer[_inputPtr++]; int digit = CharTypes.charToHex(ch); if (digit < 0) { _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; } return (char) value; }
/** * Method called when we see non-white space character other * than double quote, when expecting a field name. * In standard mode will just throw an expection; but * in non-standard modes may be able to parse name. */ protected Name _handleUnusualFieldName(int ch) throws IOException, JsonParseException { // [JACKSON-173]: allow single quotes if (ch == INT_APOSTROPHE && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { return _parseApostropheFieldName(); } // [JACKSON-69]: allow unquoted names if feature enabled: if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { _reportUnexpectedChar(ch, "was expecting double-quote to start field name"); } /* Also: note that although we use a different table here, * it does NOT handle UTF-8 decoding. It'll just pass those * high-bit codes as acceptable for later decoding. */ final int[] codes = CharTypes.getInputCodeUtf8JsNames(); // Also: must start with a valid character... if (codes[ch] != 0) { _reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); } /* Ok, now; instead of ultra-optimizing parsing here (as with * regular JSON names), let's just use the generic "slow" * variant. Can measure its impact later on if need be */ int[] quads = _quadBuffer; int qlen = 0; int currQuad = 0; int currQuadBytes = 0; while (true) { // Ok, we have one more byte to add at any rate: if (currQuadBytes < 4) { ++currQuadBytes; currQuad = (currQuad << 8) | ch; } else { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; currQuad = ch; currQuadBytes = 1; } if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in field name"); } } ch = _inputBuffer[_inputPtr] & 0xFF; if (codes[ch] != 0) { break; } ++_inputPtr; } if (currQuadBytes > 0) { if (qlen >= quads.length) { _quadBuffer = quads = growArrayBy(quads, quads.length); } quads[qlen++] = currQuad; } Name name = _symbols.findName(quads, qlen); if (name == null) { name = addName(quads, qlen, currQuadBytes); } return name; }
private void _skipCComment() throws IOException, JsonParseException { // Need to be UTF-8 aware here to decode content (for skipping) final int[] codes = CharTypes.getInputCodeComment(); // Ok: need the matching '*/' main_loop: while ((_inputPtr < _inputEnd) || loadMore()) { int i = (int) _inputBuffer[_inputPtr++] & 0xFF; int code = codes[i]; if (code != 0) { switch (code) { case INT_ASTERISK: if (_inputPtr >= _inputEnd && !loadMore()) { break main_loop; } if (_inputBuffer[_inputPtr] == INT_SLASH) { ++_inputPtr; return; } break; case INT_LF: _skipLF(); break; case INT_CR: _skipCR(); break; case 2: // 2-byte UTF _skipUtf8_2(i); break; case 3: // 3-byte UTF _skipUtf8_3(i); break; case 4: // 4-byte UTF _skipUtf8_4(i); break; default: // e.g. -1 // Is this good enough error message? _reportInvalidChar(i); } } } _reportInvalidEOF(" in a comment"); }
@Override protected char _decodeEscaped() throws IOException, JsonParseException { if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in character escape sequence"); } } int c = (int) _inputBuffer[_inputPtr++]; switch ((int) c) { // First, ones that are mapped case INT_b: return '\b'; case INT_t: return '\t'; case INT_n: return '\n'; case INT_f: return '\f'; case INT_r: return '\r'; // And these are to be returned as they are case INT_QUOTE: case INT_SLASH: case INT_BACKSLASH: return (char) c; case INT_u: // and finally hex-escaped break; default: return _handleUnrecognizedCharacterEscape((char) _decodeCharForError(c)); } // Ok, a hex escape. Need 4 characters int value = 0; for (int i = 0; i < 4; ++i) { if (_inputPtr >= _inputEnd) { if (!loadMore()) { _reportInvalidEOF(" in character escape sequence"); } } int ch = (int) _inputBuffer[_inputPtr++]; int digit = CharTypes.charToHex(ch); if (digit < 0) { _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); } value = (value << 4) | digit; } return (char) value; }
protected static void appendQuoted(StringBuilder sb, String content) { sb.append('"'); CharTypes.appendQuoted(sb, content); sb.append('"'); }