public JsonGeneratorImpl(ObjectWriteContext writeCtxt, IOContext ctxt, int features, SerializableString rvs, CharacterEscapes charEsc, PrettyPrinter pp) { super(writeCtxt, features); _ioContext = ctxt; if (Feature.ESCAPE_NON_ASCII.enabledIn(features)) { // inlined `setHighestNonEscapedChar()` _maximumNonEscapedChar = 127; } _cfgUnqNames = !Feature.QUOTE_FIELD_NAMES.enabledIn(features); _rootValueSeparator = rvs; _cfgPrettyPrinter = pp; // 03-Oct-2017, tatu: Not clean (shouldn't call non-static methods from ctor), // but for now best way to avoid code duplication setCharacterEscapes(charEsc); }
public UTF8JsonGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, int features, OutputStream out, SerializableString rootValueSep, CharacterEscapes charEsc, PrettyPrinter pp) { super(writeCtxt, ioCtxt, features, rootValueSep, charEsc, pp); _outputStream = out; _bufferRecyclable = true; _outputBuffer = ioCtxt.allocWriteEncodingBuffer(); _outputEnd = _outputBuffer.length; // To be exact, each char can take up to 6 bytes when escaped (Unicode // escape with backslash, 'u' and 4 hex digits); but to avoid fluctuation, // we will actually round down to only do up to 1/8 number of chars _outputMaxContiguous = _outputEnd >> 3; _charBuffer = ioCtxt.allocConcatBuffer(); _charBufferLength = _charBuffer.length; // By default we use this feature to determine additional quoting if (isEnabled(Feature.ESCAPE_NON_ASCII)) { setHighestNonEscapedChar(127); } }
public UTF8JsonGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, int features, OutputStream out, SerializableString rootValueSep, CharacterEscapes charEsc, PrettyPrinter pp, byte[] outputBuffer, int outputOffset, boolean bufferRecyclable) { super(writeCtxt, ioCtxt, features, rootValueSep, charEsc, pp); _outputStream = out; _bufferRecyclable = bufferRecyclable; _outputTail = outputOffset; _outputBuffer = outputBuffer; _outputEnd = _outputBuffer.length; // up to 6 bytes per char (see above), rounded up to 1/8 _outputMaxContiguous = (_outputEnd >> 3); _charBuffer = ioCtxt.allocConcatBuffer(); _charBufferLength = _charBuffer.length; }
/** * By default JSON output does only have escaping where it is strictly * necessary. This is recommended in the most cases. Nevertheless it can * be sometimes useful to have some more escaping. * * @param escapeCharacters an array which defines which characters should be * escaped and how it will be done. See * {@link CharacterEscapes}. In most cases this should * be null. Use like this: * <pre>{@code int[] esc = CharacterEscapes.standardAsciiEscapesForJSON(); * // and force escaping of a few others: * esc['\''] = CharacterEscapes.ESCAPE_STANDARD; * JsonEncoder.useEscapeJavaScript(esc); * }</pre> */ public void setJavaScriptEscapeChars(final int[] escapeCharacters) { final CharacterEscapes ce = new CharacterEscapes() { private static final long serialVersionUID = 1L; @Override public int[] getEscapeCodesForAscii() { if (escapeCharacters == null) { return CharacterEscapes.standardAsciiEscapesForJSON(); } return escapeCharacters; } @Override public SerializableString getEscapeSequence(final int ch) { final String jsEscaped = escapeChar((char) ch); return new SerializedString(jsEscaped); } }; jsonGenerator.setCharacterEscapes(ce); }
public WriterBasedJsonGenerator(ObjectWriteContext writeCtxt, IOContext ioCtxt, int features, Writer w, SerializableString rootValueSep, CharacterEscapes charEsc, PrettyPrinter pp) { super(writeCtxt, ioCtxt, features, rootValueSep, charEsc, pp); _writer = w; _outputBuffer = ioCtxt.allocConcatBuffer(); _outputEnd = _outputBuffer.length; }
private void _writeStringASCII(final int len, final int maxNonEscaped) throws IOException, JsonGenerationException { // And then we'll need to verify need for escaping etc: int end = _outputTail + len; final int[] escCodes = _outputEscapes; final int escLimit = Math.min(escCodes.length, maxNonEscaped+1); int escCode = 0; output_loop: while (_outputTail < end) { char c; // Fast loop for chars not needing escaping escape_loop: while (true) { c = _outputBuffer[_outputTail]; if (c < escLimit) { escCode = escCodes[c]; if (escCode != 0) { break escape_loop; } } else if (c > maxNonEscaped) { escCode = CharacterEscapes.ESCAPE_STANDARD; break escape_loop; } if (++_outputTail >= end) { break output_loop; } } int flushLen = (_outputTail - _outputHead); if (flushLen > 0) { _writer.write(_outputBuffer, _outputHead, flushLen); } ++_outputTail; _prependOrWriteCharacterEscape(c, escCode); } }
private void _writeSegmentASCII(int end, final int maxNonEscaped) throws IOException, JsonGenerationException { final int[] escCodes = _outputEscapes; final int escLimit = Math.min(escCodes.length, maxNonEscaped+1); int ptr = 0; int escCode = 0; int start = ptr; output_loop: while (ptr < end) { // Fast loop for chars not needing escaping char c; while (true) { c = _outputBuffer[ptr]; if (c < escLimit) { escCode = escCodes[c]; if (escCode != 0) { break; } } else if (c > maxNonEscaped) { escCode = CharacterEscapes.ESCAPE_STANDARD; break; } if (++ptr >= end) { break; } } int flushLen = (ptr - start); if (flushLen > 0) { _writer.write(_outputBuffer, start, flushLen); if (ptr >= end) { break output_loop; } } ++ptr; start = _prependOrWriteCharacterEscape(_outputBuffer, ptr, end, c, escCode); } }
@Override public JsonGenerator setCharacterEscapes(CharacterEscapes esc) { _characterEscapes = esc; if (esc == null) { // revert to standard escapes _outputEscapes = sOutputEscapes; } else { _outputEscapes = esc.getEscapeCodesForAscii(); } return this; }
public HTMLCharacterEscapes( ) { // start with set of characters known to require escaping // (double-quote, backslash etc) int[] esc = CharacterEscapes.standardAsciiEscapesForJSON(); // and force escaping of a few others: esc['<'] = CharacterEscapes.ESCAPE_STANDARD; esc['>'] = CharacterEscapes.ESCAPE_STANDARD; esc['&'] = CharacterEscapes.ESCAPE_STANDARD; esc['\''] = CharacterEscapes.ESCAPE_STANDARD; asciiEscapes = esc; }
@Override public int[] getEscapeCodesForAscii() { // add standard set of escaping characters int[] esc = CharacterEscapes.standardAsciiEscapesForJSON(); // don't escape backslash (not to corrupt windows path) esc['\\'] = CharacterEscapes.ESCAPE_NONE; return esc; }
public JsonGenerator setCharacterEscapes(CharacterEscapes paramCharacterEscapes) { this._characterEscapes = paramCharacterEscapes; if (paramCharacterEscapes == null) { this._outputEscapes = sOutputEscapes; return this; } this._outputEscapes = paramCharacterEscapes.getEscapeCodesForAscii(); return this; }
public HTMLCharacterEscapes() { asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON(); asciiEscapes['<'] = CharacterEscapes.ESCAPE_STANDARD; asciiEscapes['>'] = CharacterEscapes.ESCAPE_STANDARD; asciiEscapes['&'] = CharacterEscapes.ESCAPE_STANDARD; asciiEscapes['\''] = CharacterEscapes.ESCAPE_STANDARD; asciiEscapes['/'] = CharacterEscapes.ESCAPE_STANDARD; asciiEscapes['+'] = CharacterEscapes.ESCAPE_STANDARD; }
private void _writeStringASCII(char[] text, int offset, int len, final int maxNonEscaped) throws IOException, JsonGenerationException { len += offset; // -> len marks the end from now on final int[] escCodes = _outputEscapes; final int escLimit = Math.min(escCodes.length, maxNonEscaped+1); int escCode = 0; while (offset < len) { int start = offset; char c; while (true) { c = text[offset]; if (c < escLimit) { escCode = escCodes[c]; if (escCode != 0) { break; } } else if (c > maxNonEscaped) { escCode = CharacterEscapes.ESCAPE_STANDARD; break; } if (++offset >= len) { break; } } // Short span? Better just copy it to buffer first: int newAmount = offset - start; if (newAmount < SHORT_WRITE) { // Note: let's reserve room for escaped char (up to 6 chars) if ((_outputTail + newAmount) > _outputEnd) { _flushBuffer(); } if (newAmount > 0) { System.arraycopy(text, start, _outputBuffer, _outputTail, newAmount); _outputTail += newAmount; } } else { // Nope: better just write through _flushBuffer(); _writer.write(text, start, newAmount); } // Was this the end? if (offset >= len) { // yup break; } // Nope, need to escape the char. ++offset; _appendCharacterEscape(c, escCode); } }
private void _writeStringCustom(final int len) throws IOException, JsonGenerationException { // And then we'll need to verify need for escaping etc: int end = _outputTail + len; final int[] escCodes = _outputEscapes; final int maxNonEscaped = (_maximumNonEscapedChar < 1) ? 0xFFFF : _maximumNonEscapedChar; final int escLimit = Math.min(escCodes.length, maxNonEscaped+1); int escCode = 0; final CharacterEscapes customEscapes = _characterEscapes; output_loop: while (_outputTail < end) { char c; // Fast loop for chars not needing escaping escape_loop: while (true) { c = _outputBuffer[_outputTail]; if (c < escLimit) { escCode = escCodes[c]; if (escCode != 0) { break escape_loop; } } else if (c > maxNonEscaped) { escCode = CharacterEscapes.ESCAPE_STANDARD; break escape_loop; } else { if ((_currentEscape = customEscapes.getEscapeSequence(c)) != null) { escCode = CharacterEscapes.ESCAPE_CUSTOM; break escape_loop; } } if (++_outputTail >= end) { break output_loop; } } int flushLen = (_outputTail - _outputHead); if (flushLen > 0) { _writer.write(_outputBuffer, _outputHead, flushLen); } ++_outputTail; _prependOrWriteCharacterEscape(c, escCode); } }
private void _writeSegmentCustom(int end) throws IOException, JsonGenerationException { final int[] escCodes = _outputEscapes; final int maxNonEscaped = (_maximumNonEscapedChar < 1) ? 0xFFFF : _maximumNonEscapedChar; final int escLimit = Math.min(escCodes.length, maxNonEscaped+1); final CharacterEscapes customEscapes = _characterEscapes; int ptr = 0; int escCode = 0; int start = ptr; output_loop: while (ptr < end) { // Fast loop for chars not needing escaping char c; while (true) { c = _outputBuffer[ptr]; if (c < escLimit) { escCode = escCodes[c]; if (escCode != 0) { break; } } else if (c > maxNonEscaped) { escCode = CharacterEscapes.ESCAPE_STANDARD; break; } else { if ((_currentEscape = customEscapes.getEscapeSequence(c)) != null) { escCode = CharacterEscapes.ESCAPE_CUSTOM; break; } } if (++ptr >= end) { break; } } int flushLen = (ptr - start); if (flushLen > 0) { _writer.write(_outputBuffer, start, flushLen); if (ptr >= end) { break output_loop; } } ++ptr; start = _prependOrWriteCharacterEscape(_outputBuffer, ptr, end, c, escCode); } }
private void _writeStringCustom(char[] text, int offset, int len) throws IOException, JsonGenerationException { len += offset; // -> len marks the end from now on final int[] escCodes = _outputEscapes; final int maxNonEscaped = (_maximumNonEscapedChar < 1) ? 0xFFFF : _maximumNonEscapedChar; final int escLimit = Math.min(escCodes.length, maxNonEscaped+1); final CharacterEscapes customEscapes = _characterEscapes; int escCode = 0; while (offset < len) { int start = offset; char c; while (true) { c = text[offset]; if (c < escLimit) { escCode = escCodes[c]; if (escCode != 0) { break; } } else if (c > maxNonEscaped) { escCode = CharacterEscapes.ESCAPE_STANDARD; break; } else { if ((_currentEscape = customEscapes.getEscapeSequence(c)) != null) { escCode = CharacterEscapes.ESCAPE_CUSTOM; break; } } if (++offset >= len) { break; } } // Short span? Better just copy it to buffer first: int newAmount = offset - start; if (newAmount < SHORT_WRITE) { // Note: let's reserve room for escaped char (up to 6 chars) if ((_outputTail + newAmount) > _outputEnd) { _flushBuffer(); } if (newAmount > 0) { System.arraycopy(text, start, _outputBuffer, _outputTail, newAmount); _outputTail += newAmount; } } else { // Nope: better just write through _flushBuffer(); _writer.write(text, start, newAmount); } // Was this the end? if (offset >= len) { // yup break; } // Nope, need to escape the char. ++offset; _appendCharacterEscape(c, escCode); } }
/** * Method called to append escape sequence for given character, at the * end of standard output buffer; or if not possible, write out directly. */ private void _appendCharacterEscape(char ch, int escCode) throws IOException, JsonGenerationException { if (escCode >= 0) { // \\N (2 char) if ((_outputTail + 2) > _outputEnd) { _flushBuffer(); } _outputBuffer[_outputTail++] = '\\'; _outputBuffer[_outputTail++] = (char) escCode; return; } if (escCode != CharacterEscapes.ESCAPE_CUSTOM) { // std, \\uXXXX if ((_outputTail + 5) >= _outputEnd) { _flushBuffer(); } int ptr = _outputTail; char[] buf = _outputBuffer; buf[ptr++] = '\\'; buf[ptr++] = 'u'; // We know it's a control char, so only the last 2 chars are non-0 if (ch > 0xFF) { // beyond 8 bytes int hi = (ch >> 8) & 0xFF; buf[ptr++] = HEX_CHARS[hi >> 4]; buf[ptr++] = HEX_CHARS[hi & 0xF]; ch &= 0xFF; } else { buf[ptr++] = '0'; buf[ptr++] = '0'; } buf[ptr++] = HEX_CHARS[ch >> 4]; buf[ptr++] = HEX_CHARS[ch & 0xF]; _outputTail = ptr; return; } String escape; if (_currentEscape == null) { escape = _characterEscapes.getEscapeSequence(ch).getValue(); } else { escape = _currentEscape.getValue(); _currentEscape = null; } int len = escape.length(); if ((_outputTail + len) > _outputEnd) { _flushBuffer(); if (len > _outputEnd) { // very very long escape; unlikely but theoretically possible _writer.write(escape); return; } } escape.getChars(0, len, _outputBuffer, _outputTail); _outputTail += len; }
/** * Method for accessing custom escapes factory uses for {@link JsonGenerator}s * it creates. */ @Override public CharacterEscapes getCharacterEscapes() { return _characterEscapes; }
@Override public CharacterEscapes getCharacterEscapes() { return null; }
@Override public CharacterEscapes getCharacterEscapes() { return delegate.getCharacterEscapes(); }
public MyEscapes() { _asciiEscapes = standardAsciiEscapesForJSON(); _asciiEscapes['a'] = 'A'; // to basically give us "\A" _asciiEscapes['b'] = CharacterEscapes.ESCAPE_STANDARD; // too force "\u0062" _asciiEscapes['d'] = CharacterEscapes.ESCAPE_CUSTOM; }
public HTMLCharacterEscapes() { int[] esc = CharacterEscapes.standardAsciiEscapesForJSON(); esc['<'] = CharacterEscapes.ESCAPE_CUSTOM; esc['>'] = CharacterEscapes.ESCAPE_CUSTOM; this.asciiEscapes = esc; }
private void _writeSegmentCustom(int paramInt) { int[] arrayOfInt = this._outputEscapes; int i; if (this._maximumNonEscapedChar <= 0) i = 65535; else i = this._maximumNonEscapedChar; int j = Math.min(arrayOfInt.length, i + 1); CharacterEscapes localCharacterEscapes = this._characterEscapes; int k = 0; int m = 0; int i1; for (int n = 0; k < paramInt; n = _prependOrWriteCharacterEscape(this._outputBuffer, k, paramInt, i1, m)) { do { i1 = this._outputBuffer[k]; if (i1 < j) { int i3 = arrayOfInt[i1]; m = i3; if (i3 != 0) break; } else { if (i1 > i) { m = -1; break; } SerializableString localSerializableString = localCharacterEscapes.getEscapeSequence(i1); this._currentEscape = localSerializableString; if (localSerializableString != null) { m = -2; break; } } k++; } while (k < paramInt); int i2 = k - n; if (i2 > 0) { this._writer.write(this._outputBuffer, n, i2); if (k >= paramInt) break; } k++; } }
private void _writeStringCustom(int paramInt) { int i = paramInt + this._outputTail; int[] arrayOfInt = this._outputEscapes; int j; if (this._maximumNonEscapedChar <= 0) j = 65535; else j = this._maximumNonEscapedChar; int k = Math.min(arrayOfInt.length, j + 1); CharacterEscapes localCharacterEscapes = this._characterEscapes; while (this._outputTail < i) { int m; int i1; int n; do { m = this._outputBuffer[this._outputTail]; if (m < k) { int i3 = arrayOfInt[m]; i1 = i3; if (i3 != 0) break; } else { if (m > j) { i1 = -1; break; } SerializableString localSerializableString = localCharacterEscapes.getEscapeSequence(m); this._currentEscape = localSerializableString; if (localSerializableString != null) { i1 = -2; break; } } n = 1 + this._outputTail; this._outputTail = n; } while (n < i); return; int i2 = this._outputTail - this._outputHead; if (i2 > 0) this._writer.write(this._outputBuffer, this._outputHead, i2); this._outputTail = (1 + this._outputTail); _prependOrWriteCharacterEscape(m, i1); } }
private void _writeStringCustom(char[] paramArrayOfChar, int paramInt1, int paramInt2) { int i = paramInt2 + paramInt1; int[] arrayOfInt = this._outputEscapes; int j; if (this._maximumNonEscapedChar <= 0) j = 65535; else j = this._maximumNonEscapedChar; int k = Math.min(arrayOfInt.length, j + 1); CharacterEscapes localCharacterEscapes = this._characterEscapes; int m = 0; while (paramInt1 < i) { int n = paramInt1; int i1; do { i1 = paramArrayOfChar[paramInt1]; if (i1 < k) { int i3 = arrayOfInt[i1]; m = i3; if (i3 != 0) break; } else { if (i1 > j) { m = -1; break; } SerializableString localSerializableString = localCharacterEscapes.getEscapeSequence(i1); this._currentEscape = localSerializableString; if (localSerializableString != null) { m = -2; break; } } paramInt1++; } while (paramInt1 < i); int i2 = paramInt1 - n; if (i2 < 32) { if (i2 + this._outputTail > this._outputEnd) _flushBuffer(); if (i2 > 0) { System.arraycopy(paramArrayOfChar, n, this._outputBuffer, this._outputTail, i2); this._outputTail = (i2 + this._outputTail); } } else { _flushBuffer(); this._writer.write(paramArrayOfChar, n, i2); } if (paramInt1 >= i) break; paramInt1++; _appendCharacterEscape(i1, m); } }
public CharacterEscapes getCharacterEscapes() { return this._characterEscapes; }
private void _writeCustomStringSegment2(char[] paramArrayOfChar, int paramInt1, int paramInt2) { if (this._outputTail + 6 * (paramInt2 - paramInt1) > this._outputEnd) _flushBuffer(); int i = this._outputTail; byte[] arrayOfByte = this._outputBuffer; int[] arrayOfInt = this._outputEscapes; int j; if (this._maximumNonEscapedChar <= 0) j = 65535; else j = this._maximumNonEscapedChar; CharacterEscapes localCharacterEscapes = this._characterEscapes; while (paramInt1 < paramInt2) { int k = paramInt1; paramInt1++; int m = paramArrayOfChar[k]; if (m <= 127) { if (arrayOfInt[m] == 0) { int i5 = i; i++; arrayOfByte[i5] = ((byte)m); } else { int i2 = arrayOfInt[m]; if (i2 > 0) { int i3 = i; int i4 = i + 1; arrayOfByte[i3] = 92; i = i4 + 1; arrayOfByte[i4] = ((byte)i2); } else if (i2 == -2) { SerializableString localSerializableString2 = localCharacterEscapes.getEscapeSequence(m); if (localSerializableString2 == null) _reportError("Invalid custom escape definitions; custom escape not found for character code 0x" + Integer.toHexString(m) + ", although was supposed to have one"); i = _writeCustomEscape(arrayOfByte, i, localSerializableString2, paramInt2 - paramInt1); } else { i = _writeGenericEscape(m, i); } } } else if (m > j) { i = _writeGenericEscape(m, i); } else { SerializableString localSerializableString1 = localCharacterEscapes.getEscapeSequence(m); if (localSerializableString1 != null) { i = _writeCustomEscape(arrayOfByte, i, localSerializableString1, paramInt2 - paramInt1); } else if (m <= 2047) { int n = i; int i1 = i + 1; arrayOfByte[n] = ((byte)(0xC0 | m >> 6)); i = i1 + 1; arrayOfByte[i1] = ((byte)(0x80 | m & 0x3F)); } else { i = _outputMultiByteChar(m, i); } } } this._outputTail = i; }
public JsonFactory setCharacterEscapes(CharacterEscapes paramCharacterEscapes) { this._characterEscapes = paramCharacterEscapes; return this; }
public CharacterEscapes getCharacterEscapes() { return this.delegate.getCharacterEscapes(); }
public JsonGenerator setCharacterEscapes(CharacterEscapes paramCharacterEscapes) { this.delegate.setCharacterEscapes(paramCharacterEscapes); return this; }
public CharacterEscapes getCharacterEscapes() { return null; }
public JsonGenerator setCharacterEscapes(CharacterEscapes paramCharacterEscapes) { return this; }
@Override public JsonGenerator setCharacterEscapes(CharacterEscapes esc) { delegate.setCharacterEscapes(esc); return this; }
public EscapeForwardSlash() { _asciiEscapes = standardAsciiEscapesForJSON(); _asciiEscapes['/'] = CharacterEscapes.ESCAPE_CUSTOM; }