Skip to content

Commit d7e924b

Browse files
committed
Adds Charset serializer, also set as default serializer
With registration required == true, users still have to register the required charsets, e.g. via `kryo.register(StandardCharsets.ISO_8859_1.getClass());`. Resolves #364
1 parent 617a57f commit d7e924b

15 files changed

+60
-10
lines changed

src/com/esotericsoftware/kryo/Kryo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.lang.reflect.Proxy;
2929
import java.math.BigDecimal;
3030
import java.math.BigInteger;
31+
import java.nio.charset.Charset;
3132
import java.util.ArrayList;
3233
import java.util.Calendar;
3334
import java.util.Collection;
@@ -72,6 +73,7 @@
7273
import com.esotericsoftware.kryo.serializers.DefaultSerializers.ByteSerializer;
7374
import com.esotericsoftware.kryo.serializers.DefaultSerializers.CalendarSerializer;
7475
import com.esotericsoftware.kryo.serializers.DefaultSerializers.CharSerializer;
76+
import com.esotericsoftware.kryo.serializers.DefaultSerializers.CharsetSerializer;
7577
import com.esotericsoftware.kryo.serializers.DefaultSerializers.ClassSerializer;
7678
import com.esotericsoftware.kryo.serializers.DefaultSerializers.CollectionsEmptyListSerializer;
7779
import com.esotericsoftware.kryo.serializers.DefaultSerializers.CollectionsEmptyMapSerializer;
@@ -213,6 +215,7 @@ public Kryo (ClassResolver classResolver, ReferenceResolver referenceResolver, S
213215
addDefaultSerializer(TimeZone.class, TimeZoneSerializer.class);
214216
addDefaultSerializer(Calendar.class, CalendarSerializer.class);
215217
addDefaultSerializer(Locale.class, LocaleSerializer.class);
218+
addDefaultSerializer(Charset.class, CharsetSerializer.class);
216219
OptionalSerializers.addDefaultSerializers(this);
217220
TimeSerializers.addDefaultSerializers(this);
218221
lowPriorityDefaultSerializerCount = defaultSerializers.size();

src/com/esotericsoftware/kryo/serializers/DefaultSerializers.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1616
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1717
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18-
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
19-
18+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
19+
2020
package com.esotericsoftware.kryo.serializers;
2121

2222
import java.math.BigDecimal;
2323
import java.math.BigInteger;
24+
import java.nio.charset.Charset;
2425
import java.util.Calendar;
2526
import java.util.Collection;
2627
import java.util.Collections;
@@ -836,4 +837,20 @@ protected static boolean isSameLocale(Locale locale, String language, String cou
836837
}
837838
}
838839
}
839-
}
840+
841+
/** Serializer for {@link Charset}. Added as default serializer for java >= 7. */
842+
public static class CharsetSerializer extends Serializer<Charset> {
843+
844+
{ setImmutable(true); }
845+
846+
public void write(Kryo kryo, Output output, Charset object) {
847+
output.writeString(object.name());
848+
}
849+
850+
public Charset read(Kryo kryo, Input input, Class<Charset> type) {
851+
return Charset.forName(input.readString());
852+
}
853+
854+
}
855+
856+
}

test/com/esotericsoftware/kryo/DefaultSerializersTest.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,25 @@
1515
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1616
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1717
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18-
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
19-
18+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
19+
2020
package com.esotericsoftware.kryo;
2121

2222
import java.math.BigDecimal;
2323
import java.math.BigInteger;
24+
import java.nio.charset.Charset;
2425
import java.util.ArrayList;
26+
import java.util.Arrays;
2527
import java.util.Calendar;
2628
import java.util.Collections;
2729
import java.util.Date;
2830
import java.util.EnumSet;
31+
import java.util.List;
32+
import java.util.Locale;
2933
import java.util.TimeZone;
3034

3135
import com.esotericsoftware.kryo.io.Input;
3236
import com.esotericsoftware.kryo.io.Output;
33-
import java.util.Locale;
3437

3538
/** @author Nathan Sweet <[email protected]> */
3639
public class DefaultSerializersTest extends KryoTestCase {
@@ -342,6 +345,26 @@ public void testLocaleSerializer () {
342345
roundTrip(16, 16, new Locale("es", "ES", "áéíóú"));
343346
}
344347

348+
public void testCharset() {
349+
List<String> css = Arrays.asList("ISO-8859-1", "US-ASCII", "UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE");
350+
351+
for(String cs : css) {
352+
Charset charset = Charset.forName(cs);
353+
kryo.register(charset.getClass());
354+
int expectedLength = 1 + cs.length();
355+
roundTrip(expectedLength, expectedLength, charset);
356+
}
357+
358+
kryo = new Kryo();
359+
kryo.setRegistrationRequired(false);
360+
361+
for(String cs : css) {
362+
Charset charset = Charset.forName(cs);
363+
int expectedLength = 3 + charset.getClass().getName().length() + cs.length();
364+
roundTrip(expectedLength, expectedLength, charset);
365+
}
366+
}
367+
345368
public enum TestEnum {
346369
a, b, c
347370
}
@@ -373,4 +396,4 @@ public BigIntegerSubclass(String val) {
373396
}
374397
}
375398

376-
}
399+
}

test/com/esotericsoftware/kryo/SerializationCompatTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.esotericsoftware.kryo.SerializationCompatTestData.TestData;
2323
import com.esotericsoftware.kryo.SerializationCompatTestData.TestDataJava8;
2424
import com.esotericsoftware.kryo.io.*;
25+
import com.esotericsoftware.kryo.serializers.CollectionSerializer;
2526
import com.esotericsoftware.minlog.Log;
2627
import org.objenesis.strategy.StdInstantiatorStrategy;
2728

@@ -32,6 +33,7 @@
3233
import java.lang.reflect.Field;
3334
import java.nio.ByteOrder;
3435
import java.util.ArrayList;
36+
import java.util.Arrays;
3537
import java.util.EnumSet;
3638
import java.util.List;
3739

@@ -72,12 +74,12 @@ public class SerializationCompatTest extends KryoTestCase {
7274

7375
private static final String ENDIANNESS = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? "le" : "be";
7476
private static final int JAVA_VERSION = Integer.parseInt(System.getProperty("java.version").split("\\.")[1]);
75-
private static final int EXPECTED_DEFAULT_SERIALIZER_COUNT = JAVA_VERSION < 8 ? 33 : 51;
77+
private static final int EXPECTED_DEFAULT_SERIALIZER_COUNT = JAVA_VERSION < 8 ? 34 : 52;
7678
private static final List<TestDataDescription<?>> TEST_DATAS = new ArrayList<TestDataDescription<?>>();
7779

7880
static {
79-
TEST_DATAS.add(new TestDataDescription<TestData>("3.0.0", new TestData(), 1646, 1754));
80-
if(JAVA_VERSION >= 8) TEST_DATAS.add(new TestDataDescription<TestDataJava8>("3.1.0", new TestDataJava8(), 1806, 1958));
81+
TEST_DATAS.add(new TestDataDescription<TestData>("3.0.0", new TestData(), 1824, 1932));
82+
if(JAVA_VERSION >= 8) TEST_DATAS.add(new TestDataDescription<TestDataJava8>("3.1.0", new TestDataJava8(), 1984, 2136));
8183
};
8284

8385
@Override
@@ -213,6 +215,7 @@ private void runTest(TestDataDescription description, String variant, Function1<
213215
// if anything failed (e.g. the initial test), we should delete the file as it may be empty or corruped
214216
out.close();
215217
file.delete();
218+
throw e;
216219
}
217220
}
218221
}

test/com/esotericsoftware/kryo/SerializationCompatTestData.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.Serializable;
2727
import java.math.BigDecimal;
2828
import java.math.BigInteger;
29+
import java.nio.charset.Charset;
2930
import java.time.*;
3031
import java.util.*;
3132
import java.util.concurrent.atomic.AtomicInteger;
@@ -112,6 +113,7 @@ public static class TestData implements Serializable {
112113
private TimeZone _timeZone;
113114
private Calendar _calendar;
114115
private Locale _locale;
116+
List<Charset> _charsets;
115117

116118
private Gender _enum;
117119
private EnumSet<Gender> _enumSet;
@@ -184,6 +186,8 @@ public TestData () {
184186

185187
_timeZone = TimeZone.getTimeZone("America/Los_Angeles");
186188
_locale = Locale.ENGLISH;
189+
_charsets = new ArrayList<Charset>(Arrays.asList(Charset.forName("ISO-8859-1"), Charset.forName("US-ASCII"),
190+
Charset.forName("UTF-8"), Charset.forName("UTF-16"), Charset.forName("UTF-16BE"), Charset.forName("UTF-16LE")));
187191

188192
_enum = Gender.FEMALE;
189193
_enumSet = EnumSet.allOf(Gender.class);
178 Bytes
Binary file not shown.

test/resources/TestData-fast.ser

178 Bytes
Binary file not shown.

test/resources/TestData-standard.ser

178 Bytes
Binary file not shown.

test/resources/TestData-unsafe-le.ser

178 Bytes
Binary file not shown.
178 Bytes
Binary file not shown.
178 Bytes
Binary file not shown.

test/resources/TestDataJava8-fast.ser

178 Bytes
Binary file not shown.
178 Bytes
Binary file not shown.
178 Bytes
Binary file not shown.
178 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)