StandardSerializer

来源:互联网 发布:lable java 编辑:程序博客网 时间:2024/06/05 18:28

StandardSerializer implements 2 interfaces.
* Serializer

public interface Serializer extends AttributeHandler, Closeable {    public Object readClassAndObject(ScanBuffer buffer);    public <T> T readObject(ScanBuffer buffer, Class<T> type);    public <T> T readObjectByteOrder(ScanBuffer buffer, Class<T> type);    public <T> T readObjectNotNull(ScanBuffer buffer, Class<T> type);    public DataOutput getDataOutput(int initialCapacity);}

ScanBuffer

Scan Buffer allows sequential reads. Should not be used by multiple threads.

public interface ScanBuffer {    public boolean hasRemaining();    public byte getByte();    public boolean getBoolean();    public short getShort();    public int getInt();    public long getLong();    public char getChar();    public float getFloat();    public double getDouble();    public byte[] getBytes(int length);    public short[] getShorts(int length);    public int[] getInts(int length);    public long[] getLongs(int length);    public char[] getChars(int length);    public float[] getFloats(int length);    public double[] getDoubles(int length);}

WriteBuffer

WriteBuffer is a Buffer that allows simple writes and returns the result as a {@link StaticBuffer}.

public interface WriteBuffer {    public WriteBuffer putByte(byte val);    public WriteBuffer putBytes(byte[] val);    public WriteBuffer putBytes(StaticBuffer val);    public WriteBuffer putBoolean(boolean val);    public WriteBuffer putShort(short val);    public WriteBuffer putInt(int val);    public WriteBuffer putLong(long val);    public WriteBuffer putChar(char val);    public WriteBuffer putFloat(float val);    public WriteBuffer putDouble(double val);    public StaticBuffer getStaticBuffer();    public int getPosition();    public StaticBuffer getStaticBufferFlipBytes(int from, int to);}
  • AttributeHandler
public interface AttributeHandler {    public <T> void registerClass(int registrationNo, Class<T> type, AttributeSerializer<T> attributeHandler);    public boolean validDataType(Class datatype);    public<V> void verifyAttribute(Class<V> datatype, Object value);    /**     * Converts the given (not-null) value to the this datatype V.     * The given object will NOT be of type V.     * Throws an {@link IllegalArgumentException} if it cannot be converted.     *     * @param value to convert     * @return converted to expected datatype     */    public<V> V convert(Class<V> datatype, Object value);    public boolean isOrderPreservingDatatype(Class<?> datatype);}
  • Fields List
/**  * This offset is used by user registration to make sure they don't collide with internal class  * registrations. It must be ensured that this number is LARGER than any internally used  * registration number.  * This value may NEVER EVER be changed or compatibility to older versions breaks  */ private static final int CLASS_REGISTRATION_OFFSET = 100; private static final int MAX_REGISTRATION_NO = 100000; private final BiMap<Integer,Class> registrations = new HashMap<>(60);  /*  * A {@link BiMap} backed by two hash tables. This implementation allows null keys and values. A  * {@code HashBiMap} and its inverse are both serializable.  */ private final Map<Class,AttributeSerializer> handlers = HashBiMap.create(60);

Then resister a large amount of serializer.

registerClassInternal(11,Short.class, new ShortSerializer());public synchronized <V> void registerClassInternal(int registrationNo, Class<? extends V> datatype, AttributeSerializer<V> serializer) {        registrations.put(registrationNo, datatype);        if (serializer instanceof SerializerInjected) ((SerializerInjected)serializer).setSerializer(this);        handlers.put(datatype, serializer);    }

SerializerInjected uses the StandardSerializer to read the content from ScanBuffer. Take
ParameterSerializer for example.

public class ParameterSerializer implements AttributeSerializer<Parameter>, SerializerInjected {    private Serializer serializer;    @Override    public Parameter read(ScanBuffer buffer) {        String key = serializer.readObjectNotNull(buffer,String.class);        Object value = serializer.readClassAndObject(buffer);        return new Parameter(key,value);    }    @Override    public void write(WriteBuffer buffer, Parameter attribute) {        DataOutput out = (DataOutput)buffer;        out.writeObjectNotNull(attribute.key());        out.writeClassAndObject(attribute.value());    }    @Override    public void setSerializer(Serializer serializer) {        Preconditions.checkNotNull(serializer);        this.serializer=serializer;    }}

Take ShortSerializer for example.

registerClassInternal(11,Short.class, new ShortSerializer());registerClassInternal(18,String.class, new StringSerializer()); //supports null serialization
public class ShortSerializer implements OrderPreservingSerializer<Short>  {    private static final long serialVersionUID = 117423419862504186L;    @Override    public Short read(ScanBuffer buffer) {        return Short.valueOf((short)(buffer.getShort() + Short.MIN_VALUE));    }    @Override    public void write(WriteBuffer out, Short object) {        out.putShort((short)(object.shortValue() - Short.MIN_VALUE));    }    @Override    public Short readByteOrder(ScanBuffer buffer) {        return read(buffer);    }    @Override    public void writeByteOrder(WriteBuffer buffer, Short attribute) {        write(buffer,attribute);    }    /*    ====== These methods apply to all whole numbers with minor modifications ========    ====== byte, short, int, long ======     */    @Override    public Short convert(Object value) {        if (value instanceof Number) {            double d = ((Number)value).doubleValue();            if (Double.isNaN(d) || Math.round(d)!=d) throw new IllegalArgumentException("Not a valid short: " + value);            long l = ((Number)value).longValue();            if (l>=Short.MIN_VALUE && l<=Short.MAX_VALUE) return Short.valueOf((short)l);            else throw new IllegalArgumentException("Value too large for short: " + value);        } else if (value instanceof String) {            return Short.parseShort((String)value);        } else return null;    }}

Method getDataOutput in StandardSerializer.

public DataOutput getDataOutput(int initialCapacity) {       return new StandardDataOutput(initialCapacity);   }
  • writeObject
@Override        public DataOutput writeObject(Object object, Class type) {            return writeObjectInternal(object,type,false);        }
  • writeObjectInternal
private DataOutput writeObjectInternal(Object object, Class type, boolean byteOrder) {            if (supportsNullSerialization(type)) {                AttributeSerializer s = getSerializer(type);                if (byteOrder) ensureOrderPreserving(s,type).writeByteOrder(this,object);                else s.write(this, object);            } else {                //write flag for null or not                if (object==null) {                    putByte((byte)-1);                } else {                    putByte((byte)0);                    writeObjectNotNullInternal(object,byteOrder);                }            }            return this;        }
  • supportsNullSerialization
private boolean supportsNullSerialization(Class type) {        return getSerializer(type) instanceof SupportsNullSerializer;    }

When write a object, you must call getDataOutput to get a DataOutput object.
Then call writeObject method of DataOutput to write a object.
At last to get a StaticBuffer object by call getStaticBufferFlipBytes(int from, int to);
Meanwhile we call readObject method of StandardSerializer to read a object, pass StaticBuffer object as a parameter.
* Method readObject is a member of StandardSerializer.

public <T> T readObject(ScanBuffer buffer, Class<T> type) {        return readObjectInternal(buffer,type,false);    }
1 0
原创粉丝点击