Skip to content

Commit 80ca2ef

Browse files
committed
Fixed #549
1 parent b1391d3 commit 80ca2ef

File tree

6 files changed

+52
-16
lines changed

6 files changed

+52
-16
lines changed

src/main/java/com/fasterxml/jackson/core/JsonFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ public static int collectDefaults() {
202202
*<p>
203203
* TODO: should clean up this; looks messy having 2 alternatives
204204
* with not very clear differences.
205-
*
206-
* @since 2.6.0
205+
*
206+
* @since 2.6
207207
*/
208208
protected final transient ByteQuadsCanonicalizer _byteSymbolCanonicalizer = ByteQuadsCanonicalizer.createRoot();
209209

src/main/java/com/fasterxml/jackson/core/io/CharTypes.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,7 @@ public final class CharTypes
161161
// 04-Mar-2011, tatu: Used to use "-(i + 1)", replaced with constant
162162
table[i] = CharacterEscapes.ESCAPE_STANDARD;
163163
}
164-
/* Others (and some within that range too) have explicit shorter
165-
* sequences
166-
*/
164+
// Others (and some within that range too) have explicit shorter sequences
167165
table['"'] = '"';
168166
table['\\'] = '\\';
169167
// Escaping of slash is optional, so let's not add it
@@ -210,6 +208,19 @@ public final class CharTypes
210208
*/
211209
public static int[] get7BitOutputEscapes() { return sOutputEscapes128; }
212210

211+
/**
212+
* Alternative to {@link #get7BitOutputEscapes()} when a non-standard quote character
213+
* is used.
214+
*
215+
* @since 2.10
216+
*/
217+
public static int[] get7BitOutputEscapes(int quoteChar) {
218+
if (quoteChar == '"') {
219+
return sOutputEscapes128;
220+
}
221+
return AltEscapes.instance.escapesFor(quoteChar);
222+
}
223+
213224
public static int charToHex(int ch)
214225
{
215226
return (ch > 127) ? -1 : sHexValues[ch];
@@ -255,5 +266,25 @@ public static char[] copyHexChars() {
255266
public static byte[] copyHexBytes() {
256267
return (byte[]) HB.clone();
257268
}
269+
270+
// @since 2.10
271+
private static class AltEscapes {
272+
public final static AltEscapes instance = new AltEscapes();
273+
274+
private int[][] _altEscapes = new int[128][];
275+
276+
public int[] escapesFor(int quoteChar) {
277+
int[] esc = _altEscapes[quoteChar];
278+
if (esc == null) {
279+
esc = Arrays.copyOf(sOutputEscapes128, 128);
280+
// Only add escape setting if character does not already have it
281+
if (esc[quoteChar] == 0) {
282+
esc[quoteChar] = CharacterEscapes.ESCAPE_STANDARD;
283+
}
284+
_altEscapes[quoteChar] = esc;
285+
}
286+
return esc;
287+
}
288+
}
258289
}
259290

src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ public UTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec,
122122
{
123123
super(ctxt, features, codec);
124124
_outputStream = out;
125-
_quoteChar = (byte) quoteChar; // TODO: validate/truncate
125+
_quoteChar = (byte) quoteChar;
126+
if (quoteChar != '"') { // since 2.10
127+
_outputEscapes = CharTypes.get7BitOutputEscapes(quoteChar);
128+
}
126129

127130
_bufferRecyclable = true;
128131
_outputBuffer = ctxt.allocWriteEncodingBuffer();
@@ -152,7 +155,10 @@ public UTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec,
152155

153156
super(ctxt, features, codec);
154157
_outputStream = out;
155-
_quoteChar = (byte) quoteChar; // TODO: validate/truncate
158+
_quoteChar = (byte) quoteChar;
159+
if (quoteChar != '"') { // since 2.10
160+
_outputEscapes = CharTypes.get7BitOutputEscapes(quoteChar);
161+
}
156162

157163
_bufferRecyclable = bufferRecyclable;
158164
_outputTail = outputOffset;

src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ public WriterBasedJsonGenerator(IOContext ctxt, int features,
109109
_outputBuffer = ctxt.allocConcatBuffer();
110110
_outputEnd = _outputBuffer.length;
111111
_quoteChar = quoteChar;
112+
if (quoteChar != '"') { // since 2.10
113+
_outputEscapes = CharTypes.get7BitOutputEscapes(quoteChar);
114+
}
112115
}
113116

114117
/*

src/test/java/com/fasterxml/jackson/core/json/CustomQuoteCharTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ public void testAposQuotingWithCharBased() throws Exception
7575
_writeObject(g, "key", "It's \"fun\"");
7676
g.close();
7777
// should escape apostrophes but not quotes?
78-
assertEquals("{'key':'It\\'s' \"fun\"}", w.toString());
78+
assertEquals("{'key':'It\\u0027s \\\"fun\\\"'}", w.toString());
7979

8080
// with Array
8181
w = new StringWriter();
8282
g = createGenerator(JSON_F, w);
8383
_writeArray(g, "It's a sin");
8484
g.close();
85-
assertEquals("['It\\'s a sin']", w.toString());
85+
assertEquals("['It\\u0027s a sin']", w.toString());
8686
}
8787

8888
public void testAposQuotingWithByteBased() throws Exception
@@ -96,14 +96,14 @@ public void testAposQuotingWithByteBased() throws Exception
9696
_writeObject(g, "key", "It's \"fun\"");
9797
g.close();
9898
// should escape apostrophes but not quotes?
99-
assertEquals("{'key':'It\\'s' \"fun\"}", out.toString("UTF-8"));
99+
assertEquals("{'key':'It\\u0027s \\\"fun\\\"'}", out.toString("UTF-8"));
100100

101101
// with Array
102102
out = new ByteArrayOutputStream();
103103
g = createGenerator(JSON_F, out);
104104
_writeArray(g, "It's a sin");
105105
g.close();
106-
assertEquals("['It\\'s a sin']", out.toString("UTF-8"));
106+
assertEquals("['It\\u0027s a sin']", out.toString("UTF-8"));
107107
}
108108

109109
private void _writeObject(JsonGenerator g, String key, String value) throws Exception {

src/test/java/com/fasterxml/jackson/core/json/TestUtf8Generator.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package com.fasterxml.jackson.core.json;
22

3-
import com.fasterxml.jackson.core.BaseTest;
4-
import com.fasterxml.jackson.core.JsonFactory;
5-
import com.fasterxml.jackson.core.JsonGenerator;
6-
import com.fasterxml.jackson.core.JsonParser;
7-
import com.fasterxml.jackson.core.JsonToken;
3+
import com.fasterxml.jackson.core.*;
84
import com.fasterxml.jackson.core.filter.FilteringGeneratorDelegate;
95
import com.fasterxml.jackson.core.filter.JsonPointerBasedFilter;
106
import com.fasterxml.jackson.core.io.IOContext;

0 commit comments

Comments
 (0)