1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.commons.compress.archivers.sevenz; 19 20 import java.util.LinkedList; 21 22 /** 23 * The unit of solid compression. 24 */ 25 class Folder { 26 /// List of coders used in this folder, eg. one for compression, one for encryption. 27 Coder[] coders; 28 /// Total number of input streams across all coders. 29 /// this field is currently unused but technically part of the 7z API 30 long totalInputStreams; 31 /// Total number of output streams across all coders. 32 long totalOutputStreams; 33 /// Mapping between input and output streams. 34 BindPair[] bindPairs; 35 /// Indeces of input streams, one per input stream not listed in bindPairs. 36 long[] packedStreams; 37 /// Unpack sizes, per each output stream. 38 long[] unpackSizes; 39 /// Whether the folder has a CRC. 40 boolean hasCrc; 41 /// The CRC, if present. 42 long crc; 43 /// The number of unpack substreams, product of the number of 44 /// output streams and the nuber of non-empty files in this 45 /// folder. 46 int numUnpackSubStreams; 47 48 /** 49 * Sorts Coders using bind pairs. 50 * <p>The first coder reads from the packed stream (we currently 51 * only support single input stream decoders), the second reads 52 * from the output of the first and so on.</p> 53 */ getOrderedCoders()54 Iterable<Coder> getOrderedCoders() { 55 final LinkedList<Coder> l = new LinkedList<>(); 56 int current = (int) packedStreams[0]; // more that 2^31 coders? 57 while (current != -1) { 58 l.addLast(coders[current]); 59 final int pair = findBindPairForOutStream(current); 60 current = pair != -1 ? (int) bindPairs[pair].inIndex : -1; 61 } 62 return l; 63 } 64 findBindPairForInStream(final int index)65 int findBindPairForInStream(final int index) { 66 for (int i = 0; i < bindPairs.length; i++) { 67 if (bindPairs[i].inIndex == index) { 68 return i; 69 } 70 } 71 return -1; 72 } 73 findBindPairForOutStream(final int index)74 int findBindPairForOutStream(final int index) { 75 for (int i = 0; i < bindPairs.length; i++) { 76 if (bindPairs[i].outIndex == index) { 77 return i; 78 } 79 } 80 return -1; 81 } 82 getUnpackSize()83 long getUnpackSize() { 84 if (totalOutputStreams == 0) { 85 return 0; 86 } 87 for (int i = ((int)totalOutputStreams) - 1; i >= 0; i--) { 88 if (findBindPairForOutStream(i) < 0) { 89 return unpackSizes[i]; 90 } 91 } 92 return 0; 93 } 94 getUnpackSizeForCoder(final Coder coder)95 long getUnpackSizeForCoder(final Coder coder) { 96 if (coders != null) { 97 for (int i = 0; i < coders.length; i++) { 98 if (coders[i] == coder) { 99 return unpackSizes[i]; 100 } 101 } 102 } 103 return 0; 104 } 105 106 @Override toString()107 public String toString() { 108 return "Folder with " + coders.length + " coders, " + totalInputStreams 109 + " input streams, " + totalOutputStreams + " output streams, " 110 + bindPairs.length + " bind pairs, " + packedStreams.length 111 + " packed streams, " + unpackSizes.length + " unpack sizes, " 112 + (hasCrc ? "with CRC " + crc : "without CRC") 113 + " and " + numUnpackSubStreams + " unpack streams"; 114 } 115 } 116 117