src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java
author lancea
Mon, 28 Oct 2019 13:17:54 -0400
changeset 58822 9d95d8a8b750
parent 57665 bf325b739c8a
permissions -rw-r--r--
8232879: Writing out data with the Zip File System leads to a CRC failure Reviewed-by: lancea, clanger Contributed-by: Jaikiran Pai <jai.forums2013@gmail.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
     1
/*
57665
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
     2
 * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
23925
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
     4
 *
23925
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    10
 *
23925
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    15
 * accompanied this code).
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    16
 *
23925
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    20
 *
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    23
 * questions.
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    24
 */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    25
23925
0d5f2d863262 8038500: (zipfs) Upgrade ZIP provider to be a supported provider
sherman
parents: 14342
diff changeset
    26
package jdk.nio.zipfs;
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    27
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    28
import java.io.IOException;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    29
import java.io.OutputStream;
57665
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    30
import java.nio.file.attribute.PosixFilePermission;
47331
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
    31
import java.time.DateTimeException;
33405
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
    32
import java.time.Instant;
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
    33
import java.time.LocalDateTime;
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
    34
import java.time.ZoneId;
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    35
import java.util.Arrays;
47331
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
    36
import java.util.Date;
57665
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    37
import java.util.Set;
53043
fd2e8f941ded 8215472: (zipfs) Cleanups in implementation classes of jdk.zipfs and tests
clanger
parents: 47331
diff changeset
    38
import java.util.concurrent.TimeUnit;
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    39
import java.util.regex.PatternSyntaxException;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    40
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    41
/**
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    42
 * @author Xueming Shen
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    43
 */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    44
class ZipUtils {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
    45
57665
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    46
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    47
     * The bit flag used to specify read permission by the owner.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    48
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    49
    static final int POSIX_USER_READ = 0400;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    50
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    51
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    52
     * The bit flag used to specify write permission by the owner.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    53
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    54
    static final int POSIX_USER_WRITE = 0200;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    55
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    56
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    57
     * The bit flag used to specify execute permission by the owner.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    58
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    59
    static final int POSIX_USER_EXECUTE = 0100;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    60
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    61
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    62
     * The bit flag used to specify read permission by the group.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    63
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    64
    static final int POSIX_GROUP_READ = 040;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    65
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    66
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    67
     * The bit flag used to specify write permission by the group.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    68
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    69
    static final int POSIX_GROUP_WRITE = 020;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    70
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    71
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    72
     * The bit flag used to specify execute permission by the group.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    73
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    74
    static final int POSIX_GROUP_EXECUTE = 010;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    75
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    76
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    77
     * The bit flag used to specify read permission by others.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    78
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    79
    static final int POSIX_OTHER_READ = 04;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    80
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    81
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    82
     * The bit flag used to specify write permission by others.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    83
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    84
    static final int POSIX_OTHER_WRITE = 02;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    85
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    86
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    87
     * The bit flag used to specify execute permission by others.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    88
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    89
    static final int POSIX_OTHER_EXECUTE = 01;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    90
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    91
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    92
     * Convert a {@link PosixFilePermission} object into the appropriate bit
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    93
     * flag.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    94
     *
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    95
     * @param perm The {@link PosixFilePermission} object.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    96
     * @return The bit flag as int.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    97
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    98
    static int permToFlag(PosixFilePermission perm) {
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
    99
        switch(perm) {
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   100
        case OWNER_READ:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   101
            return POSIX_USER_READ;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   102
        case OWNER_WRITE:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   103
            return POSIX_USER_WRITE;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   104
        case OWNER_EXECUTE:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   105
            return POSIX_USER_EXECUTE;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   106
        case GROUP_READ:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   107
            return POSIX_GROUP_READ;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   108
        case GROUP_WRITE:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   109
            return POSIX_GROUP_WRITE;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   110
        case GROUP_EXECUTE:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   111
            return POSIX_GROUP_EXECUTE;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   112
        case OTHERS_READ:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   113
            return POSIX_OTHER_READ;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   114
        case OTHERS_WRITE:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   115
            return POSIX_OTHER_WRITE;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   116
        case OTHERS_EXECUTE:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   117
            return POSIX_OTHER_EXECUTE;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   118
        default:
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   119
            return 0;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   120
        }
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   121
    }
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   122
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   123
    /**
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   124
     * Converts a set of {@link PosixFilePermission}s into an int value where
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   125
     * the according bits are set.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   126
     *
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   127
     * @param perms A Set of {@link PosixFilePermission} objects.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   128
     *
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   129
     * @return A bit mask representing the input Set.
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   130
     */
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   131
    static int permsToFlags(Set<PosixFilePermission> perms) {
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   132
        if (perms == null) {
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   133
            return -1;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   134
        }
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   135
        int flags = 0;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   136
        for (PosixFilePermission perm : perms) {
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   137
            flags |= permToFlag(perm);
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   138
        }
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   139
        return flags;
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   140
    }
bf325b739c8a 8213031: (zipfs) Add support for POSIX file permissions
clanger
parents: 53043
diff changeset
   141
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   142
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   143
     * Writes a 16-bit short to the output stream in little-endian byte order.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   144
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   145
    public static void writeShort(OutputStream os, int v) throws IOException {
7189
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   146
        os.write(v & 0xff);
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   147
        os.write((v >>> 8) & 0xff);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   148
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   149
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   150
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   151
     * Writes a 32-bit int to the output stream in little-endian byte order.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   152
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   153
    public static void writeInt(OutputStream os, long v) throws IOException {
7189
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   154
        os.write((int)(v & 0xff));
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   155
        os.write((int)((v >>>  8) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   156
        os.write((int)((v >>> 16) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   157
        os.write((int)((v >>> 24) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   158
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   159
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   160
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   161
     * Writes a 64-bit int to the output stream in little-endian byte order.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   162
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   163
    public static void writeLong(OutputStream os, long v) throws IOException {
7189
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   164
        os.write((int)(v & 0xff));
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   165
        os.write((int)((v >>>  8) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   166
        os.write((int)((v >>> 16) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   167
        os.write((int)((v >>> 24) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   168
        os.write((int)((v >>> 32) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   169
        os.write((int)((v >>> 40) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   170
        os.write((int)((v >>> 48) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   171
        os.write((int)((v >>> 56) & 0xff));
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   172
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   173
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   174
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   175
     * Writes an array of bytes to the output stream.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   176
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   177
    public static void writeBytes(OutputStream os, byte[] b)
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   178
        throws IOException
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   179
    {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   180
        os.write(b, 0, b.length);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   181
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   182
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   183
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   184
     * Writes an array of bytes to the output stream.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   185
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   186
    public static void writeBytes(OutputStream os, byte[] b, int off, int len)
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   187
        throws IOException
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   188
    {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   189
        os.write(b, off, len);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   190
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   191
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   192
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   193
     * Append a slash at the end, if it does not have one yet
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   194
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   195
    public static byte[] toDirectoryPath(byte[] dir) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   196
        if (dir.length != 0 && dir[dir.length - 1] != '/') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   197
            dir = Arrays.copyOf(dir, dir.length + 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   198
            dir[dir.length - 1] = '/';
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   199
        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   200
        return dir;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   201
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   202
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   203
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   204
     * Converts DOS time to Java time (number of milliseconds since epoch).
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   205
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   206
    public static long dosToJavaTime(long dtime) {
47331
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   207
        int year = (int) (((dtime >> 25) & 0x7f) + 1980);
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   208
        int month = (int) ((dtime >> 21) & 0x0f);
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   209
        int day = (int) ((dtime >> 16) & 0x1f);
46154
fcef65412084 8184940: JDK 9 rejects zip files where the modified day or month is 0
cushon
parents: 33405
diff changeset
   210
        int hour = (int) ((dtime >> 11) & 0x1f);
fcef65412084 8184940: JDK 9 rejects zip files where the modified day or month is 0
cushon
parents: 33405
diff changeset
   211
        int minute = (int) ((dtime >> 5) & 0x3f);
fcef65412084 8184940: JDK 9 rejects zip files where the modified day or month is 0
cushon
parents: 33405
diff changeset
   212
        int second = (int) ((dtime << 1) & 0x3e);
47331
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   213
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   214
        if (month > 0 && month < 13 && day > 0 && hour < 24 && minute < 60 && second < 60) {
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   215
            try {
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   216
                LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   217
                return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   218
                        ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   219
            } catch (DateTimeException dte) {
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   220
                // ignore
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   221
            }
46154
fcef65412084 8184940: JDK 9 rejects zip files where the modified day or month is 0
cushon
parents: 33405
diff changeset
   222
        }
47331
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   223
        return overflowDosToJavaTime(year, month, day, hour, minute, second);
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   224
    }
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   225
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   226
    /*
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   227
     * Deal with corner cases where an arguably mal-formed DOS time is used
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   228
     */
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   229
    @SuppressWarnings("deprecation") // Use of Date constructor
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   230
    private static long overflowDosToJavaTime(int year, int month, int day,
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   231
                                              int hour, int minute, int second) {
39d1de71faca 8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59
redestad
parents: 47216
diff changeset
   232
        return new Date(year - 1900, month - 1, day, hour, minute, second).getTime();
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   233
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   234
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   235
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   236
     * Converts Java time to DOS time.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   237
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   238
    public static long javaToDosTime(long time) {
33405
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   239
        Instant instant = Instant.ofEpochMilli(time);
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   240
        LocalDateTime ldt = LocalDateTime.ofInstant(
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   241
                instant, ZoneId.systemDefault());
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   242
        int year = ldt.getYear() - 1980;
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   243
        if (year < 0) {
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   244
            return (1 << 21) | (1 << 16);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   245
        }
33405
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   246
        return (year << 25 |
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   247
            ldt.getMonthValue() << 21 |
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   248
            ldt.getDayOfMonth() << 16 |
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   249
            ldt.getHour() << 11 |
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   250
            ldt.getMinute() << 5 |
24ee3a0ba28f 8066644: Fix deprecation warnings in jdk.zipfs module
redestad
parents: 27941
diff changeset
   251
            ldt.getSecond() >> 1) & 0xffffffffL;
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   252
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   253
7189
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   254
    // used to adjust values between Windows and java epoch
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   255
    private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   256
    public static final long winToJavaTime(long wtime) {
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   257
        return TimeUnit.MILLISECONDS.convert(
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   258
               wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   259
    }
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   260
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   261
    public static final long javaToWinTime(long time) {
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   262
        return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   263
               - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   264
    }
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   265
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   266
    public static final long unixToJavaTime(long utime) {
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   267
        return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   268
    }
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   269
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   270
    public static final long javaToUnixTime(long time) {
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   271
        return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   272
    }
5749df30059b 6994145: (zipfs) README should be updated
sherman
parents: 6699
diff changeset
   273
6699
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   274
    private static final String regexMetaChars = ".^$+{[]|()";
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   275
    private static final String globMetaChars = "\\*?[{";
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   276
    private static boolean isRegexMeta(char c) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   277
        return regexMetaChars.indexOf(c) != -1;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   278
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   279
    private static boolean isGlobMeta(char c) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   280
        return globMetaChars.indexOf(c) != -1;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   281
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   282
    private static char EOL = 0;  //TBD
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   283
    private static char next(String glob, int i) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   284
        if (i < glob.length()) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   285
            return glob.charAt(i);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   286
        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   287
        return EOL;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   288
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   289
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   290
    /*
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   291
     * Creates a regex pattern from the given glob expression.
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   292
     *
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   293
     * @throws  PatternSyntaxException
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   294
     */
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   295
    public static String toRegexPattern(String globPattern) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   296
        boolean inGroup = false;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   297
        StringBuilder regex = new StringBuilder("^");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   298
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   299
        int i = 0;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   300
        while (i < globPattern.length()) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   301
            char c = globPattern.charAt(i++);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   302
            switch (c) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   303
                case '\\':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   304
                    // escape special characters
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   305
                    if (i == globPattern.length()) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   306
                        throw new PatternSyntaxException("No character to escape",
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   307
                                globPattern, i - 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   308
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   309
                    char next = globPattern.charAt(i++);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   310
                    if (isGlobMeta(next) || isRegexMeta(next)) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   311
                        regex.append('\\');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   312
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   313
                    regex.append(next);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   314
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   315
                case '/':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   316
                    regex.append(c);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   317
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   318
                case '[':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   319
                    // don't match name separator in class
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   320
                    regex.append("[[^/]&&[");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   321
                    if (next(globPattern, i) == '^') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   322
                        // escape the regex negation char if it appears
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   323
                        regex.append("\\^");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   324
                        i++;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   325
                    } else {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   326
                        // negation
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   327
                        if (next(globPattern, i) == '!') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   328
                            regex.append('^');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   329
                            i++;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   330
                        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   331
                        // hyphen allowed at start
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   332
                        if (next(globPattern, i) == '-') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   333
                            regex.append('-');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   334
                            i++;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   335
                        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   336
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   337
                    boolean hasRangeStart = false;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   338
                    char last = 0;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   339
                    while (i < globPattern.length()) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   340
                        c = globPattern.charAt(i++);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   341
                        if (c == ']') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   342
                            break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   343
                        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   344
                        if (c == '/') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   345
                            throw new PatternSyntaxException("Explicit 'name separator' in class",
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   346
                                    globPattern, i - 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   347
                        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   348
                        // TBD: how to specify ']' in a class?
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   349
                        if (c == '\\' || c == '[' ||
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   350
                                c == '&' && next(globPattern, i) == '&') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   351
                            // escape '\', '[' or "&&" for regex class
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   352
                            regex.append('\\');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   353
                        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   354
                        regex.append(c);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   355
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   356
                        if (c == '-') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   357
                            if (!hasRangeStart) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   358
                                throw new PatternSyntaxException("Invalid range",
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   359
                                        globPattern, i - 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   360
                            }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   361
                            if ((c = next(globPattern, i++)) == EOL || c == ']') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   362
                                break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   363
                            }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   364
                            if (c < last) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   365
                                throw new PatternSyntaxException("Invalid range",
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   366
                                        globPattern, i - 3);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   367
                            }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   368
                            regex.append(c);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   369
                            hasRangeStart = false;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   370
                        } else {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   371
                            hasRangeStart = true;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   372
                            last = c;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   373
                        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   374
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   375
                    if (c != ']') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   376
                        throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   377
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   378
                    regex.append("]]");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   379
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   380
                case '{':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   381
                    if (inGroup) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   382
                        throw new PatternSyntaxException("Cannot nest groups",
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   383
                                globPattern, i - 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   384
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   385
                    regex.append("(?:(?:");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   386
                    inGroup = true;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   387
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   388
                case '}':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   389
                    if (inGroup) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   390
                        regex.append("))");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   391
                        inGroup = false;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   392
                    } else {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   393
                        regex.append('}');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   394
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   395
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   396
                case ',':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   397
                    if (inGroup) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   398
                        regex.append(")|(?:");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   399
                    } else {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   400
                        regex.append(',');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   401
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   402
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   403
                case '*':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   404
                    if (next(globPattern, i) == '*') {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   405
                        // crosses directory boundaries
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   406
                        regex.append(".*");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   407
                        i++;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   408
                    } else {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   409
                        // within directory boundary
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   410
                        regex.append("[^/]*");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   411
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   412
                    break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   413
                case '?':
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   414
                   regex.append("[^/]");
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   415
                   break;
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   416
                default:
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   417
                    if (isRegexMeta(c)) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   418
                        regex.append('\\');
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   419
                    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   420
                    regex.append(c);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   421
            }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   422
        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   423
        if (inGroup) {
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   424
            throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   425
        }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   426
        return regex.append('$').toString();
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   427
    }
d8229570529d 6990846: Demo: NIO.2 filesystem provider for zip/jar archives
sherman
parents:
diff changeset
   428
}