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