package org.jboss.remoting.loading;
import java.io.Externalizable;
public class CompressedClassBytes extends ClassBytes implements Externalizable
{
static final long serialVersionUID = 5984363018051268886L;
private static final int MIN_COMPRESS = Integer.parseInt(System.getProperty("jboss.remoting.compression.min","1000"));
private static final boolean DEBUG = Boolean.getBoolean("jboss.remoting.compression.debug");
private int compressionLevel;
private int compressedSize;
private int originalSize;
public CompressedClassBytes ()
{
super(null,null);
}
public CompressedClassBytes (String className, byte data[], int compressionLevel)
{
super (className, data);
this.compressionLevel = compressionLevel;
}
public static void main (String args[])
{
try
{
String string = new String("Hello,world - this is a test of compression, not sure what will happen. alskjfdalksjflkajsdfljaslkfjaslkdjflksajflkajsfdlkjsalkfjaslkfdjlksajflkasjfdlkajslkfjsalkfjasldfjlksadjflkasjfdlkajdsf");
byte buf [] = org.jboss.remoting.loading.ClassUtil.serialize(string);
CompressedClassBytes cb=new CompressedClassBytes("java.lang.String",buf,9);
byte b1[]=org.jboss.remoting.loading.ClassUtil.serialize(cb);
Object obj = ClassUtil.deserialize(b1,ClassLoader.getSystemClassLoader());
}
catch (Throwable ex)
{
ex.printStackTrace();
}
}
public void readExternal (java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException
{
compressionLevel = in.readInt();
originalSize = in.readInt();
compressedSize = in.readInt();
byte buf[] = new byte[compressedSize];
int count = in.read(buf,0,compressedSize);
if (compressedSize!=originalSize)
{
this.classBytes = uncompress(buf);
}
else
{
this.classBytes = buf;
}
if (DEBUG)
{
System.err.println("<< reading compressed: "+compressedSize+", original: "+originalSize+", compressionLevel:"+compressionLevel);
}
this.className = (String)in.readObject();
}
public void writeExternal (java.io.ObjectOutput out) throws java.io.IOException
{
out.writeInt(compressionLevel);
out.writeInt(classBytes.length);
byte compressed [] = compress(classBytes);
out.writeInt(compressed.length);
out.write(compressed);
out.writeObject(className);
out.flush();
}
public byte[] compress (byte[] input)
{
if (input.length < MIN_COMPRESS)
return input;
java.util.zip.Deflater deflater = new java.util.zip.Deflater (compressionLevel);
deflater.setInput (input, 0, input.length);
deflater.finish ();
byte[] buff = new byte[input.length + 50];
deflater.deflate (buff);
int compressedSize = deflater.getTotalOut ();
if (deflater.getTotalIn () != input.length)
{
if (DEBUG)
{
System.err.println(">> Attempting compression and the data didn't compress well, returning original");
}
return input;
}
if (compressedSize >= input.length - 4)
{
if (DEBUG)
{
System.err.println(">> Compressed size is larger than original .. ?");
}
return input;
}
byte[] output = new byte[compressedSize + 4];
System.arraycopy (buff, 0, output, 4, compressedSize);
output[0] = (byte) (input.length >> 24);
output[1] = (byte) (input.length >> 16);
output[2] = (byte) (input.length >> 8);
output[3] = (byte) (input.length);
if (DEBUG)
{
System.err.println(">> writing compressed: "+output.length+", original: "+classBytes.length+", compressionLevel:"+compressionLevel);
}
return output;
}
public byte[] uncompress (byte[] input) throws java.io.IOException
{
try
{
int uncompressedSize =
(((input[0] & 0xff) << 24) +
((input[1] & 0xff) << 16) +
((input[2] & 0xff) << 8) +
((input[3] & 0xff)));
java.util.zip.Inflater inflater = new java.util.zip.Inflater ();
inflater.setInput (input, 4, input.length - 4);
inflater.finished ();
byte[] out = new byte[uncompressedSize];
inflater.inflate (out);
inflater.reset ();
return out;
}
catch (java.util.zip.DataFormatException e)
{
throw new java.io.IOException ("Input Stream is corrupt: " + e);
}
}
}