diff --git a/src/main/java/com/jsoniter/JsonIterator.java b/src/main/java/com/jsoniter/JsonIterator.java index 1f8d077e..56e155bc 100644 --- a/src/main/java/com/jsoniter/JsonIterator.java +++ b/src/main/java/com/jsoniter/JsonIterator.java @@ -6,9 +6,11 @@ import java.io.Closeable; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -494,6 +496,10 @@ public static final Any deserialize(String input) { return deserialize(input.getBytes()); } + public static Any deserialize(final String input, final Charset charset) { + return deserialize(input.getBytes(charset)); + } + public static final Any deserialize(Config config, byte[] input) { JsoniterSpi.setCurrentConfig(config); try { diff --git a/src/main/java/com/jsoniter/output/JsonStream.java b/src/main/java/com/jsoniter/output/JsonStream.java index 88f77077..3551754c 100644 --- a/src/main/java/com/jsoniter/output/JsonStream.java +++ b/src/main/java/com/jsoniter/output/JsonStream.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Type; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; public class JsonStream extends OutputStream { @@ -470,6 +472,10 @@ public static String serialize(Object obj) { return serialize(JsoniterSpi.getCurrentConfig().escapeUnicode(), obj.getClass(), obj); } + public static String serialize(Object obj, final Charset charset) { + return serialize(JsoniterSpi.getCurrentConfig().escapeUnicode(), obj.getClass(), obj, charset); + } + public static String serialize(Config config, TypeLiteral typeLiteral, Object obj) { JsoniterSpi.setCurrentConfig(config); try { @@ -484,12 +490,16 @@ public static String serialize(TypeLiteral typeLiteral, Object obj) { } public static String serialize(boolean escapeUnicode, Type type, Object obj) { + return serialize(escapeUnicode, type, obj, Charset.defaultCharset()); + } + + public static String serialize(boolean escapeUnicode, Type type, Object obj, Charset charset) { JsonStream stream = JsonStreamPool.borrowJsonStream(); try { stream.reset(null); stream.writeVal(type, obj); if (escapeUnicode) { - return new String(stream.buf, 0, stream.count); + return new String(stream.buf, 0, stream.count, charset); } else { return new String(stream.buf, 0, stream.count, "UTF8"); } @@ -504,7 +514,6 @@ public static void setMode(EncodingMode mode) { Config newConfig = JsoniterSpi.getDefaultConfig().copyBuilder().encodingMode(mode).build(); JsoniterSpi.setDefaultConfig(newConfig); JsoniterSpi.setCurrentConfig(newConfig); - } public static void setIndentionStep(int indentionStep) { diff --git a/src/test/java/com/jsoniter/output/TestString.java b/src/test/java/com/jsoniter/output/TestString.java index 96dda062..66b527dc 100644 --- a/src/test/java/com/jsoniter/output/TestString.java +++ b/src/test/java/com/jsoniter/output/TestString.java @@ -1,15 +1,45 @@ package com.jsoniter.output; +import com.jsoniter.JsonIterator; +import com.jsoniter.any.Any; import com.jsoniter.spi.Config; import junit.framework.TestCase; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + public class TestString extends TestCase { public void test_unicode() { String output = JsonStream.serialize(new Config.Builder().escapeUnicode(false).build(), "中文"); assertEquals("\"中文\"", output); } + public void test_escape_control_character() { String output = JsonStream.serialize(new String(new byte[]{0})); assertEquals("\"\\u0000\"", output); } + + public void test_encoding_different_than_default() throws NoSuchFieldException, IllegalAccessException { + Charset defaultEncoding = Charset.defaultCharset(); + try { + // Sets the default encoding + setDefaultEncoding("US-ASCII"); + + Any output = JsonIterator.deserialize("{\"name\":\"Thomas Müller\"}", StandardCharsets.UTF_8); + assertEquals("{\"name\":\"Thomas Müller\"}", JsonStream.serialize(output, StandardCharsets.UTF_8)); + } finally { + // Sets the default encoding back to its real default + setDefaultEncoding(defaultEncoding.name()); + } + } + + private void setDefaultEncoding(String defaultEncoding) throws NoSuchFieldException, IllegalAccessException { + // This block sets the Default Charset + System.setProperty("file.encoding", defaultEncoding); + // Unfortunately this "hack" is necessary (https://stackoverflow.com/questions/361975/setting-the-default-java-character-encoding) + Field cs = Charset.class.getDeclaredField("defaultCharset"); + cs.setAccessible(true); + cs.set(null, null); + } }