emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/GZIPHeader.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 07 Feb 2013 12:58:12 +0100
branchemul
changeset 694 0d277415ed02
permissions -rw-r--r--
Rebasing the Inflater support on jzlib which, unlike GNU ClassPath, has correct implementation of Huffman code. Making the implementation more easily testable by turning Inflater and ZipInputStream into pure delegates. Current implementation is going to need proper long support.
     1 /* -*-mode:java; c-basic-offset:2; -*- */
     2 /*
     3 Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
     4 
     5 Redistribution and use in source and binary forms, with or without
     6 modification, are permitted provided that the following conditions are met:
     7 
     8   1. Redistributions of source code must retain the above copyright notice,
     9      this list of conditions and the following disclaimer.
    10 
    11   2. Redistributions in binary form must reproduce the above copyright 
    12      notice, this list of conditions and the following disclaimer in 
    13      the documentation and/or other materials provided with the distribution.
    14 
    15   3. The names of the authors may not be used to endorse or promote products
    16      derived from this software without specific prior written permission.
    17 
    18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
    19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
    21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
    22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
    24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  */
    29 /*
    30  * This program is based on zlib-1.1.3, so all credit should go authors
    31  * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
    32  * and contributors of zlib.
    33  */
    34 
    35 package org.apidesign.bck2brwsr.emul.zip;
    36 
    37 import org.apidesign.bck2brwsr.emul.lang.System;
    38 import java.io.UnsupportedEncodingException;
    39 
    40 /**
    41  * @see "http://www.ietf.org/rfc/rfc1952.txt"
    42  */
    43 final class GZIPHeader implements Cloneable {
    44 
    45   public static final byte OS_MSDOS = (byte) 0x00;
    46   public static final byte OS_AMIGA = (byte) 0x01;
    47   public static final byte OS_VMS = (byte) 0x02;
    48   public static final byte OS_UNIX = (byte) 0x03;
    49   public static final byte OS_ATARI = (byte) 0x05;
    50   public static final byte OS_OS2 = (byte) 0x06;
    51   public static final byte OS_MACOS = (byte) 0x07;
    52   public static final byte OS_TOPS20 = (byte) 0x0a;
    53   public static final byte OS_WIN32 = (byte) 0x0b;
    54   public static final byte OS_VMCMS = (byte) 0x04;
    55   public static final byte OS_ZSYSTEM = (byte) 0x08;
    56   public static final byte OS_CPM = (byte) 0x09;
    57   public static final byte OS_QDOS = (byte) 0x0c;
    58   public static final byte OS_RISCOS = (byte) 0x0d;
    59   public static final byte OS_UNKNOWN = (byte) 0xff;
    60 
    61   boolean text = false;
    62   private boolean fhcrc = false;
    63   long time;
    64   int xflags;
    65   int os = 255;
    66   byte[] extra;
    67   byte[] name;
    68   byte[] comment;
    69   int hcrc;
    70   long crc;
    71   boolean done = false;
    72   long mtime = 0;
    73 
    74   public void setModifiedTime(long mtime) {
    75     this.mtime = mtime;
    76   }
    77 
    78   public long getModifiedTime() {
    79     return mtime;
    80   }
    81 
    82   public void setOS(int os) {
    83     if((0<=os && os <=13) || os==255)
    84       this.os=os;
    85     else
    86       throw new IllegalArgumentException("os: "+os);
    87   }
    88 
    89   public int getOS(){
    90     return os;
    91   }
    92 
    93   public void setName(String name) {
    94     try{
    95       this.name=name.getBytes("ISO-8859-1");
    96     }
    97     catch(UnsupportedEncodingException e){
    98       throw new IllegalArgumentException("name must be in ISO-8859-1 "+name);
    99     }
   100   }
   101 
   102   public String getName(){
   103     if(name==null) return "";
   104     try {
   105       return new String(name, "ISO-8859-1");
   106     }
   107     catch (UnsupportedEncodingException e) {
   108       throw new IllegalArgumentException(e.toString());
   109     }
   110   }
   111 
   112   public void setComment(String comment) {
   113     try{
   114       this.comment=comment.getBytes("ISO-8859-1");
   115     }
   116     catch(UnsupportedEncodingException e){
   117       throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name);
   118     }
   119   }
   120 
   121   public String getComment(){
   122     if(comment==null) return "";
   123     try {
   124       return new String(comment, "ISO-8859-1");
   125     }
   126     catch (UnsupportedEncodingException e) {
   127       throw new IllegalArgumentException(e.toString());
   128     }
   129   }
   130 
   131   public void setCRC(long crc){
   132     this.crc = crc;
   133   }
   134 
   135   public long getCRC(){
   136     return crc;
   137   }
   138 /*
   139   void put(Deflate d){
   140     int flag = 0;
   141     if(text){
   142       flag |= 1;     // FTEXT
   143     }
   144     if(fhcrc){
   145       flag |= 2;     // FHCRC
   146     }
   147     if(extra!=null){
   148       flag |= 4;     // FEXTRA
   149     }
   150     if(name!=null){
   151       flag |= 8;    // FNAME
   152     }
   153     if(comment!=null){
   154       flag |= 16;   // FCOMMENT
   155     }
   156     int xfl = 0;
   157     if(d.level == JZlib.Z_BEST_SPEED){
   158       xfl |= 4;
   159     }
   160     else if (d.level == JZlib.Z_BEST_COMPRESSION){
   161       xfl |= 2;
   162     }
   163 
   164     d.put_short((short)0x8b1f);  // ID1 ID2
   165     d.put_byte((byte)8);         // CM(Compression Method)
   166     d.put_byte((byte)flag);
   167     d.put_byte((byte)mtime);
   168     d.put_byte((byte)(mtime>>8));
   169     d.put_byte((byte)(mtime>>16));
   170     d.put_byte((byte)(mtime>>24));
   171     d.put_byte((byte)xfl);
   172     d.put_byte((byte)os);
   173 
   174     if(extra!=null){
   175       d.put_byte((byte)extra.length);
   176       d.put_byte((byte)(extra.length>>8));
   177       d.put_byte(extra, 0, extra.length);
   178     }
   179 
   180     if(name!=null){
   181       d.put_byte(name, 0, name.length);
   182       d.put_byte((byte)0);
   183     }
   184 
   185     if(comment!=null){
   186       d.put_byte(comment, 0, comment.length);
   187       d.put_byte((byte)0);
   188     }
   189   }
   190 */
   191   @Override
   192   public Object clone() throws CloneNotSupportedException {
   193     GZIPHeader gheader = (GZIPHeader)super.clone();
   194     byte[] tmp;
   195     if(gheader.extra!=null){
   196       tmp=new byte[gheader.extra.length];
   197       System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length);
   198       gheader.extra = tmp;
   199     }
   200 
   201     if(gheader.name!=null){
   202       tmp=new byte[gheader.name.length];
   203       System.arraycopy(gheader.name, 0, tmp, 0, tmp.length);
   204       gheader.name = tmp;
   205     }
   206 
   207     if(gheader.comment!=null){
   208       tmp=new byte[gheader.comment.length];
   209       System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length);
   210       gheader.comment = tmp;
   211     }
   212 
   213     return gheader;
   214   }
   215 }