1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * https://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.commons.compress.compressors.gzip; 20 21 import java.nio.charset.Charset; 22 import java.nio.charset.StandardCharsets; 23 import java.util.LinkedHashMap; 24 import java.util.Map; 25 26 import org.apache.commons.compress.compressors.FileNameUtil; 27 28 /** 29 * Utility code for the GZIP compression format. 30 * 31 * @see <a href="https://datatracker.ietf.org/doc/html/rfc1952">RFC 1952 GZIP File Format Specification</a> 32 * @ThreadSafe 33 */ 34 public class GzipUtils { 35 36 /** Header flag indicating a comment follows the header. */ 37 static final int FCOMMENT = 0x10; 38 39 /** Header flag indicating an EXTRA subfields collection follows the header. */ 40 static final int FEXTRA = 0x04; 41 42 /** Header flag indicating a header CRC follows the header. */ 43 static final int FHCRC = 0x02; 44 45 private static final FileNameUtil fileNameUtil; 46 47 /** Header flag indicating a file name follows the header. */ 48 static final int FNAME = 0x08; 49 50 static final int FRESERVED = 0xE0; 51 52 /** 53 * Charset for file name and comments per the <a href="https://tools.ietf.org/html/rfc1952">GZIP File Format Specification</a>. 54 */ 55 static final Charset GZIP_ENCODING = StandardCharsets.ISO_8859_1; 56 57 /** 58 * Member header ID1 (IDentification 1). 59 * 60 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 61 */ 62 static final int ID1 = 31; 63 64 /** 65 * Member header ID2 (IDentification 2). 66 * 67 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 68 */ 69 static final int ID2 = 139; 70 71 /** 72 * Member header XFL (eXtra FLags) when the "deflate" method (CM = 8) is set, then XFL = 2 means the compressor used maximum compression (slowest 73 * algorithm). 74 * 75 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 76 */ 77 static final byte XFL_MAX_COMPRESSION = 2; 78 79 /** 80 * Member header XFL (eXtra FLags) when the "deflate" method (CM = 8) is set, then XFL = 4 means the compressor used the fastest algorithm. 81 * 82 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 83 */ 84 static final byte XFL_MAX_SPEED = 4; 85 86 static final byte XFL_UNKNOWN = 0; 87 88 /** 89 * Using {@link LinkedHashMap} so {@code .tgz} is preferred over {@code .taz} as compressed extension of {@code .tar} as FileNameUtil will use the first one 90 * found. 91 */ 92 static { 93 final Map<String, String> uncompressSuffix = new LinkedHashMap<>(); 94 uncompressSuffix.put(".tgz", ".tar"); 95 uncompressSuffix.put(".taz", ".tar"); 96 uncompressSuffix.put(".svgz", ".svg"); 97 uncompressSuffix.put(".cpgz", ".cpio"); 98 uncompressSuffix.put(".wmz", ".wmf"); 99 uncompressSuffix.put(".emz", ".emf"); 100 uncompressSuffix.put(".gz", ""); 101 uncompressSuffix.put(".z", ""); 102 uncompressSuffix.put("-gz", ""); 103 uncompressSuffix.put("-z", ""); 104 uncompressSuffix.put("_z", ""); 105 fileNameUtil = new FileNameUtil(uncompressSuffix, ".gz"); 106 } 107 /** 108 * Maps the given file name to the name that the file should have after compression with gzip. Common file types with custom suffixes for compressed 109 * versions are automatically detected and correctly mapped. For example the name "package.tar" is mapped to "package.tgz". If no custom mapping is 110 * applicable, then the default ".gz" suffix is appended to the file name. 111 * 112 * @param fileName name of a file 113 * @return name of the corresponding compressed file 114 * @deprecated Use {@link #getCompressedFileName(String)}. 115 */ 116 @Deprecated 117 public static String getCompressedFilename(final String fileName) { 118 return fileNameUtil.getCompressedFileName(fileName); 119 } 120 121 /** 122 * Maps the given file name to the name that the file should have after compression with gzip. Common file types with custom suffixes for compressed 123 * versions are automatically detected and correctly mapped. For example the name "package.tar" is mapped to "package.tgz". If no custom mapping is 124 * applicable, then the default ".gz" suffix is appended to the file name. 125 * 126 * @param fileName name of a file 127 * @return name of the corresponding compressed file 128 * @since 1.25.0 129 */ 130 public static String getCompressedFileName(final String fileName) { 131 return fileNameUtil.getCompressedFileName(fileName); 132 } 133 134 /** 135 * Maps the given name of a gzip-compressed file to the name that the file should have after uncompression. Commonly used file type specific suffixes like 136 * ".tgz" or ".svgz" are automatically detected and correctly mapped. For example the name "package.tgz" is mapped to "package.tar". And any file names with 137 * the generic ".gz" suffix (or any other generic gzip suffix) is mapped to a name without that suffix. If no gzip suffix is detected, then the file name is 138 * returned unmapped. 139 * 140 * @param fileName name of a file 141 * @return name of the corresponding uncompressed file 142 * @deprecated Use {@link #getUncompressedFileName(String)}. 143 */ 144 @Deprecated 145 public static String getUncompressedFilename(final String fileName) { 146 return fileNameUtil.getUncompressedFileName(fileName); 147 } 148 149 /** 150 * Maps the given name of a gzip-compressed file to the name that the file should have after uncompression. Commonly used file type specific suffixes like 151 * ".tgz" or ".svgz" are automatically detected and correctly mapped. For example the name "package.tgz" is mapped to "package.tar". And any file names with 152 * the generic ".gz" suffix (or any other generic gzip suffix) is mapped to a name without that suffix. If no gzip suffix is detected, then the file name is 153 * returned unmapped. 154 * 155 * @param fileName name of a file 156 * @return name of the corresponding uncompressed file 157 * @since 1.25.0 158 */ 159 public static String getUncompressedFileName(final String fileName) { 160 return fileNameUtil.getUncompressedFileName(fileName); 161 } 162 163 /** 164 * Detects common gzip suffixes in the given file name. 165 * 166 * @param fileName name of a file 167 * @return {@code true} if the file name has a common gzip suffix, {@code false} otherwise 168 * @deprecated Use {@link #isCompressedFileName(String)}. 169 */ 170 @Deprecated 171 public static boolean isCompressedFilename(final String fileName) { 172 return fileNameUtil.isCompressedFileName(fileName); 173 } 174 175 /** 176 * Detects common gzip suffixes in the given file name. 177 * 178 * @param fileName name of a file 179 * @return {@code true} if the file name has a common gzip suffix, {@code false} otherwise 180 * @since 1.25.0 181 */ 182 public static boolean isCompressedFileName(final String fileName) { 183 return fileNameUtil.isCompressedFileName(fileName); 184 } 185 186 /** Private constructor to prevent instantiation of this utility class. */ 187 private GzipUtils() { 188 } 189 190 }