aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java')
-rw-r--r--src/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java b/src/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java
new file mode 100644
index 00000000..f2bff9fd
--- /dev/null
+++ b/src/eu/siacs/conversations/utils/zlib/ZLibOutputStream.java
@@ -0,0 +1,89 @@
+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;
+ }
+ int count = 0;
+ if (!def.needsInput()) {
+ do {
+ count = def.deflate(buf, 0, buf.length);
+ out.write(buf, 0, count);
+ } while (count > 0);
+ out.flush();
+ }
+ try {
+ do {
+ count = (Integer) method.invoke(def, buf, 0, buf.length, 2);
+ 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();
+ }
+
+}