/** * */ package net.varkhan.base.conversion.serializer.composite; import net.varkhan.base.conversion.serializer.DecodingException; import net.varkhan.base.conversion.serializer.EncodingException; import net.varkhan.base.conversion.serializer.Serializer; import net.varkhan.base.conversion.serializer.primitives.VariadicSerializer; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Array; import java.nio.ByteBuffer; /** * <b>Generic array serializer</b>. * <p/> * Serializes an array of objects. * <p/> * * @author varkhan * @date Nov 7, 2010 * @time 11:58:15 PM */ public class ArraySerializer<S,C> implements Serializer<S[],C> { private final Class<S> type; private final Serializer<S,C> serializer; /** * @param serializer the underlying type serializer */ @SuppressWarnings("unchecked") public ArraySerializer(Serializer<S,C> serializer) { this.type=(Class<S>) Object.class; this.serializer=serializer; } /** * @param type the array element type * @param serializer the underlying type serializer */ public ArraySerializer(Class<S> type, Serializer<S,C> serializer) { this.type=type; this.serializer=serializer; } public S[] decode(InputStream stm, C ctx) { long l=VariadicSerializer._decode(stm); @SuppressWarnings("unchecked") S[] v=(S[]) Array.newInstance(type, (int) l); int i=0; while(i<l) { v[i++]=serializer.decode(stm, ctx); } return v; } public S[] decode(ByteBuffer buf, C ctx) { long l=VariadicSerializer._decode(buf); @SuppressWarnings("unchecked") S[] v=(S[]) Array.newInstance(type, (int) l); int i=0; while(i<l) { v[i++]=serializer.decode(buf, ctx); } return v; } public S[] decode(byte[] dat, long pos, long len, C ctx) { long l=VariadicSerializer._decode(dat, pos, len); long c=VariadicSerializer._length(l); @SuppressWarnings("unchecked") S[] obj=(S[]) Array.newInstance(type, (int) l); int i=0; while(i<l && c<len) { S v=serializer.decode(dat, pos+c, len-c, ctx); c+=serializer.length(v, ctx); obj[i++]=v; } if(i<l) throw new DecodingException("Buffer underflow: "+i+" elements out of "+l); return obj; } public long encode(S[] obj, OutputStream stm, C ctx) { long c=VariadicSerializer._encode(obj.length, stm); for(S v : obj) c+=serializer.encode(v, stm, ctx); return c; } public long encode(S[] obj, ByteBuffer buf, C ctx) { long c=VariadicSerializer._encode(obj.length, buf); for(S v : obj) c+=serializer.encode(v, buf, ctx); return c; } public long encode(S[] obj, byte[] dat, long pos, long len, C ctx) { long c=VariadicSerializer._encode(obj.length, dat, pos, len); int i=0; while(i<obj.length && c<len) { S v=obj[i++]; c+=serializer.encode(v, dat, pos+c, len-c, ctx); } if(i<obj.length) throw new EncodingException("Buffer overflow: "+i+" characters out of "+obj.length); return c; } public long length(S[] obj, C ctx) { long c=VariadicSerializer._length(obj.length); for(S v : obj) c+=serializer.length(v, ctx); return c; } }