package org.simantics.databoard.serialization.impl; import gnu.trove.map.hash.TObjectIntHashMap; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.List; import java.util.TreeSet; import org.simantics.databoard.binding.MapBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.util.IsReferableQuery; import org.simantics.databoard.binding.util.Result; import org.simantics.databoard.serialization.SerializationException; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.serialization.Serializer.CompositeSerializer; public class MapSerializer extends CompositeSerializer { Integer fixedSizeOfKey, fixedSizeOfValue, fixedSizeOfEntry; public Serializer keySerializer, valueSerializer; MapBinding binding; /** * * @param binding * @param keySerializer (optional) can be set later * @param valueSerializer (optional) can be set later */ public MapSerializer(MapBinding binding, Serializer keySerializer, Serializer valueSerializer) { super( IsReferableQuery.isReferable( binding.type() ) != Result.No ); this.keySerializer = keySerializer; this.valueSerializer = valueSerializer; this.binding = binding; } @Override public void finalizeConstruction() { fixedSizeOfKey = keySerializer.getConstantSize(); fixedSizeOfValue = valueSerializer.getConstantSize(); fixedSizeOfEntry = (fixedSizeOfKey!=null && fixedSizeOfValue!=null) ? (fixedSizeOfKey+fixedSizeOfValue) : null; } @Override public Object deserialize(DataInput in, List identities) throws IOException{ try { int length = in.readInt(); if (length<0) throw new SerializationException("Cannot use negative array length"); assertRemainingBytes(in, (long)length*((long)keySerializer.getMinSize()+(long)valueSerializer.getMinSize())); Object keys[] = new Object[length]; Object values[] = new Object[length]; for(int i=0;i identities, Object obj) throws IOException { try { TreeSet oldKeys = new TreeSet( binding.getKeyBinding() ); binding.getKeys(obj, oldKeys); int length = in.readInt(); if (length<0) throw new SerializationException("Cannot use negative array length"); assertRemainingBytes(in, (long)length*((long)keySerializer.getMinSize()+(long)valueSerializer.getMinSize())); for(int i=0;i identities) throws IOException, SerializationException { int length = in.readInt(); if (fixedSizeOfEntry!=null) { in.skipBytes( length * fixedSizeOfEntry ); return; } for(int i=0;i identities, Object map) throws IOException { try { int length = binding.size(map); //if (binding.isOrderedMap(map)) { Object[] keys = new Object[length]; Object[] values = new Object[length]; binding.getAll(map, keys, values); out.writeInt(length); for(int i=0;i copyMap = new TreeMap(binding.getKeyBinding()); binding.getAll(map, copyMap); Iterator> iter = copyMap.entrySet().iterator(); putLength(out, length); while (iter.hasNext()) { Entry e = iter.next(); Object key = e.getKey(); Object value = e.getValue(); keySerializer.serialize(out, identities, key); valueSerializer.serialize(out, identities, value); } }*/ } catch (BindingException e) { throw new IOException( e ); } } @Override public Integer getConstantSize() { return null; } @Override public int getSize(Object obj, TObjectIntHashMap identities) throws IOException { try { int length = binding.size(obj); if (fixedSizeOfEntry!=null) return 4 + fixedSizeOfEntry * length; int result = 4; Object keys[] = binding.getKeys(obj); for(int i=0;i