jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
author martin
Tue, 15 Sep 2015 21:56:04 -0700
changeset 32649 2ee9017c7597
parent 29986 97167d851fc4
permissions -rw-r--r--
8136583: Core libraries should use blessed modifier order Summary: Run blessed-modifier-order script (see bug) Reviewed-by: psandoz, chegar, alanb, plevart
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 21278
diff changeset
     2
 * Copyright (c) 2003, 2013, 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(
29986
97167d851fc4 8078467: Update core libraries to use diamond with anonymous classes
darcy
parents: 25859
diff changeset
    90
            new java.security.PrivilegedAction<>() {
12559
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
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 29986
diff changeset
   107
    private static 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
16076
d7183f4305e5 7186946: Refine unpacker resource usage
ksrini
parents: 12559
diff changeset
   112
    private synchronized long getUnpackerPtr() {
d7183f4305e5 7186946: Refine unpacker resource usage
ksrini
parents: 12559
diff changeset
   113
        return unpackerPtr;
d7183f4305e5 7186946: Refine unpacker resource usage
ksrini
parents: 12559
diff changeset
   114
    }
d7183f4305e5 7186946: Refine unpacker resource usage
ksrini
parents: 12559
diff changeset
   115
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    // Callback from the unpacker engine to get more data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        if (in == null)  return 0;  // nothing is readable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        long maxlen = pbuf.capacity() - pbuf.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        assert(minlen <= maxlen);  // don't talk nonsense
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        long numread = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        int steps = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        while (numread < minlen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            steps++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            // read available input, up to buf.length or maxlen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            int readlen = _buf.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            if (readlen > (maxlen - numread))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                readlen = (int)(maxlen - numread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            int nr = in.read(_buf, 0, readlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            if (nr <= 0)  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            numread += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            assert(numread <= maxlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            // %%% get rid of this extra copy by using nio?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            pbuf.put(_buf, 0, nr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        if (_verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        if (maxlen > 100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            _estByteLimit = _byteCount + maxlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            _estByteLimit = (_byteCount + numread) * 20;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        _byteCount += numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        updateProgress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        return numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    private void updateProgress() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        // Progress is a combination of segment reading and file writing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        final double READ_WT  = 0.33;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        final double WRITE_WT = 0.67;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        double readProgress = _segCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        if (_estByteLimit > 0 && _byteCount > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            readProgress += (double)_byteCount / _estByteLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        double writeProgress = _fileCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        double scaledProgress
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            = READ_WT  * readProgress  / Math.max(_estSegLimit,1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            + WRITE_WT * writeProgress / Math.max(_estFileLimit,1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        int percent = (int) Math.round(100*scaledProgress);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        if (percent > 100)  percent = 100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        if (percent > _prevPercent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            _prevPercent = percent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            _props.setInteger(Pack200.Unpacker.PROGRESS, percent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                Utils.log.info("progress = "+percent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    private void copyInOption(String opt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        String val = _props.getProperty(opt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            Utils.log.info("set "+opt+"="+val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        if (val != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            boolean set = setOption(opt, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            if (!set)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                Utils.log.warning("Invalid option "+opt+"="+val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    void run(InputStream inRaw, JarOutputStream jstream,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
             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
   182
        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
   183
        this.in = in0;    // for readInputFn to see
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        _verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        // TODO eliminate and fix in unpack.cpp
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        copyInOption(Utils.DEBUG_VERBOSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        copyInOption(Pack200.Unpacker.DEFLATE_HINT);
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 16100
diff changeset
   193
        if (modtime == Constants.NO_MODTIME)  // Don't pass KEEP && NOW
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            copyInOption(Utils.UNPACK_MODIFICATION_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        updateProgress();  // reset progress bar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            // Read the packed bits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            long counts = start(presetInput, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            _byteCount = _estByteLimit = 0;  // reset partial scan counts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            ++_segCount;  // just finished scanning a whole segment...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            int nextSeg  = (int)( counts >>> 32 );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            int nextFile = (int)( counts >>>  0 );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            // Estimate eventual total number of segments and files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            _estSegLimit = _segCount + nextSeg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            double filesAfterThisSeg = _fileCount + nextFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            _estFileLimit = (int)( (filesAfterThisSeg *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                                    _estSegLimit) / _segCount );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            // Write the files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            int[] intParts = { 0,0, 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            //    intParts = {size.hi/lo, mod, defl}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            Object[] parts = { intParts, null, null, null };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            //       parts = { {intParts}, name, data0/1 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            while (getNextFile(parts)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                //BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                String name = (String) parts[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                long   size = ( (long)intParts[0] << 32)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                            + (((long)intParts[1] << 32) >>> 32);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                long   mtime = (modtime != Constants.NO_MODTIME ) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                                modtime : intParts[2] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                boolean deflateHint = (intParts[3] != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                ByteBuffer data0 = (ByteBuffer) parts[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                ByteBuffer data1 = (ByteBuffer) parts[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                writeEntry(jstream, name, mtime, size, deflateHint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                           data0, data1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                ++_fileCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                updateProgress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            }
6320
6b48de58428e 6531345: Memory leak in unpack200
ksrini
parents: 6313
diff changeset
   231
            presetInput = getUnusedInput();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            long consumed = finish();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                Utils.log.info("bytes consumed = "+consumed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            if (presetInput == null &&
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   236
                !Utils.isPackMagic(Utils.readMagic(in0))) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            if (_verbose > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                if (presetInput != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                    Utils.log.info("unused input = "+presetInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        }
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(InputStream in, JarOutputStream jstream) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        run(in, jstream, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    void run(File inFile, JarOutputStream jstream) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        // %%% maybe memory-map the file, and pass it straight into unpacker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        ByteBuffer mappedFile = null;
8803
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   253
        try (FileInputStream fis = new FileInputStream(inFile)) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   254
            run(fis, jstream, mappedFile);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   255
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        // Note:  caller is responsible to finish with jstream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    private void writeEntry(JarOutputStream j, String name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                            long mtime, long lsize, boolean deflateHint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                            ByteBuffer data0, ByteBuffer data1) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        int size = (int)lsize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        if (size != lsize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            throw new IOException("file too large: "+lsize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        CRC32 crc32 = _crc32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        if (_verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            Utils.log.fine("Writing entry: "+name+" size="+size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                             +(deflateHint?" deflated":""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        if (_buf.length < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            int newSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            while (newSize < _buf.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                newSize <<= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                if (newSize <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                    newSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            _buf = new byte[newSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        assert(_buf.length >= size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        int fillp = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        if (data0 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            int size0 = data0.capacity();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            data0.get(_buf, fillp, size0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            fillp += size0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        if (data1 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            int size1 = data1.capacity();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            data1.get(_buf, fillp, size1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            fillp += size1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        while (fillp < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            // Fill in rest of data from the stream itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            int nr = in.read(_buf, fillp, size - fillp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            if (nr <= 0)  throw new IOException("EOF at end of archive");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            fillp += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        ZipEntry z = new ZipEntry(name);
10115
eb08d08c7ef7 7060849: Eliminate pack200 build warnings
ksrini
parents: 9035
diff changeset
   304
        z.setTime(mtime * 1000);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        if (size == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            z.setMethod(ZipOutputStream.STORED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            z.setSize(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            z.setCrc(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            z.setCompressedSize(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        } else if (!deflateHint) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            z.setMethod(ZipOutputStream.STORED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            z.setSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            z.setCompressedSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            crc32.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            crc32.update(_buf, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            z.setCrc(crc32.getValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            z.setMethod(Deflater.DEFLATED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            z.setSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        j.putNextEntry(z);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        if (size > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            j.write(_buf, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        j.closeEntry();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
}