96 lines
2.4 KiB
Java
96 lines
2.4 KiB
Java
![]() |
package eu.siacs.conversations.utils.zlib;
|
||
|
|
||
|
import java.io.IOException;
|
||
|
import java.io.OutputStream;
|
||
|
import java.lang.reflect.InvocationTargetException;
|
||
|
import java.lang.reflect.Method;
|
||
|
import java.security.NoSuchAlgorithmException;
|
||
|
import java.util.zip.Deflater;
|
||
|
import java.util.zip.DeflaterOutputStream;
|
||
|
|
||
|
/**
|
||
|
* <p>
|
||
|
* Android 2.2 includes Java7 FLUSH_SYNC option, which will be used by this
|
||
|
* Implementation, preferable via reflection. The @hide was remove in API level
|
||
|
* 19. This class might thus go away in the future.
|
||
|
* </p>
|
||
|
* <p>
|
||
|
* Please use {@link ZLibOutputStream#SUPPORTED} to check for flush
|
||
|
* compatibility.
|
||
|
* </p>
|
||
|
*/
|
||
|
public class ZLibOutputStream extends DeflaterOutputStream {
|
||
|
|
||
|
/**
|
||
|
* The reflection based flush method.
|
||
|
*/
|
||
|
|
||
|
private final static Method method;
|
||
|
/**
|
||
|
* SUPPORTED is true if a flush compatible method exists.
|
||
|
*/
|
||
|
public final static boolean SUPPORTED;
|
||
|
|
||
|
/**
|
||
|
* Static block to initialize {@link #SUPPORTED} and {@link #method}.
|
||
|
*/
|
||
|
static {
|
||
|
Method m = null;
|
||
|
try {
|
||
|
m = Deflater.class.getMethod("deflate", byte[].class, int.class,
|
||
|
int.class, int.class);
|
||
|
} catch (SecurityException e) {
|
||
|
} catch (NoSuchMethodException e) {
|
||
|
}
|
||
|
method = m;
|
||
|
SUPPORTED = (method != null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a new ZLib compatible output stream wrapping the given low level
|
||
|
* stream. ZLib compatiblity means we will send a zlib header.
|
||
|
*
|
||
|
* @param os
|
||
|
* OutputStream The underlying stream.
|
||
|
* @throws IOException
|
||
|
* In case of a lowlevel transfer problem.
|
||
|
* @throws NoSuchAlgorithmException
|
||
|
* In case of a {@link Deflater} error.
|
||
|
*/
|
||
|
public ZLibOutputStream(OutputStream os) throws IOException,
|
||
|
NoSuchAlgorithmException {
|
||
|
super(os, new Deflater(Deflater.BEST_COMPRESSION));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Flush the given stream, preferring Java7 FLUSH_SYNC if available.
|
||
|
*
|
||
|
* @throws IOException
|
||
|
* In case of a lowlevel exception.
|
||
|
*/
|
||
|
@Override
|
||
|
public void flush() throws IOException {
|
||
|
if (!SUPPORTED) {
|
||
|
super.flush();
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
int count = 0;
|
||
|
do {
|
||
|
count = (Integer) method.invoke(def, buf, 0, buf.length, 3);
|
||
|
if (count > 0) {
|
||
|
out.write(buf, 0, count);
|
||
|
}
|
||
|
} while (count > 0);
|
||
|
} catch (IllegalArgumentException e) {
|
||
|
throw new IOException("Can't flush");
|
||
|
} catch (IllegalAccessException e) {
|
||
|
throw new IOException("Can't flush");
|
||
|
} catch (InvocationTargetException e) {
|
||
|
throw new IOException("Can't flush");
|
||
|
}
|
||
|
super.flush();
|
||
|
}
|
||
|
|
||
|
}
|