jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
author ksrini
Tue, 29 May 2012 14:56:48 -0700
changeset 12857 0a5f341c2a28
parent 12559 9456ceada8b1
child 16076 d7183f4305e5
child 14342 8435a30053c1
permissions -rw-r--r--
7168401: pack200 does not produce a compatible pack file for JDK7 classes if indy is not present Reviewed-by: jrose
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8803
diff changeset
     2
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
package com.sun.java.util.jar.pack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
7192
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    29
import java.io.BufferedInputStream;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    30
import java.io.File;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    31
import java.io.FileInputStream;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    32
import java.io.IOException;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    33
import java.io.InputStream;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    34
import java.nio.ByteBuffer;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    35
import java.util.jar.JarOutputStream;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    36
import java.util.jar.Pack200;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    37
import java.util.zip.CRC32;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    38
import java.util.zip.Deflater;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    39
import java.util.zip.ZipEntry;
445c518364c4 7003227: (pack200) intermittent failures compiling pack200
ksrini
parents: 6320
diff changeset
    40
import java.util.zip.ZipOutputStream;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
class NativeUnpack {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    // Pointer to the native unpacker obj
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    private long unpackerPtr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    // Input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    private BufferedInputStream in;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private static synchronized native void initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    // Starts processing at the indicated position in the buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    // If the buffer is null, the readInputFn callback is used to get bytes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    // Returns (s<<32|f), the number of following segments and files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    private synchronized native long start(ByteBuffer buf, long offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    // Returns true if there's another, and fills in the parts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private synchronized native boolean getNextFile(Object[] parts);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private synchronized native ByteBuffer getUnusedInput();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    // Resets the engine and frees all resources.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    // Returns total number of bytes consumed by the engine.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    private synchronized native long finish();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    // Setting state in the unpacker.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    protected  synchronized native boolean setOption(String opt, String value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    protected  synchronized native String getOption(String opt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    private  int _verbose;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    // State for progress bar:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    private  long _byteCount;      // bytes read in current segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    private  int  _segCount;       // number of segs scanned
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private  int  _fileCount;      // number of files written
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    private  long _estByteLimit;   // estimate of eventual total
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    private  int  _estSegLimit;    // ditto
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private  int  _estFileLimit;   // ditto
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private  int  _prevPercent = -1; // for monotonicity
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    private final CRC32   _crc32 = new CRC32();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private       byte[]  _buf   = new byte[1<<14];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private  UnpackerImpl _p200;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private  PropMap _props;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        // If loading from stand alone build uncomment this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        // System.loadLibrary("unpack");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        java.security.AccessController.doPrivileged(
12559
9456ceada8b1 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary
mchung
parents: 10115
diff changeset
    90
            new java.security.PrivilegedAction<Void>() {
9456ceada8b1 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary
mchung
parents: 10115
diff changeset
    91
                public Void run() {
9456ceada8b1 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary
mchung
parents: 10115
diff changeset
    92
                    System.loadLibrary("unpack");
9456ceada8b1 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary
mchung
parents: 10115
diff changeset
    93
                    return null;
9456ceada8b1 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary
mchung
parents: 10115
diff changeset
    94
                }
9456ceada8b1 7164376: Replace use of sun.security.action.LoadLibraryAction with System.loadLibrary
mchung
parents: 10115
diff changeset
    95
            });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    NativeUnpack(UnpackerImpl p200) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        _p200  = p200;
6313
470912c9e214 6888127: java.util.jar.Pack200.Packer Memory Leak
ksrini
parents: 5506
diff changeset
   102
        _props = p200.props;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        p200._nunp = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    // for JNI callbacks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    static private Object currentInstance() {
6313
470912c9e214 6888127: java.util.jar.Pack200.Packer Memory Leak
ksrini
parents: 5506
diff changeset
   108
        UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        return (p200 == null)? null: p200._nunp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    // Callback from the unpacker engine to get more data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        if (in == null)  return 0;  // nothing is readable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        long maxlen = pbuf.capacity() - pbuf.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        assert(minlen <= maxlen);  // don't talk nonsense
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        long numread = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        int steps = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        while (numread < minlen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            steps++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            // read available input, up to buf.length or maxlen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            int readlen = _buf.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            if (readlen > (maxlen - numread))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                readlen = (int)(maxlen - numread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            int nr = in.read(_buf, 0, readlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            if (nr <= 0)  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            numread += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            assert(numread <= maxlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            // %%% get rid of this extra copy by using nio?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            pbuf.put(_buf, 0, nr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        if (_verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        if (maxlen > 100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            _estByteLimit = _byteCount + maxlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            _estByteLimit = (_byteCount + numread) * 20;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        _byteCount += numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        updateProgress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        return numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    private void updateProgress() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        // Progress is a combination of segment reading and file writing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        final double READ_WT  = 0.33;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        final double WRITE_WT = 0.67;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        double readProgress = _segCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        if (_estByteLimit > 0 && _byteCount > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            readProgress += (double)_byteCount / _estByteLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        double writeProgress = _fileCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        double scaledProgress
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            = READ_WT  * readProgress  / Math.max(_estSegLimit,1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            + WRITE_WT * writeProgress / Math.max(_estFileLimit,1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        int percent = (int) Math.round(100*scaledProgress);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        if (percent > 100)  percent = 100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        if (percent > _prevPercent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            _prevPercent = percent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            _props.setInteger(Pack200.Unpacker.PROGRESS, percent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                Utils.log.info("progress = "+percent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    private void copyInOption(String opt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        String val = _props.getProperty(opt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            Utils.log.info("set "+opt+"="+val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        if (val != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            boolean set = setOption(opt, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            if (!set)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                Utils.log.warning("Invalid option "+opt+"="+val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    void run(InputStream inRaw, JarOutputStream jstream,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
             ByteBuffer presetInput) throws IOException {
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   178
        BufferedInputStream in0 = new BufferedInputStream(inRaw);
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   179
        this.in = in0;    // for readInputFn to see
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        _verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        // TODO eliminate and fix in unpack.cpp
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        copyInOption(Utils.DEBUG_VERBOSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        copyInOption(Pack200.Unpacker.DEFLATE_HINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        if (modtime == Constants.NO_MODTIME)  // Dont pass KEEP && NOW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            copyInOption(Utils.UNPACK_MODIFICATION_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        updateProgress();  // reset progress bar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            // Read the packed bits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            long counts = start(presetInput, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            _byteCount = _estByteLimit = 0;  // reset partial scan counts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            ++_segCount;  // just finished scanning a whole segment...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            int nextSeg  = (int)( counts >>> 32 );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            int nextFile = (int)( counts >>>  0 );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            // Estimate eventual total number of segments and files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            _estSegLimit = _segCount + nextSeg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            double filesAfterThisSeg = _fileCount + nextFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            _estFileLimit = (int)( (filesAfterThisSeg *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                                    _estSegLimit) / _segCount );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            // Write the files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            int[] intParts = { 0,0, 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            //    intParts = {size.hi/lo, mod, defl}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            Object[] parts = { intParts, null, null, null };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            //       parts = { {intParts}, name, data0/1 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            while (getNextFile(parts)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                //BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                String name = (String) parts[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                long   size = ( (long)intParts[0] << 32)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                            + (((long)intParts[1] << 32) >>> 32);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                long   mtime = (modtime != Constants.NO_MODTIME ) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                                modtime : intParts[2] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                boolean deflateHint = (intParts[3] != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                ByteBuffer data0 = (ByteBuffer) parts[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                ByteBuffer data1 = (ByteBuffer) parts[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                writeEntry(jstream, name, mtime, size, deflateHint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                           data0, data1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                ++_fileCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                updateProgress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            }
6320
6b48de58428e 6531345: Memory leak in unpack200
ksrini
parents: 6313
diff changeset
   227
            presetInput = getUnusedInput();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            long consumed = finish();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                Utils.log.info("bytes consumed = "+consumed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            if (presetInput == null &&
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   232
                !Utils.isPackMagic(Utils.readMagic(in0))) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            if (_verbose > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                if (presetInput != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                    Utils.log.info("unused input = "+presetInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    void run(InputStream in, JarOutputStream jstream) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        run(in, jstream, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    void run(File inFile, JarOutputStream jstream) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        // %%% maybe memory-map the file, and pass it straight into unpacker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        ByteBuffer mappedFile = null;
8803
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   249
        try (FileInputStream fis = new FileInputStream(inFile)) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   250
            run(fis, jstream, mappedFile);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   251
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        // Note:  caller is responsible to finish with jstream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    private void writeEntry(JarOutputStream j, String name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                            long mtime, long lsize, boolean deflateHint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                            ByteBuffer data0, ByteBuffer data1) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        int size = (int)lsize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        if (size != lsize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            throw new IOException("file too large: "+lsize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        CRC32 crc32 = _crc32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        if (_verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            Utils.log.fine("Writing entry: "+name+" size="+size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                             +(deflateHint?" deflated":""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        if (_buf.length < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            int newSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            while (newSize < _buf.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                newSize <<= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                if (newSize <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                    newSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            _buf = new byte[newSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        assert(_buf.length >= size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        int fillp = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        if (data0 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            int size0 = data0.capacity();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            data0.get(_buf, fillp, size0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            fillp += size0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        if (data1 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            int size1 = data1.capacity();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            data1.get(_buf, fillp, size1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            fillp += size1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        while (fillp < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            // Fill in rest of data from the stream itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            int nr = in.read(_buf, fillp, size - fillp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            if (nr <= 0)  throw new IOException("EOF at end of archive");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            fillp += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        ZipEntry z = new ZipEntry(name);
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 9035
diff changeset
   300
        z.setTime(mtime * 1000);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        if (size == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            z.setMethod(ZipOutputStream.STORED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            z.setSize(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            z.setCrc(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            z.setCompressedSize(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        } else if (!deflateHint) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            z.setMethod(ZipOutputStream.STORED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            z.setSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            z.setCompressedSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            crc32.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            crc32.update(_buf, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            z.setCrc(crc32.getValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            z.setMethod(Deflater.DEFLATED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            z.setSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        j.putNextEntry(z);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        if (size > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            j.write(_buf, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        j.closeEntry();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
}