jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 8803 b3f57bfca459
child 10115 eb08d08c7ef7
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
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(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                new sun.security.action.LoadLibraryAction("unpack"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    NativeUnpack(UnpackerImpl p200) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        _p200  = p200;
6313
470912c9e214 6888127: java.util.jar.Pack200.Packer Memory Leak
ksrini
parents: 5506
diff changeset
    97
        _props = p200.props;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        p200._nunp = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    // for JNI callbacks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    static private Object currentInstance() {
6313
470912c9e214 6888127: java.util.jar.Pack200.Packer Memory Leak
ksrini
parents: 5506
diff changeset
   103
        UnpackerImpl p200 = (UnpackerImpl) Utils.getTLGlobals();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        return (p200 == null)? null: p200._nunp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    // Callback from the unpacker engine to get more data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        if (in == null)  return 0;  // nothing is readable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        long maxlen = pbuf.capacity() - pbuf.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        assert(minlen <= maxlen);  // don't talk nonsense
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        long numread = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        int steps = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        while (numread < minlen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
            steps++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            // read available input, up to buf.length or maxlen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            int readlen = _buf.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            if (readlen > (maxlen - numread))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                readlen = (int)(maxlen - numread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            int nr = in.read(_buf, 0, readlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            if (nr <= 0)  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            numread += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            assert(numread <= maxlen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            // %%% get rid of this extra copy by using nio?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            pbuf.put(_buf, 0, nr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        if (_verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        if (maxlen > 100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            _estByteLimit = _byteCount + maxlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            _estByteLimit = (_byteCount + numread) * 20;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        _byteCount += numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        updateProgress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        return numread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    private void updateProgress() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        // Progress is a combination of segment reading and file writing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        final double READ_WT  = 0.33;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        final double WRITE_WT = 0.67;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        double readProgress = _segCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        if (_estByteLimit > 0 && _byteCount > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            readProgress += (double)_byteCount / _estByteLimit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        double writeProgress = _fileCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        double scaledProgress
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            = READ_WT  * readProgress  / Math.max(_estSegLimit,1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            + WRITE_WT * writeProgress / Math.max(_estFileLimit,1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        int percent = (int) Math.round(100*scaledProgress);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        if (percent > 100)  percent = 100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        if (percent > _prevPercent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            _prevPercent = percent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            _props.setInteger(Pack200.Unpacker.PROGRESS, percent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                Utils.log.info("progress = "+percent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    private void copyInOption(String opt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        String val = _props.getProperty(opt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            Utils.log.info("set "+opt+"="+val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (val != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            boolean set = setOption(opt, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            if (!set)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                Utils.log.warning("Invalid option "+opt+"="+val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    void run(InputStream inRaw, JarOutputStream jstream,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
             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
   173
        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
   174
        this.in = in0;    // for readInputFn to see
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        _verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        // TODO eliminate and fix in unpack.cpp
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        copyInOption(Utils.DEBUG_VERBOSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        copyInOption(Pack200.Unpacker.DEFLATE_HINT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        if (modtime == Constants.NO_MODTIME)  // Dont pass KEEP && NOW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            copyInOption(Utils.UNPACK_MODIFICATION_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        updateProgress();  // reset progress bar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            // Read the packed bits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            long counts = start(presetInput, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            _byteCount = _estByteLimit = 0;  // reset partial scan counts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            ++_segCount;  // just finished scanning a whole segment...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            int nextSeg  = (int)( counts >>> 32 );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            int nextFile = (int)( counts >>>  0 );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            // Estimate eventual total number of segments and files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            _estSegLimit = _segCount + nextSeg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            double filesAfterThisSeg = _fileCount + nextFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            _estFileLimit = (int)( (filesAfterThisSeg *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                                    _estSegLimit) / _segCount );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            // Write the files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            int[] intParts = { 0,0, 0, 0 };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            //    intParts = {size.hi/lo, mod, defl}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            Object[] parts = { intParts, null, null, null };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            //       parts = { {intParts}, name, data0/1 }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            while (getNextFile(parts)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                //BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                String name = (String) parts[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                long   size = ( (long)intParts[0] << 32)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                            + (((long)intParts[1] << 32) >>> 32);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                long   mtime = (modtime != Constants.NO_MODTIME ) ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                                modtime : intParts[2] ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                boolean deflateHint = (intParts[3] != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                ByteBuffer data0 = (ByteBuffer) parts[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                ByteBuffer data1 = (ByteBuffer) parts[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                writeEntry(jstream, name, mtime, size, deflateHint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                           data0, data1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                ++_fileCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                updateProgress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            }
6320
6b48de58428e 6531345: Memory leak in unpack200
ksrini
parents: 6313
diff changeset
   222
            presetInput = getUnusedInput();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            long consumed = finish();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            if (_verbose > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                Utils.log.info("bytes consumed = "+consumed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            if (presetInput == null &&
7795
98021fc612af 6990106: FindBugs scan - Malicious code vulnerability Warnings in com.sun.java.util.jar.pack.*
ksrini
parents: 7192
diff changeset
   227
                !Utils.isPackMagic(Utils.readMagic(in0))) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            if (_verbose > 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                if (presetInput != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                    Utils.log.info("unused input = "+presetInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    void run(InputStream in, JarOutputStream jstream) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        run(in, jstream, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    void run(File inFile, JarOutputStream jstream) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        // %%% maybe memory-map the file, and pass it straight into unpacker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        ByteBuffer mappedFile = null;
8803
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   244
        try (FileInputStream fis = new FileInputStream(inFile)) {
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   245
            run(fis, jstream, mappedFile);
b3f57bfca459 7022382: convert pack200 library code to use try-with-resources
smarks
parents: 7795
diff changeset
   246
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        // Note:  caller is responsible to finish with jstream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    private void writeEntry(JarOutputStream j, String name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                            long mtime, long lsize, boolean deflateHint,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                            ByteBuffer data0, ByteBuffer data1) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        int size = (int)lsize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        if (size != lsize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            throw new IOException("file too large: "+lsize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        CRC32 crc32 = _crc32;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        if (_verbose > 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            Utils.log.fine("Writing entry: "+name+" size="+size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                             +(deflateHint?" deflated":""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        if (_buf.length < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            int newSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            while (newSize < _buf.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                newSize <<= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                if (newSize <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                    newSize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            _buf = new byte[newSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        assert(_buf.length >= size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        int fillp = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        if (data0 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            int size0 = data0.capacity();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            data0.get(_buf, fillp, size0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            fillp += size0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        if (data1 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            int size1 = data1.capacity();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            data1.get(_buf, fillp, size1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            fillp += size1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        while (fillp < size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            // Fill in rest of data from the stream itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            int nr = in.read(_buf, fillp, size - fillp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            if (nr <= 0)  throw new IOException("EOF at end of archive");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            fillp += nr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        ZipEntry z = new ZipEntry(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        z.setTime( (long)mtime * 1000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        if (size == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            z.setMethod(ZipOutputStream.STORED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            z.setSize(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            z.setCrc(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            z.setCompressedSize(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        } else if (!deflateHint) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            z.setMethod(ZipOutputStream.STORED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            z.setSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            z.setCompressedSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            crc32.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            crc32.update(_buf, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            z.setCrc(crc32.getValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            z.setMethod(Deflater.DEFLATED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            z.setSize(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        j.putNextEntry(z);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        if (size > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            j.write(_buf, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        j.closeEntry();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
}