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 * http://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.archivers.tar; 20 21 import java.io.IOException; 22 import java.util.ArrayList; 23 import java.util.List; 24 25 /** 26 * A sparse entry in a <a href="https://www.gnu.org/software/tar/manual/html_node/Standard.html">Tar archive</a>. 27 * 28 * <p> 29 * The C structure for a sparse entry is: 30 * 31 * <pre> 32 * struct posix_header { 33 * struct sparse sp[21]; // TarConstants.SPARSELEN_GNU_SPARSE - offset 0 34 * char isextended; // TarConstants.ISEXTENDEDLEN_GNU_SPARSE - offset 504 35 * }; 36 * </pre> 37 * 38 * Whereas, "struct sparse" is: 39 * 40 * <pre> 41 * struct sparse { 42 * char offset[12]; // offset 0 43 * char numbytes[12]; // offset 12 44 * }; 45 * </pre> 46 * 47 * <p> 48 * Each such struct describes a block of data that has actually been written to the archive. The offset describes where in the extracted file the data is 49 * supposed to start and the numbytes provides the length of the block. When extracting the entry the gaps between the sparse structs are equivalent to areas 50 * filled with zero bytes. 51 * </p> 52 */ 53 54 public class TarArchiveSparseEntry implements TarConstants { 55 /** If an extension sparse header follows. */ 56 private final boolean isExtended; 57 58 private final List<TarArchiveStructSparse> sparseHeaders; 59 60 /** 61 * Constructs an entry from an archive's header bytes. File is set to null. 62 * 63 * @param headerBuf The header bytes from a tar archive entry. 64 * @throws IOException on unknown format 65 */ 66 public TarArchiveSparseEntry(final byte[] headerBuf) throws IOException { 67 int offset = 0; 68 sparseHeaders = new ArrayList<>(TarUtils.readSparseStructs(headerBuf, 0, SPARSE_HEADERS_IN_EXTENSION_HEADER)); 69 offset += SPARSELEN_GNU_SPARSE; 70 isExtended = TarUtils.parseBoolean(headerBuf, offset); 71 } 72 73 /** 74 * Gets information about the configuration for the sparse entry. 75 * 76 * @since 1.20 77 * @return information about the configuration for the sparse entry. 78 */ 79 public List<TarArchiveStructSparse> getSparseHeaders() { 80 return sparseHeaders; 81 } 82 83 public boolean isExtended() { 84 return isExtended; 85 } 86 }