001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.compress.compressors.gzip; 020 021import java.nio.charset.Charset; 022import java.nio.charset.StandardCharsets; 023import java.util.LinkedHashMap; 024import java.util.Map; 025 026import org.apache.commons.compress.compressors.FileNameUtil; 027 028/** 029 * Utility code for the GZIP compression format. 030 * 031 * @see <a href="https://datatracker.ietf.org/doc/html/rfc1952">RFC 1952 GZIP File Format Specification</a> 032 * @ThreadSafe 033 */ 034public class GzipUtils { 035 036 /** Header flag indicating a comment follows the header. */ 037 static final int FCOMMENT = 0x10; 038 039 /** Header flag indicating an EXTRA subfields collection follows the header. */ 040 static final int FEXTRA = 0x04; 041 042 /** Header flag indicating a header CRC follows the header. */ 043 static final int FHCRC = 0x02; 044 045 private static final FileNameUtil fileNameUtil; 046 047 /** Header flag indicating a file name follows the header. */ 048 static final int FNAME = 0x08; 049 050 static final int FRESERVED = 0xE0; 051 052 /** 053 * Charset for file name and comments per the <a href="https://tools.ietf.org/html/rfc1952">GZIP File Format Specification</a>. 054 */ 055 static final Charset GZIP_ENCODING = StandardCharsets.ISO_8859_1; 056 057 /** 058 * Member header ID1 (IDentification 1). 059 * 060 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 061 */ 062 static final int ID1 = 31; 063 064 /** 065 * Member header ID2 (IDentification 2). 066 * 067 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 068 */ 069 static final int ID2 = 139; 070 071 /** 072 * Member header XFL (eXtra FLags) when the "deflate" method (CM = 8) is set, then XFL = 2 means the compressor used maximum compression (slowest 073 * algorithm). 074 * 075 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 076 */ 077 static final byte XFL_MAX_COMPRESSION = 2; 078 079 /** 080 * Member header XFL (eXtra FLags) when the "deflate" method (CM = 8) is set, then XFL = 4 means the compressor used the fastest algorithm. 081 * 082 * See <a href="https://datatracker.ietf.org/doc/html/rfc1952#page-5">RFC1952</a> 2.3.1. Member header and trailer. 083 */ 084 static final byte XFL_MAX_SPEED = 4; 085 086 static final byte XFL_UNKNOWN = 0; 087 088 /** 089 * Using {@link LinkedHashMap} so {@code .tgz} is preferred over {@code .taz} as compressed extension of {@code .tar} as FileNameUtil will use the first one 090 * found. 091 */ 092 static { 093 final Map<String, String> uncompressSuffix = new LinkedHashMap<>(); 094 uncompressSuffix.put(".tgz", ".tar"); 095 uncompressSuffix.put(".taz", ".tar"); 096 uncompressSuffix.put(".svgz", ".svg"); 097 uncompressSuffix.put(".cpgz", ".cpio"); 098 uncompressSuffix.put(".wmz", ".wmf"); 099 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}