Save This Page
Home » openjdk-7 » java » util » zip » [javadoc | source]
    1   /* OutputWindow.java --
    2      Copyright (C) 2001, 2004  Free Software Foundation, Inc.
    3   
    4   This file is part of GNU Classpath.
    5   
    6   GNU Classpath is free software; you can redistribute it and/or modify
    7   it under the terms of the GNU General Public License as published by
    8   the Free Software Foundation; either version 2, or (at your option)
    9   any later version.
   10   
   11   GNU Classpath is distributed in the hope that it will be useful, but
   12   WITHOUT ANY WARRANTY; without even the implied warranty of
   13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14   General Public License for more details.
   15   
   16   You should have received a copy of the GNU General Public License
   17   along with GNU Classpath; see the file COPYING.  If not, write to the
   18   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   19   02110-1301 USA.
   20   
   21   Linking this library statically or dynamically with other modules is
   22   making a combined work based on this library.  Thus, the terms and
   23   conditions of the GNU General Public License cover the whole
   24   combination.
   25   
   26   As a special exception, the copyright holders of this library give you
   27   permission to link this library with independent modules to produce an
   28   executable, regardless of the license terms of these independent
   29   modules, and to copy and distribute the resulting executable under
   30   terms of your choice, provided that you also meet, for each linked
   31   independent module, the terms and conditions of the license of that
   32   module.  An independent module is a module which is not derived from
   33   or based on this library.  If you modify this library, you may extend
   34   this exception to your version of the library, but you are not
   35   obligated to do so.  If you do not wish to do so, delete this
   36   exception statement from your version. */
   37   
   38   package java.util.zip;
   39   
   40   /**
   41    * Contains the output from the Inflation process.
   42    *
   43    * We need to have a window so that we can refer backwards into the output stream
   44    * to repeat stuff.
   45    *
   46    * @author John Leuner
   47    * @since 1.1
   48    */
   49   class OutputWindow
   50   {
   51     private static final int WINDOW_SIZE = 1 << 15;
   52     private static final int WINDOW_MASK = WINDOW_SIZE - 1;
   53   
   54     private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
   55     private int window_end  = 0;
   56     private int window_filled = 0;
   57   
   58     public void write(int abyte)
   59     {
   60       if (window_filled++ == WINDOW_SIZE)
   61         throw new IllegalStateException("Window full");
   62       window[window_end++] = (byte) abyte;
   63       window_end &= WINDOW_MASK;
   64     }
   65   
   66     private void slowRepeat(int rep_start, int len, int dist)
   67     {
   68       while (len-- > 0)
   69         {
   70   	window[window_end++] = window[rep_start++];
   71   	window_end &= WINDOW_MASK;
   72   	rep_start &= WINDOW_MASK;
   73         }
   74     }
   75   
   76     public void repeat(int len, int dist)
   77     {
   78       if ((window_filled += len) > WINDOW_SIZE)
   79         throw new IllegalStateException("Window full");
   80   
   81       int rep_start = (window_end - dist) & WINDOW_MASK;
   82       int border = WINDOW_SIZE - len;
   83       if (rep_start <= border && window_end < border)
   84         {
   85   	if (len <= dist)
   86   	  {
   87   	    System.arraycopy(window, rep_start, window, window_end, len);
   88   	    window_end += len;
   89   	  }
   90   	else
   91   	  {
   92   	    /* We have to copy manually, since the repeat pattern overlaps.
   93   	     */
   94   	    while (len-- > 0)
   95   	      window[window_end++] = window[rep_start++];
   96   	  }
   97         }
   98       else
   99         slowRepeat(rep_start, len, dist);
  100     }
  101   
  102     public int copyStored(StreamManipulator input, int len)
  103     {
  104       len = Math.min(Math.min(len, WINDOW_SIZE - window_filled), 
  105   		   input.getAvailableBytes());
  106       int copied;
  107   
  108       int tailLen = WINDOW_SIZE - window_end;
  109       if (len > tailLen)
  110         {
  111   	copied = input.copyBytes(window, window_end, tailLen);
  112   	if (copied == tailLen)
  113   	  copied += input.copyBytes(window, 0, len - tailLen);
  114         }
  115       else
  116         copied = input.copyBytes(window, window_end, len);
  117   
  118       window_end = (window_end + copied) & WINDOW_MASK;
  119       window_filled += copied;
  120       return copied;
  121     }
  122   
  123     public void copyDict(byte[] dict, int offset, int len)
  124     {
  125       if (window_filled > 0)
  126         throw new IllegalStateException();
  127   
  128       if (len > WINDOW_SIZE)
  129         {
  130   	offset += len - WINDOW_SIZE;
  131   	len = WINDOW_SIZE;
  132         }
  133       System.arraycopy(dict, offset, window, 0, len);
  134       window_end = len & WINDOW_MASK;
  135     }
  136   
  137     public int getFreeSpace()
  138     {
  139       return WINDOW_SIZE - window_filled;
  140     }
  141   
  142     public int getAvailable()
  143     {
  144       return window_filled;
  145     }
  146   
  147     public int copyOutput(byte[] output, int offset, int len)
  148     {
  149       int copy_end = window_end;
  150       if (len > window_filled)
  151         len = window_filled;
  152       else
  153         copy_end = (window_end - window_filled + len) & WINDOW_MASK;
  154   
  155       int copied = len;
  156       int tailLen = len - copy_end;
  157   
  158       if (tailLen > 0)
  159         {
  160   	System.arraycopy(window, WINDOW_SIZE - tailLen,
  161   			 output, offset, tailLen);
  162   	offset += tailLen;
  163   	len = copy_end;
  164         }
  165       System.arraycopy(window, copy_end - len, output, offset, len);
  166       window_filled -= copied;
  167       if (window_filled < 0)
  168         throw new IllegalStateException();
  169       return copied;
  170     }
  171   
  172     public void reset() {
  173       window_filled = window_end = 0;
  174     }
  175   }
  176   
  177   
  178   

Save This Page
Home » openjdk-7 » java » util » zip » [javadoc | source]