rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 706 emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java@a48961ff3e6b
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     9  * The contents of this file are subject to the terms of either the GNU
    10  * General Public License Version 2 only ("GPL") or the Common
    11  * Development and Distribution License("CDDL") (collectively, the
    12  * "License"). You may not use this file except in compliance with the
    13  * License. You can obtain a copy of the License at
    14  * http://www.netbeans.org/cddl-gplv2.html
    15  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    16  * specific language governing permissions and limitations under the
    17  * License.  When distributing the software, include this License Header
    18  * Notice in each file and include the License file at
    19  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    20  * particular file as subject to the "Classpath" exception as provided
    21  * by Oracle in the GPL Version 2 section of the License file that
    22  * accompanied this code. If applicable, add the following below the
    23  * License Header, with the fields enclosed by brackets [] replaced by
    24  * your own identifying information:
    25  * "Portions Copyrighted [year] [name of copyright owner]"
    26  *
    27  * Contributor(s):
    28  *
    29  * Portions Copyrighted 2007 Sun Microsystems, Inc.
    30  */
    31 package org.apidesign.bck2brwsr.emul.zip;
    32 
    33 import java.io.ByteArrayInputStream;
    34 import java.io.IOException;
    35 import java.io.InputStream;
    36 import java.util.zip.ZipEntry;
    37 import java.util.zip.ZipInputStream;
    38 
    39 /**
    40  *
    41  * @author Tomas Zezula
    42  */
    43 public final class FastJar {
    44     private final byte[] arr;
    45 
    46     public FastJar(byte[] arr) {
    47         this.arr = arr;
    48     }
    49     
    50     
    51     private static final int GIVE_UP = 1<<16;
    52 
    53     public static final  class Entry {
    54         
    55         public final String name;
    56         final long offset;
    57         private final long dosTime;
    58         
    59         Entry (String name, long offset, long time) {
    60             assert name != null;
    61             this.name = name;
    62             this.offset = offset;
    63             this.dosTime = time;
    64         }        
    65 /*        
    66         public long getTime () {
    67             Date d = new Date((int)(((dosTime >> 25) & 0x7f) + 80),
    68                     (int)(((dosTime >> 21) & 0x0f) - 1),
    69                     (int)((dosTime >> 16) & 0x1f),
    70                     (int)((dosTime >> 11) & 0x1f),
    71                     (int)((dosTime >> 5) & 0x3f),
    72                     (int)((dosTime << 1) & 0x3e));
    73             return d.getTime();
    74         }
    75         */
    76     }
    77     
    78     public InputStream getInputStream (final Entry e) throws IOException {
    79         return getInputStream(arr, e.offset);
    80     }
    81     
    82     private static InputStream getInputStream (byte[] arr, final long offset) throws IOException {
    83         ByteArrayInputStream is = new ByteArrayInputStream(arr);
    84         is.skip(offset);
    85         ZipInputStream in = new ZipInputStream (is);
    86         ZipEntry e = in.getNextEntry();
    87         if (e != null && e.getCrc() == 0L && e.getMethod() == ZipEntry.STORED) {
    88             int cp = arr.length - is.available();
    89             return new ByteArrayInputStream(arr, cp, (int)e.getSize());
    90         }
    91         return in;
    92     }
    93     
    94     public Entry[] list() throws IOException {
    95         final int size = arr.length;
    96 
    97         int at = size - ZipInputStream.ENDHDR;
    98 
    99         byte[] data = new byte[ZipInputStream.ENDHDR];        
   100         int giveup = 0;
   101 
   102         do {
   103             org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length);
   104             at--;
   105             giveup++;
   106             if (giveup > GIVE_UP) {
   107                 throw new IOException ();
   108             }
   109         } while (getsig(data) != ZipInputStream.ENDSIG);
   110 
   111 
   112         final long censize = endsiz(data);
   113         final long cenoff  = endoff(data);
   114         at = (int) cenoff;                                                     
   115 
   116         Entry[] result = new Entry[0];
   117         int cenread = 0;
   118         data = new byte[ZipInputStream.CENHDR];
   119         while (cenread < censize) {
   120             org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length);
   121             at += data.length;
   122             if (getsig(data) != ZipInputStream.CENSIG) {
   123                 throw new IOException("No central table");          //NOI18N
   124             }
   125             int cennam = cennam(data);
   126             int cenext = cenext(data);
   127             int cencom = cencom(data);
   128             long lhoff = cenoff(data);
   129             long centim = centim(data);
   130             String name = new String(arr, at, cennam, "UTF-8");
   131             at += cennam;
   132             int seekby = cenext+cencom;
   133             int cendatalen = ZipInputStream.CENHDR + cennam + seekby;
   134             cenread+=cendatalen;
   135             result = addEntry(result, new Entry(name,lhoff, centim));
   136             at += seekby;
   137         }
   138         return result;
   139     }
   140 
   141     private Entry[] addEntry(Entry[] result, Entry entry) {
   142         Entry[] e = new Entry[result.length + 1];
   143         e[result.length] = entry;
   144         org.apidesign.bck2brwsr.emul.lang.System.arraycopy(result, 0, e, 0, result.length);
   145         return e;
   146     }
   147 
   148     private static final long getsig(final byte[] b) throws IOException {return get32(b,0);}
   149     private static final long endsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDSIZ);}
   150     private static final long endoff(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDOFF);}
   151     private static final long  cenlen(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENLEN);}
   152     private static final long  censiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENSIZ);}
   153     private static final long centim(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENTIM);}
   154     private static final int  cennam(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENNAM);}
   155     private static final int  cenext(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENEXT);}
   156     private static final int  cencom(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENCOM);}
   157     private static final long cenoff (final byte[] b) throws IOException {return get32(b,ZipInputStream.CENOFF);}
   158     private static final int lochow(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCHOW);}
   159     private static final int locname(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCNAM);}
   160     private static final int locext(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCEXT);}
   161     private static final long locsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.LOCSIZ);}
   162     
   163     private static final int get16(final byte[] b, int off) throws IOException {        
   164         final int b1 = b[off];
   165 	final int b2 = b[off+1];
   166         return (b1 & 0xff) | ((b2 & 0xff) << 8);
   167     }
   168 
   169     private static final long get32(final byte[] b, int off) throws IOException {
   170 	final int s1 = get16(b, off);
   171 	final int s2 = get16(b, off+2);
   172         return s1 | ((long)s2 << 16);
   173     }
   174 
   175 }