--- /home/cpdev/src/classpath/java/util/zip/Deflater.java	2005-07-02 21:03:49.000000000 +0000
+++ java/util/zip/Deflater.java	2005-06-30 05:34:52.000000000 +0000
@@ -37,6 +37,8 @@
 
 package java.util.zip;
 
+import gnu.gcj.RawData;
+
 /**
  * This is the Deflater class.  The deflater class compresses input
  * with the deflate algorithm described in RFC 1951.  It has several
@@ -91,72 +93,20 @@
    */
   public static final int DEFLATED = 8;
 
-  /*
-   * The Deflater can do the following state transitions:
-   *
-   * (1) -> INIT_STATE   ----> INIT_FINISHING_STATE ---.
-   *        /  | (2)      (5)                         |
-   *       /   v          (5)                         |
-   *   (3)| SETDICT_STATE ---> SETDICT_FINISHING_STATE |(3)
-   *       \   | (3)                 |        ,-------'
-   *        |  |                     | (3)   /
-   *        v  v          (5)        v      v
-   * (1) -> BUSY_STATE   ----> FINISHING_STATE
-   *                                | (6)
-   *                                v
-   *                           FINISHED_STATE
-   *    \_____________________________________/
-   *          | (7)
-   *          v
-   *        CLOSED_STATE
-   *
-   * (1) If we should produce a header we start in INIT_STATE, otherwise
-   *     we start in BUSY_STATE.
-   * (2) A dictionary may be set only when we are in INIT_STATE, then
-   *     we change the state as indicated.
-   * (3) Whether a dictionary is set or not, on the first call of deflate
-   *     we change to BUSY_STATE.
-   * (4) -- intentionally left blank -- :)
-   * (5) FINISHING_STATE is entered, when flush() is called to indicate that
-   *     there is no more INPUT.  There are also states indicating, that
-   *     the header wasn't written yet.
-   * (6) FINISHED_STATE is entered, when everything has been flushed to the
-   *     internal pending output buffer.
-   * (7) At any time (7)
-   * 
-   */
-
-  private static final int IS_SETDICT              = 0x01;
-  private static final int IS_FLUSHING             = 0x04;
-  private static final int IS_FINISHING            = 0x08;
-  
-  private static final int INIT_STATE              = 0x00;
-  private static final int SETDICT_STATE           = 0x01;
-  private static final int INIT_FINISHING_STATE    = 0x08;
-  private static final int SETDICT_FINISHING_STATE = 0x09;
-  private static final int BUSY_STATE              = 0x10;
-  private static final int FLUSHING_STATE          = 0x14;
-  private static final int FINISHING_STATE         = 0x1c;
-  private static final int FINISHED_STATE          = 0x1e;
-  private static final int CLOSED_STATE            = 0x7f;
-
   /** Compression level. */
   private int level;
 
-  /** should we include a header. */
-  private boolean noHeader;
+  /** Compression strategy. */
+  private int strategy;
 
-  /** The current state. */
-  private int state;
+  /** The zlib stream. */
+  private RawData zstream;
 
-  /** The total bytes of output written. */
-  private int totalOut;
- 
-  /** The pending output. */
-  private DeflaterPending pending;
+  /** True if finished. */
+  private boolean is_finished;
 
-  /** The deflater engine. */
-  private DeflaterEngine engine;
+  /** `Flush' flag to pass to next call to deflate. */
+  private int flush_flag;
 
   /**
    * Creates a new deflater with default compression level.
@@ -186,33 +136,23 @@
    * useful for the GZIP format.
    * @exception IllegalArgumentException if lvl is out of range.
    */
-  public Deflater(int lvl, boolean nowrap)
+  public Deflater(int lvl, boolean noHeader)
   {
-    if (lvl == DEFAULT_COMPRESSION)
-      lvl = 6;
-    else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION)
-      throw new IllegalArgumentException();
-
-    pending = new DeflaterPending();
-    engine = new DeflaterEngine(pending);
-    this.noHeader = nowrap;
-    setStrategy(DEFAULT_STRATEGY);
+    this.strategy = DEFAULT_STRATEGY;
+    init(lvl, noHeader);
     setLevel(lvl);
-    reset();
   }
 
+  private native void init(int level, boolean noHeader);
+  
+  private native void update();
+
   /** 
    * Resets the deflater.  The deflater acts afterwards as if it was
    * just created with the same compression level and strategy as it
    * had before.  
    */
-  public void reset() 
-  {
-    state = (noHeader ? BUSY_STATE : INIT_STATE);
-    totalOut = 0;
-    pending.reset();
-    engine.reset();
-  }
+  public native void reset();
   
   /**
    * Frees all objects allocated by the compressor.  There's no
@@ -223,55 +163,30 @@
    * <i>undefined</i>.  
    * @deprecated Just clear all references to deflater instead.
    */
-  public void end()
-  {
-    engine = null;
-    pending = null;
-    state = CLOSED_STATE;
-  }
+  public native void end();
 
   /** 
    * Gets the current adler checksum of the data that was processed so
    * far.
    */
-  public int getAdler()
-  {
-    return engine.getAdler();
-  }
+  public native int getAdler();
 
   /** 
    * Gets the number of input bytes processed so far.
    */
-  public int getTotalIn()
-  {
-    return engine.getTotalIn();
-  }
+  public native int getTotalIn();
 
   /** 
    * Gets the number of output bytes so far.
    */
-  public int getTotalOut()
-  {
-    return totalOut;
-  }
+  public native int getTotalOut();
 
   /** 
    * Finalizes this object.
    */
   protected void finalize()
   {
-    /* Exists solely for compatibility.  We don't have any native state. */
-  }
-
-  /** 
-   * Flushes the current input block.  Further calls to deflate() will
-   * produce enough output to inflate everything in the current input
-   * block.  This is not part of Sun's JDK so I have made it package
-   * private.  It is used by DeflaterOutputStream to implement
-   * flush().
-   */
-  void flush() {
-    state |= IS_FLUSHING;
+    end();
   }
 
   /** 
@@ -279,17 +194,15 @@
    * to give more input after this method was called.  This method must
    * be called to force all bytes to be flushed.
    */
-  public void finish() {
-    state |= IS_FLUSHING | IS_FINISHING;
-  }
+  public native void finish();
 
   /** 
    * Returns true iff the stream was finished and no more output bytes
    * are available.
    */
-  public boolean finished()
+  public synchronized boolean finished()
   {
-    return state == FINISHED_STATE && pending.isFlushed();
+    return is_finished;
   }
 
   /**
@@ -299,10 +212,7 @@
    * <em>NOTE</em>: This method can also return true when the stream
    * was finished.  
    */
-  public boolean needsInput()
-  {
-    return engine.needsInput();
-  }
+  public native boolean needsInput();
 
   /**
    * Sets the data which should be compressed next.  This should be only
@@ -331,12 +241,7 @@
    * @exception IllegalStateException if the buffer was finished() or ended()
    * or if previous input is still pending.
    */
-  public void setInput(byte[] input, int off, int len)
-  {
-    if ((state & IS_FINISHING) != 0)
-      throw new IllegalStateException("finish()/end() already called");
-    engine.setInput(input, off, len);
-  }
+  public native void setInput(byte[] input, int off, int len);
 
   /** 
    * Sets the compression level.  There is no guarantee of the exact
@@ -345,19 +250,12 @@
    * before the end of the so far given input.  
    * @param lvl the new compression level.
    */
-  public void setLevel(int lvl)
+  public synchronized void setLevel(int lvl)
   {
-    if (lvl == DEFAULT_COMPRESSION)
-      lvl = 6;
-    else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION)
+    if (lvl != -1 && (lvl < 0 || lvl > 9))
       throw new IllegalArgumentException();
-
-
-    if (level != lvl)
-      {
-	level = lvl;
-	engine.setLevel(lvl);
-      }
+    level = (lvl == -1) ? 6 : lvl;
+    update();
   }
 
   /** 
@@ -367,12 +265,13 @@
    * setLevel() applies.
    * @param stgy the new compression strategy.
    */
-  public void setStrategy(int stgy)
+  public synchronized void setStrategy(int stgy)
   {
     if (stgy != DEFAULT_STRATEGY && stgy != FILTERED
 	&& stgy != HUFFMAN_ONLY)
       throw new IllegalArgumentException();
-    engine.setStrategy(stgy);
+    strategy = stgy;
+    update();
   }
 
   /**
@@ -397,91 +296,7 @@
    * @exception IndexOutOfBoundsException if offset and/or length
    * don't match the array length.  
    */
-  public int deflate(byte[] output, int offset, int length)
-  {
-    int origLength = length;
-
-    if (state == CLOSED_STATE)
-      throw new IllegalStateException("Deflater closed");
-
-    if (state < BUSY_STATE)
-      {
-	/* output header */
-	int header = (DEFLATED + 
-		      ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
-	int level_flags = (level - 1) >> 1;
-	if (level_flags < 0 || level_flags > 3) 
-	  level_flags = 3;
-	header |= level_flags << 6;
-	if ((state & IS_SETDICT) != 0)
-	  /* Dictionary was set */
-	  header |= DeflaterConstants.PRESET_DICT;
-	header += 31 - (header % 31);
-
-	pending.writeShortMSB(header);
-	if ((state & IS_SETDICT) != 0)
-	  {
-	    int chksum = engine.getAdler();
-	    engine.resetAdler();
-	    pending.writeShortMSB(chksum >> 16);
-	    pending.writeShortMSB(chksum & 0xffff);
-	  }
-
-	state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
-      }
-
-    for (;;)
-      {
-	int count = pending.flush(output, offset, length);
-	offset += count;
-	totalOut += count;
-	length -= count;
-	if (length == 0 || state == FINISHED_STATE)
-	  break;
-
-	if (!engine.deflate((state & IS_FLUSHING) != 0, 
-			    (state & IS_FINISHING) != 0))
-	  {
-	    if (state == BUSY_STATE)
-	      /* We need more input now */
-	      return origLength - length;
-	    else if (state == FLUSHING_STATE)
-	      {
-		if (level != NO_COMPRESSION)
-		  {
-		    /* We have to supply some lookahead.  8 bit lookahead
-		     * are needed by the zlib inflater, and we must fill 
-		     * the next byte, so that all bits are flushed.
-		     */
-		    int neededbits = 8 + ((-pending.getBitCount()) & 7);
-		    while (neededbits > 0)
-		      {
-			/* write a static tree block consisting solely of
-			 * an EOF:
-			 */
-			pending.writeBits(2, 10);
-			neededbits -= 10;
-		      }
-		  }
-		state = BUSY_STATE;
-	      }
-	    else if (state == FINISHING_STATE)
-	      {
-		pending.alignToByte();
-		/* We have completed the stream */
-		if (!noHeader)
-		  {
-		    int adler = engine.getAdler();
-		    pending.writeShortMSB(adler >> 16);
-		    pending.writeShortMSB(adler & 0xffff);
-		  }
-		state = FINISHED_STATE;
-	      }
-	  }
-      }
-
-    return origLength - length;
-  }
+  public native int deflate(byte[] output, int off, int len);
 
   /**
    * Sets the dictionary which should be used in the deflate process.
@@ -509,12 +324,5 @@
    * @exception IllegalStateException if setInput () or deflate () were
    * already called or another dictionary was already set.
    */
-  public void setDictionary(byte[] dict, int offset, int length)
-  {
-    if (state != INIT_STATE)
-      throw new IllegalStateException();
-
-    state = SETDICT_STATE;
-    engine.setDictionary(dict, offset, length);
-  }
+  public native void setDictionary(byte[] buf, int off, int len);
 }
