001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018 019package org.apache.commons.compress.utils; 020 021import java.io.UnsupportedEncodingException; 022 023import org.apache.commons.compress.archivers.ArchiveEntry; 024 025/** 026 * Generic Archive utilities 027 */ 028public class ArchiveUtils { 029 030 /** Private constructor to prevent instantiation of this utility class. */ 031 private ArchiveUtils(){ 032 } 033 034 /** 035 * Generates a string containing the name, isDirectory setting and size of an entry. 036 * <p> 037 * For example: 038 * <pre> 039 * - 2000 main.c 040 * d 100 testfiles 041 * </pre> 042 * 043 * @return the representation of the entry 044 */ 045 public static String toString(ArchiveEntry entry){ 046 StringBuilder sb = new StringBuilder(); 047 sb.append(entry.isDirectory()? 'd' : '-');// c.f. "ls -l" output 048 String size = Long.toString(entry.getSize()); 049 sb.append(' '); 050 // Pad output to 7 places, leading spaces 051 for(int i=7; i > size.length(); i--){ 052 sb.append(' '); 053 } 054 sb.append(size); 055 sb.append(' ').append(entry.getName()); 056 return sb.toString(); 057 } 058 059 /** 060 * Check if buffer contents matches Ascii String. 061 * 062 * @param expected 063 * @param buffer 064 * @param offset 065 * @param length 066 * @return {@code true} if buffer is the same as the expected string 067 */ 068 public static boolean matchAsciiBuffer( 069 String expected, byte[] buffer, int offset, int length){ 070 byte[] buffer1; 071 try { 072 buffer1 = expected.getBytes(CharsetNames.US_ASCII); 073 } catch (UnsupportedEncodingException e) { 074 throw new RuntimeException(e); // Should not happen 075 } 076 return isEqual(buffer1, 0, buffer1.length, buffer, offset, length, false); 077 } 078 079 /** 080 * Check if buffer contents matches Ascii String. 081 * 082 * @param expected 083 * @param buffer 084 * @return {@code true} if buffer is the same as the expected string 085 */ 086 public static boolean matchAsciiBuffer(String expected, byte[] buffer){ 087 return matchAsciiBuffer(expected, buffer, 0, buffer.length); 088 } 089 090 /** 091 * Convert a string to Ascii bytes. 092 * Used for comparing "magic" strings which need to be independent of the default Locale. 093 * 094 * @param inputString 095 * @return the bytes 096 */ 097 public static byte[] toAsciiBytes(String inputString){ 098 try { 099 return inputString.getBytes(CharsetNames.US_ASCII); 100 } catch (UnsupportedEncodingException e) { 101 throw new RuntimeException(e); // Should never happen 102 } 103 } 104 105 /** 106 * Convert an input byte array to a String using the ASCII character set. 107 * 108 * @param inputBytes 109 * @return the bytes, interpreted as an Ascii string 110 */ 111 public static String toAsciiString(final byte[] inputBytes){ 112 try { 113 return new String(inputBytes, CharsetNames.US_ASCII); 114 } catch (UnsupportedEncodingException e) { 115 throw new RuntimeException(e); // Should never happen 116 } 117 } 118 119 /** 120 * Convert an input byte array to a String using the ASCII character set. 121 * 122 * @param inputBytes input byte array 123 * @param offset offset within array 124 * @param length length of array 125 * @return the bytes, interpreted as an Ascii string 126 */ 127 public static String toAsciiString(final byte[] inputBytes, int offset, int length){ 128 try { 129 return new String(inputBytes, offset, length, CharsetNames.US_ASCII); 130 } catch (UnsupportedEncodingException e) { 131 throw new RuntimeException(e); // Should never happen 132 } 133 } 134 135 /** 136 * Compare byte buffers, optionally ignoring trailing nulls 137 * 138 * @param buffer1 139 * @param offset1 140 * @param length1 141 * @param buffer2 142 * @param offset2 143 * @param length2 144 * @param ignoreTrailingNulls 145 * @return {@code true} if buffer1 and buffer2 have same contents, having regard to trailing nulls 146 */ 147 public static boolean isEqual( 148 final byte[] buffer1, final int offset1, final int length1, 149 final byte[] buffer2, final int offset2, final int length2, 150 boolean ignoreTrailingNulls){ 151 int minLen=length1 < length2 ? length1 : length2; 152 for (int i=0; i < minLen; i++){ 153 if (buffer1[offset1+i] != buffer2[offset2+i]){ 154 return false; 155 } 156 } 157 if (length1 == length2){ 158 return true; 159 } 160 if (ignoreTrailingNulls){ 161 if (length1 > length2){ 162 for(int i = length2; i < length1; i++){ 163 if (buffer1[offset1+i] != 0){ 164 return false; 165 } 166 } 167 } else { 168 for(int i = length1; i < length2; i++){ 169 if (buffer2[offset2+i] != 0){ 170 return false; 171 } 172 } 173 } 174 return true; 175 } 176 return false; 177 } 178 179 /** 180 * Compare byte buffers 181 * 182 * @param buffer1 183 * @param offset1 184 * @param length1 185 * @param buffer2 186 * @param offset2 187 * @param length2 188 * @return {@code true} if buffer1 and buffer2 have same contents 189 */ 190 public static boolean isEqual( 191 final byte[] buffer1, final int offset1, final int length1, 192 final byte[] buffer2, final int offset2, final int length2){ 193 return isEqual(buffer1, offset1, length1, buffer2, offset2, length2, false); 194 } 195 196 /** 197 * Compare byte buffers 198 * 199 * @param buffer1 200 * @param buffer2 201 * @return {@code true} if buffer1 and buffer2 have same contents 202 */ 203 public static boolean isEqual(final byte[] buffer1, final byte[] buffer2 ){ 204 return isEqual(buffer1, 0, buffer1.length, buffer2, 0, buffer2.length, false); 205 } 206 207 /** 208 * Compare byte buffers, optionally ignoring trailing nulls 209 * 210 * @param buffer1 211 * @param buffer2 212 * @param ignoreTrailingNulls 213 * @return {@code true} if buffer1 and buffer2 have same contents 214 */ 215 public static boolean isEqual(final byte[] buffer1, final byte[] buffer2, boolean ignoreTrailingNulls){ 216 return isEqual(buffer1, 0, buffer1.length, buffer2, 0, buffer2.length, ignoreTrailingNulls); 217 } 218 219 /** 220 * Compare byte buffers, ignoring trailing nulls 221 * 222 * @param buffer1 223 * @param offset1 224 * @param length1 225 * @param buffer2 226 * @param offset2 227 * @param length2 228 * @return {@code true} if buffer1 and buffer2 have same contents, having regard to trailing nulls 229 */ 230 public static boolean isEqualWithNull( 231 final byte[] buffer1, final int offset1, final int length1, 232 final byte[] buffer2, final int offset2, final int length2){ 233 return isEqual(buffer1, offset1, length1, buffer2, offset2, length2, true); 234 } 235 236 /** 237 * Returns true if the first N bytes of an array are all zero 238 * 239 * @param a 240 * The array to check 241 * @param size 242 * The number of characters to check (not the size of the array) 243 * @return true if the first N bytes are zero 244 */ 245 public static boolean isArrayZero(byte[] a, int size) { 246 for (int i = 0; i < size; i++) { 247 if (a[i] != 0) { 248 return false; 249 } 250 } 251 return true; 252 } 253}