package org.jivesoftware.smack.compression;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
   private static final Method method;
   private static final boolean supported;
   private static final int compressionLevel = -1;
   private static final int SYNC_FLUSH_INT = 2;
   private static final int FULL_FLUSH_INT = 3;

   public Java7ZlibInputOutputStream() {
      super("zlib");
   }

   public boolean isSupported() {
      return supported;
   }

   public InputStream getInputStream(InputStream inputStream) {
      return new InflaterInputStream(inputStream, new Inflater(), 512) {
         public int available() throws IOException {
            return this.inf.needsInput() ? 0 : super.available();
         }
      };
   }

   public OutputStream getOutputStream(OutputStream outputStream) {
      final byte flushMethodInt;
      if (flushMethod == XMPPInputOutputStream.FlushMethod.SYNC_FLUSH) {
         flushMethodInt = 2;
      } else {
         flushMethodInt = 3;
      }

      return new DeflaterOutputStream(outputStream, new Deflater(-1)) {
         public void flush() throws IOException {
            if (!Java7ZlibInputOutputStream.supported) {
               super.flush();
            } else {
               int count;
               try {
                  while((count = (Integer)Java7ZlibInputOutputStream.method.invoke(this.def, this.buf, 0, this.buf.length, Integer.valueOf(flushMethodInt))) != 0) {
                     this.out.write(this.buf, 0, count);
                  }
               } catch (IllegalArgumentException var2) {
                  throw new IOException("Can't flush");
               } catch (IllegalAccessException var3) {
                  throw new IOException("Can't flush");
               } catch (InvocationTargetException var4) {
                  throw new IOException("Can't flush");
               }

               super.flush();
            }
         }
      };
   }

   static {
      Method m = null;

      try {
         m = Deflater.class.getMethod("deflate", byte[].class, Integer.TYPE, Integer.TYPE, Integer.TYPE);
      } catch (SecurityException var2) {
      } catch (NoSuchMethodException var3) {
      }

      method = m;
      supported = method != null;
   }
}
