com.esotericsoftware.kryo.serializers.DefaultSerializers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kryo-slf4j-shaded Show documentation
Show all versions of kryo-slf4j-shaded Show documentation
Fork of Esoteric Software's Kryo built by Nathan Sweet that replaces Minlog with slf4j as the logging facade. This contains the shaded reflectasm jar to prevent conflicts with other versions of asm.
The newest version!
/* Copyright (c) 2008, Nathan Sweet
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
package com.esotericsoftware.kryo.serializers;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Currency;
import java.util.Date;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.KryoSerializable;
import com.esotericsoftware.kryo.Registration;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import static com.esotericsoftware.kryo.Kryo.*;
import static com.esotericsoftware.kryo.util.Util.*;
import java.lang.reflect.Constructor;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Locale;
/** Contains many serializer classes that are provided by {@link Kryo#addDefaultSerializer(Class, Class) default}.
* @author Nathan Sweet */
public class DefaultSerializers {
static public class VoidSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Object object) {
}
public Object read (Kryo kryo, Input input, Class type) {
return null;
}
}
static public class BooleanSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Boolean object) {
output.writeBoolean(object);
}
public Boolean read (Kryo kryo, Input input, Class type) {
return input.readBoolean();
}
}
static public class ByteSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Byte object) {
output.writeByte(object);
}
public Byte read (Kryo kryo, Input input, Class type) {
return input.readByte();
}
}
static public class CharSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Character object) {
output.writeChar(object);
}
public Character read (Kryo kryo, Input input, Class type) {
return input.readChar();
}
}
static public class ShortSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Short object) {
output.writeShort(object);
}
public Short read (Kryo kryo, Input input, Class type) {
return input.readShort();
}
}
static public class IntSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Integer object) {
output.writeInt(object, false);
}
public Integer read (Kryo kryo, Input input, Class type) {
return input.readInt(false);
}
}
static public class LongSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Long object) {
output.writeLong(object, false);
}
public Long read (Kryo kryo, Input input, Class type) {
return input.readLong(false);
}
}
static public class FloatSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Float object) {
output.writeFloat(object);
}
public Float read (Kryo kryo, Input input, Class type) {
return input.readFloat();
}
}
static public class DoubleSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Double object) {
output.writeDouble(object);
}
public Double read (Kryo kryo, Input input, Class type) {
return input.readDouble();
}
}
/** @see Output#writeString(String) */
static public class StringSerializer extends Serializer {
{
setImmutable(true);
setAcceptsNull(true);
}
public void write (Kryo kryo, Output output, String object) {
output.writeString(object);
}
public String read (Kryo kryo, Input input, Class type) {
return input.readString();
}
}
/** Serializer for {@link BigInteger} and any subclass.
* @author Tumi (enhacements) */
static public class BigIntegerSerializer extends Serializer {
{
setImmutable(true);
setAcceptsNull(true);
}
public void write (Kryo kryo, Output output, BigInteger object) {
if (object == null) {
output.writeVarInt(NULL, true);
return;
}
BigInteger value = (BigInteger)object;
// fast-path optimizations for BigInteger.ZERO constant
if (value == BigInteger.ZERO) {
output.writeVarInt(2, true);
output.writeByte(0);
return;
}
// default behaviour
byte[] bytes = value.toByteArray();
output.writeVarInt(bytes.length + 1, true);
output.writeBytes(bytes);
}
public BigInteger read (Kryo kryo, Input input, Class type) {
int length = input.readVarInt(true);
if (length == NULL) return null;
byte[] bytes = input.readBytes(length - 1);
if (type != BigInteger.class && type != null) {
// For subclasses, use reflection
try {
Constructor constructor = type.getConstructor(byte[].class);
if (!constructor.isAccessible()) {
try {
constructor.setAccessible(true);
}
catch (SecurityException se) {}
}
return constructor.newInstance(bytes);
} catch (Exception ex) {
throw new KryoException(ex);
}
}
if (length == 2) {
// fast-path optimizations for BigInteger constants
switch (bytes[0]) {
case 0:
return BigInteger.ZERO;
case 1:
return BigInteger.ONE;
case 10:
return BigInteger.TEN;
}
}
return new BigInteger(bytes);
}
}
/** Serializer for {@link BigDecimal} and any subclass.
* @author Tumi (enhacements) */
static public class BigDecimalSerializer extends Serializer {
private final BigIntegerSerializer bigIntegerSerializer = new BigIntegerSerializer();
{
setAcceptsNull(true);
setImmutable(true);
}
public void write (Kryo kryo, Output output, BigDecimal object) {
if (object == null) {
output.writeVarInt(NULL, true);
return;
}
BigDecimal value = (BigDecimal)object;
// fast-path optimizations for BigDecimal constants
if (value == BigDecimal.ZERO) {
bigIntegerSerializer.write(kryo, output, BigInteger.ZERO);
output.writeInt(0, false); // for backwards compatibility
return;
}
// default behaviour
bigIntegerSerializer.write(kryo, output, value.unscaledValue());
output.writeInt(value.scale(), false);
}
public BigDecimal read (Kryo kryo, Input input, Class type) {
BigInteger unscaledValue = bigIntegerSerializer.read(kryo, input, BigInteger.class);
if (unscaledValue == null) return null;
int scale = input.readInt(false);
if (type != BigDecimal.class && type != null) {
// For subclasses, use reflection
try {
Constructor constructor = type.getConstructor(BigInteger.class, int.class);
if (!constructor.isAccessible()) {
try {
constructor.setAccessible(true);
}
catch (SecurityException se) {}
}
return constructor.newInstance(unscaledValue, scale);
} catch (Exception ex) {
throw new KryoException(ex);
}
}
// fast-path optimizations for BigDecimal constants
if (unscaledValue == BigInteger.ZERO && scale == 0) {
return BigDecimal.ZERO;
}
// default behaviour
return new BigDecimal(unscaledValue, scale);
}
}
static public class ClassSerializer extends Serializer {
{
setImmutable(true);
setAcceptsNull(true);
}
public void write (Kryo kryo, Output output, Class object) {
kryo.writeClass(output, object);
output.writeByte((object != null && object.isPrimitive()) ? 1 : 0);
}
public Class read (Kryo kryo, Input input, Class type) {
Registration registration = kryo.readClass(input);
int isPrimitive = input.read();
Class typ = registration != null ? registration.getType() : null;
if (typ == null || !typ.isPrimitive()) return typ;
return (isPrimitive == 1) ? typ : getWrapperClass(typ);
}
}
/** Serializer for {@link Date}, {@link java.sql.Date}, {@link Time}, {@link Timestamp} and any other subclass.
* @author Tumi */
static public class DateSerializer extends Serializer {
private Date create(Kryo kryo, Class extends Date> type, long time) throws KryoException {
if (type == Date.class || type == null) {
return new Date(time);
}
if (type == Timestamp.class) {
return new Timestamp(time);
}
if (type == java.sql.Date.class) {
return new java.sql.Date(time);
}
if (type == Time.class) {
return new Time(time);
}
// other cases, reflection
try {
// Try to avoid invoking the no-args constructor
// (which is expected to initialize the instance with the current time)
Constructor extends Date> constructor = type.getConstructor(long.class);
if (!constructor.isAccessible()) {
try {
constructor.setAccessible(true);
}
catch (SecurityException se) {}
}
return constructor.newInstance(time);
} catch (Exception ex) {
// default strategy
Date d = (Date)kryo.newInstance(type);
d.setTime(time);
return d;
}
}
public void write (Kryo kryo, Output output, Date object) {
output.writeLong(object.getTime(), true);
}
public Date read (Kryo kryo, Input input, Class type) {
return create(kryo, type, input.readLong(true));
}
public Date copy (Kryo kryo, Date original) {
return create(kryo, original.getClass(), original.getTime());
}
}
static public class EnumSerializer extends Serializer {
{
setImmutable(true);
setAcceptsNull(true);
}
private Object[] enumConstants;
public EnumSerializer (Class extends Enum> type) {
enumConstants = type.getEnumConstants();
if (enumConstants == null) throw new IllegalArgumentException("The type must be an enum: " + type);
}
public void write (Kryo kryo, Output output, Enum object) {
if (object == null) {
output.writeVarInt(NULL, true);
return;
}
output.writeVarInt(object.ordinal() + 1, true);
}
public Enum read (Kryo kryo, Input input, Class type) {
int ordinal = input.readVarInt(true);
if (ordinal == NULL) return null;
ordinal--;
if (ordinal < 0 || ordinal > enumConstants.length - 1)
throw new KryoException("Invalid ordinal for enum \"" + type.getName() + "\": " + ordinal);
Object constant = enumConstants[ordinal];
return (Enum)constant;
}
}
static public class EnumSetSerializer extends Serializer {
public void write (Kryo kryo, Output output, EnumSet object) {
Serializer serializer;
if (object.isEmpty()) {
EnumSet tmp = EnumSet.complementOf(object);
if (tmp.isEmpty()) throw new KryoException("An EnumSet must have a defined Enum to be serialized.");
serializer = kryo.writeClass(output, tmp.iterator().next().getClass()).getSerializer();
} else {
serializer = kryo.writeClass(output, object.iterator().next().getClass()).getSerializer();
}
output.writeInt(object.size(), true);
for (Object element : object)
serializer.write(kryo, output, element);
}
public EnumSet read (Kryo kryo, Input input, Class type) {
Registration registration = kryo.readClass(input);
EnumSet object = EnumSet.noneOf(registration.getType());
Serializer serializer = registration.getSerializer();
int length = input.readInt(true);
for (int i = 0; i < length; i++)
object.add(serializer.read(kryo, input, null));
return object;
}
public EnumSet copy (Kryo kryo, EnumSet original) {
return EnumSet.copyOf(original);
}
}
/** @author Martin Grotzke */
static public class CurrencySerializer extends Serializer {
{
setImmutable(true);
setAcceptsNull(true);
}
public void write (Kryo kryo, Output output, Currency object) {
output.writeString(object == null ? null : object.getCurrencyCode());
}
public Currency read (Kryo kryo, Input input, Class type) {
String currencyCode = input.readString();
if (currencyCode == null) return null;
return Currency.getInstance(currencyCode);
}
}
/** @author Martin Grotzke */
static public class StringBufferSerializer extends Serializer {
{
setAcceptsNull(true);
}
public void write (Kryo kryo, Output output, StringBuffer object) {
output.writeString(object);
}
public StringBuffer read (Kryo kryo, Input input, Class type) {
String value = input.readString();
if (value == null) return null;
return new StringBuffer(value);
}
public StringBuffer copy (Kryo kryo, StringBuffer original) {
return new StringBuffer(original);
}
}
/** @author Martin Grotzke */
static public class StringBuilderSerializer extends Serializer {
{
setAcceptsNull(true);
}
public void write (Kryo kryo, Output output, StringBuilder object) {
output.writeString(object);
}
public StringBuilder read (Kryo kryo, Input input, Class type) {
return input.readStringBuilder();
}
public StringBuilder copy (Kryo kryo, StringBuilder original) {
return new StringBuilder(original);
}
}
static public class KryoSerializableSerializer extends Serializer {
public void write (Kryo kryo, Output output, KryoSerializable object) {
object.write(kryo, output);
}
public KryoSerializable read (Kryo kryo, Input input, Class type) {
KryoSerializable object = kryo.newInstance(type);
kryo.reference(object);
object.read(kryo, input);
return object;
}
}
/** Serializer for lists created via {@link Collections#emptyList()} or that were just assigned the
* {@link Collections#EMPTY_LIST}.
* @author Martin Grotzke */
static public class CollectionsEmptyListSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Object object) {
}
public Object read (Kryo kryo, Input input, Class type) {
return Collections.EMPTY_LIST;
}
}
/** Serializer for maps created via {@link Collections#emptyMap()} or that were just assigned the {@link Collections#EMPTY_MAP}.
* @author Martin Grotzke */
static public class CollectionsEmptyMapSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Object object) {
}
public Object read (Kryo kryo, Input input, Class type) {
return Collections.EMPTY_MAP;
}
}
/** Serializer for sets created via {@link Collections#emptySet()} or that were just assigned the {@link Collections#EMPTY_SET}.
* @author Martin Grotzke */
static public class CollectionsEmptySetSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, Object object) {
}
public Object read (Kryo kryo, Input input, Class type) {
return Collections.EMPTY_SET;
}
}
/** Serializer for lists created via {@link Collections#singletonList(Object)}.
* @author Martin Grotzke */
static public class CollectionsSingletonListSerializer extends Serializer {
{
setImmutable(true);
}
public void write (Kryo kryo, Output output, List object) {
kryo.writeClassAndObject(output, object.get(0));
}
public List read (Kryo kryo, Input input, Class type) {
return Collections.singletonList(kryo.readClassAndObject(input));
}
}
/** Serializer for maps created via {@link Collections#singletonMap(Object, Object)}.
* @author Martin Grotzke */
static public class CollectionsSingletonMapSerializer extends Serializer