From 6d01183b95922cc8a75c9634be70510ef38e8330 Mon Sep 17 00:00:00 2001 From: Lukas Svoboda Date: Sun, 23 Jan 2022 16:20:51 +0100 Subject: [PATCH] Fixed public api 'public static String serialize(boolean escapeUnicode, Type type, Object obj)' implementation. Fixes #289, #299. --- .../java/com/jsoniter/output/JsonStream.java | 59 +++++++++++-------- .../com/jsoniter/output/StreamImplString.java | 4 +- .../java/com/jsoniter/spi/JsoniterSpi.java | 1 + .../java/com/jsoniter/output/TestString.java | 25 +++++++- 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/jsoniter/output/JsonStream.java b/src/main/java/com/jsoniter/output/JsonStream.java index 88f77077..7886bc05 100644 --- a/src/main/java/com/jsoniter/output/JsonStream.java +++ b/src/main/java/com/jsoniter/output/JsonStream.java @@ -442,52 +442,59 @@ public static void serialize(TypeLiteral typeLiteral, Object obj, OutputStream o } public static void serialize(Type type, Object obj, OutputStream out) { - JsonStream stream = JsonStreamPool.borrowJsonStream(); - try { - try { - stream.reset(out); - stream.writeVal(type, obj); - } finally { - stream.close(); - } - } catch (IOException e) { - throw new JsonException(e); - } finally { - JsonStreamPool.returnJsonStream(stream); - } + serialize(type, obj, out, false); } public static String serialize(Config config, Object obj) { - JsoniterSpi.setCurrentConfig(config); - try { - return serialize(config.escapeUnicode(), obj.getClass(), obj); - } finally { - JsoniterSpi.clearCurrentConfig(); - } + return serialize(config, obj.getClass(), obj); } public static String serialize(Object obj) { - return serialize(JsoniterSpi.getCurrentConfig().escapeUnicode(), obj.getClass(), obj); + return serialize(obj.getClass(), obj); } public static String serialize(Config config, TypeLiteral typeLiteral, Object obj) { + return serialize(config, typeLiteral.getType(), obj); + } + + private static String serialize(Config config, Type type, Object obj) { + final Config configBackup = JsoniterSpi.getCurrentConfig(); + // Set temporary config JsoniterSpi.setCurrentConfig(config); try { - return serialize(config.escapeUnicode(), typeLiteral.getType(), obj); + return serialize(type, obj); } finally { - JsoniterSpi.clearCurrentConfig(); + // Revert old config + JsoniterSpi.setCurrentConfig(configBackup); } } public static String serialize(TypeLiteral typeLiteral, Object obj) { - return serialize(JsoniterSpi.getCurrentConfig().escapeUnicode(), typeLiteral.getType(), obj); + return serialize(typeLiteral.getType(), obj); } public static String serialize(boolean escapeUnicode, Type type, Object obj) { - JsonStream stream = JsonStreamPool.borrowJsonStream(); + final Config currentConfig = JsoniterSpi.getCurrentConfig(); + return serialize(currentConfig.copyBuilder().escapeUnicode(escapeUnicode).build(), type, obj); + } + + private static String serialize(Type type, Object obj) { + return serialize(type, obj, null, true); + } + + private static String serialize(Type type, Object obj, OutputStream out, boolean returnObjAsString) { + final JsonStream stream = JsonStreamPool.borrowJsonStream(); + final boolean escapeUnicode = JsoniterSpi.getCurrentConfig().escapeUnicode(); try { - stream.reset(null); - stream.writeVal(type, obj); + try { + stream.reset(out); + stream.writeVal(type, obj); + } finally { + stream.close(); + } + if (!returnObjAsString) { + return ""; + } if (escapeUnicode) { return new String(stream.buf, 0, stream.count); } else { diff --git a/src/main/java/com/jsoniter/output/StreamImplString.java b/src/main/java/com/jsoniter/output/StreamImplString.java index cbab7bca..7c4a27a7 100644 --- a/src/main/java/com/jsoniter/output/StreamImplString.java +++ b/src/main/java/com/jsoniter/output/StreamImplString.java @@ -132,7 +132,7 @@ private static void writeStringSlowPath(JsonStream stream, String val, int i, in if (escapeUnicode) { for (; i < valLen; i++) { int c = val.charAt(i); - if (c > 125) { + if (c > 127) { writeAsSlashU(stream, c); } else { writeAsciiChar(stream, c); @@ -147,7 +147,7 @@ private static void writeStringSlowPathWithoutEscapeUnicode(JsonStream stream, S int _surrogate; for (; i < valLen; i++) { int c = val.charAt(i); - if (c > 125) { + if (c > 127) { if (c < 0x800) { // 2-byte stream.write( (byte) (0xc0 | (c >> 6)), diff --git a/src/main/java/com/jsoniter/spi/JsoniterSpi.java b/src/main/java/com/jsoniter/spi/JsoniterSpi.java index 7f505e1a..4b40e77e 100644 --- a/src/main/java/com/jsoniter/spi/JsoniterSpi.java +++ b/src/main/java/com/jsoniter/spi/JsoniterSpi.java @@ -43,6 +43,7 @@ public static void setCurrentConfig(Config val) { currentConfig.set(val); } + // TODO usage of this method leads to potentially unexpected side effects. All usage should be checked. public static void clearCurrentConfig() { currentConfig.set(defaultConfig); } diff --git a/src/test/java/com/jsoniter/output/TestString.java b/src/test/java/com/jsoniter/output/TestString.java index 91814dc9..186c770a 100644 --- a/src/test/java/com/jsoniter/output/TestString.java +++ b/src/test/java/com/jsoniter/output/TestString.java @@ -1,19 +1,40 @@ package com.jsoniter.output; import com.jsoniter.spi.Config; +import com.jsoniter.spi.Config.Builder; +import com.jsoniter.spi.JsoniterSpi; +import java.io.ByteArrayOutputStream; import junit.framework.TestCase; public class TestString extends TestCase { + + public static final String UTF8_GREETING = "Привет čau 你好 ~"; + public void test_unicode() { String output = JsonStream.serialize(new Config.Builder().escapeUnicode(false).build(), "中文"); assertEquals("\"中文\"", output); } public void test_unicode_tilde() { - String output = JsonStream.serialize(new Config.Builder().escapeUnicode(false).build(), "~"); - assertEquals("\"~\"", output); + final String tilde = "~"; + String output = JsonStream.serialize(new Config.Builder().escapeUnicode(false).build(), tilde); + assertEquals("\""+tilde+"\"", output); + } + public void test_escape_unicode() { + final Config config = new Builder().escapeUnicode(false).build(); + + assertEquals("\""+UTF8_GREETING+"\"", JsonStream.serialize(config, UTF8_GREETING)); + assertEquals("\""+UTF8_GREETING+"\"", JsonStream.serialize(config.escapeUnicode(), UTF8_GREETING.getClass(), UTF8_GREETING)); } public void test_escape_control_character() { String output = JsonStream.serialize(new String(new byte[]{0})); assertEquals("\"\\u0000\"", output); } + public void test_serialize_into_output_stream() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + boolean escapeUnicode = JsoniterSpi.getCurrentConfig().escapeUnicode(); + JsoniterSpi.setCurrentConfig(JsoniterSpi.getCurrentConfig().copyBuilder().escapeUnicode(false).build()); + JsonStream.serialize(String.class, UTF8_GREETING, baos); + JsoniterSpi.setCurrentConfig(JsoniterSpi.getCurrentConfig().copyBuilder().escapeUnicode(escapeUnicode).build()); + assertEquals("\"" + UTF8_GREETING + "\"", baos.toString()); + } }