Package com.esotericsoftware.kryo.serializers

Source Code of com.esotericsoftware.kryo.serializers.MapSerializer

package com.esotericsoftware.kryo.serializers;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/** Serializes objects that implement the {@link Map} interface.
* <p>
* With the default constructor, a map requires a 1-3 byte header and an extra 4 bytes is written for each key/value pair.
* @author Nathan Sweet <misc@n4te.com> */
public class MapSerializer extends Serializer<Map> {
  private Class keyClass, valueClass;
  private Serializer keySerializer, valueSerializer;
  private boolean keysCanBeNull = true, valuesCanBeNull = true;
  private Class keyGenericType, valueGenericType;

  /** @param keysCanBeNull False if all keys are not null. This saves 1 byte per key if keyClass is set. True if it is not known
   *           (default). */
  public void setKeysCanBeNull (boolean keysCanBeNull) {
    this.keysCanBeNull = keysCanBeNull;
  }

  /** @param keyClass The concrete class of each key. This saves 1 byte per key. Set to null if the class is not known or varies
   *           per key (default).
   * @param keySerializer The serializer to use for each key. */
  public void setKeyClass (Class keyClass, Serializer keySerializer) {
    this.keyClass = keyClass;
    this.keySerializer = keySerializer;
  }

  /** @param valueClass The concrete class of each value. This saves 1 byte per value. Set to null if the class is not known or
   *           varies per value (default).
   * @param valueSerializer The serializer to use for each value. */
  public void setValueClass (Class valueClass, Serializer valueSerializer) {
    this.valueClass = valueClass;
    this.valueSerializer = valueSerializer;
  }

  /** @param valuesCanBeNull True if values are not null. This saves 1 byte per value if keyClass is set. False if it is not known
   *           (default). */
  public void setValuesCanBeNull (boolean valuesCanBeNull) {
    this.valuesCanBeNull = valuesCanBeNull;
  }

  public void setGenerics (Kryo kryo, Class[] generics) {
    keyGenericType = null;
    valueGenericType = null;
   
    if (generics != null && generics.length > 0) {
      if (generics[0] != null && kryo.isFinal(generics[0])) keyGenericType = generics[0];
      if (generics.length > 1 && generics[1] != null && kryo.isFinal(generics[1])) valueGenericType = generics[1];
    }
  }

  public void write (Kryo kryo, Output output, Map map) {
    int length = map.size();
    output.writeInt(length, true);

    Serializer keySerializer = this.keySerializer;
    if (keyGenericType != null) {
      if (keySerializer == null) keySerializer = kryo.getSerializer(keyGenericType);
      keyGenericType = null;
    }
    Serializer valueSerializer = this.valueSerializer;
    if (valueGenericType != null) {
      if (valueSerializer == null) valueSerializer = kryo.getSerializer(valueGenericType);
      valueGenericType = null;
    }

    for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
      Entry entry = (Entry)iter.next();
      if (keySerializer != null) {
        if (keysCanBeNull)
          kryo.writeObjectOrNull(output, entry.getKey(), keySerializer);
        else
          kryo.writeObject(output, entry.getKey(), keySerializer);
      } else
        kryo.writeClassAndObject(output, entry.getKey());
      if (valueSerializer != null) {
        if (valuesCanBeNull)
          kryo.writeObjectOrNull(output, entry.getValue(), valueSerializer);
        else
          kryo.writeObject(output, entry.getValue(), valueSerializer);
      } else
        kryo.writeClassAndObject(output, entry.getValue());
    }
  }

  /** Used by {@link #read(Kryo, Input, Class)} to create the new object. This can be overridden to customize object creation, eg
   * to call a constructor with arguments. The default implementation uses {@link Kryo#newInstance(Class)}. */
  protected Map create (Kryo kryo, Input input, Class<Map> type) {
    return kryo.newInstance(type);
  }

  public Map read (Kryo kryo, Input input, Class<Map> type) {
    Map map = create(kryo, input, type);
    int length = input.readInt(true);

    Class keyClass = this.keyClass;
    Class valueClass = this.valueClass;

    Serializer keySerializer = this.keySerializer;
    if (keyGenericType != null) {
      keyClass = keyGenericType;
      if (keySerializer == null) keySerializer = kryo.getSerializer(keyClass);
      keyGenericType = null;
    }
    Serializer valueSerializer = this.valueSerializer;
    if (valueGenericType != null) {
      valueClass = valueGenericType;
      if (valueSerializer == null) valueSerializer = kryo.getSerializer(valueClass);
      valueGenericType = null;
    }

    kryo.reference(map);

    for (int i = 0; i < length; i++) {
      Object key;
      if (keySerializer != null) {
        if (keysCanBeNull)
          key = kryo.readObjectOrNull(input, keyClass, keySerializer);
        else
          key = kryo.readObject(input, keyClass, keySerializer);
      } else
        key = kryo.readClassAndObject(input);
      Object value;
      if (valueSerializer != null) {
        if (valuesCanBeNull)
          value = kryo.readObjectOrNull(input, valueClass, valueSerializer);
        else
          value = kryo.readObject(input, valueClass, valueSerializer);
      } else
        value = kryo.readClassAndObject(input);
      map.put(key, value);
    }
    return map;
  }

  protected Map createCopy (Kryo kryo, Map original) {
    return kryo.newInstance(original.getClass());
  }

  public Map copy (Kryo kryo, Map original) {
    Map copy = createCopy(kryo, original);
    for (Iterator iter = original.entrySet().iterator(); iter.hasNext();) {
      Entry entry = (Entry)iter.next();
      copy.put(kryo.copy(entry.getKey()), kryo.copy(entry.getValue()));
    }
    return copy;
  }
}
TOP

Related Classes of com.esotericsoftware.kryo.serializers.MapSerializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.