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 * @param entry the entry 044 * @return the representation of the entry 045 */ 046 public static String toString(ArchiveEntry entry){ 047 StringBuilder sb = new StringBuilder(); 048 sb.append(entry.isDirectory()? 'd' : '-');// c.f. "ls -l" output 049 String size = Long.toString(entry.getSize()); 050 sb.append(' '); 051 // Pad output to 7 places, leading spaces 052 for(int i=7; i > size.length(); i--){ 053 sb.append(' '); 054 } 055 sb.append(size); 056 sb.append(' ').append(entry.getName()); 057 return sb.toString(); 058 } 059 060 /** 061 * Check if buffer contents matches Ascii String. 062 * 063 * @param expected expected string 064 * @param buffer the buffer 065 * @param offset offset to read from 066 * @param length length of the buffer 067 * @return {@code true} if buffer is the same as the expected string 068 */ 069 public static boolean matchAsciiBuffer( 070 String expected, byte[] buffer, int offset, int length){ 071 byte[] buffer1; 072 try { 073 buffer1 = expected.getBytes(CharsetNames.US_ASCII); 074 } catch (UnsupportedEncodingException e) { 075 throw new RuntimeException(e); // Should not happen 076 } 077 return isEqual(buffer1, 0, buffer1.length, buffer, offset, length, false); 078 } 079 080 /** 081 * Check if buffer contents matches Ascii String. 082 * 083 * @param expected the expected strin 084 * @param buffer the buffer 085 * @return {@code true} if buffer is the same as the expected string 086 */ 087 public static boolean matchAsciiBuffer(String expected, byte[] buffer){ 088 return matchAsciiBuffer(expected, buffer, 0, buffer.length); 089 } 090 091 /** 092 * Convert a string to Ascii bytes. 093 * Used for comparing "magic" strings which need to be independent of the default Locale. 094 * 095 * @param inputString string to convert 096 * @return the bytes 097 */ 098 public static byte[] toAsciiBytes(String inputString){ 099 try { 100 return inputString.getBytes(CharsetNames.US_ASCII); 101 } catch (UnsupportedEncodingException e) { 102 throw new RuntimeException(e); // Should never happen 103 } 104 } 105 106 /** 107 * Convert an input byte array to a String using the ASCII character set. 108 * 109 * @param inputBytes bytes to convert 110 * @return the bytes, interpreted as an Ascii string 111 */ 112 public static String toAsciiString(final byte[] inputBytes){ 113 try { 114 return new String(inputBytes, CharsetNames.US_ASCII); 115 } catch (UnsupportedEncodingException e) { 116 throw new RuntimeException(e); // Should never happen 117 } 118 } 119 120 /** 121 * Convert an input byte array to a String using the ASCII character set. 122 * 123 * @param inputBytes input byte array 124 * @param offset offset within array 125 * @param length length of array 126 * @return the bytes, interpreted as an Ascii string 127 */ 128 public static String toAsciiString(final byte[] inputBytes, int offset, int length){ 129 try { 130 return new String(inputBytes, offset, length, CharsetNames.US_ASCII); 131 } catch (UnsupportedEncodingException e) { 132 throw new RuntimeException(e); // Should never happen 133 } 134 } 135 136 /** 137 * Compare byte buffers, optionally ignoring trailing nulls 138 * 139 * @param buffer1 first buffer 140 * @param offset1 first offset 141 * @param length1 first length 142 * @param buffer2 second buffer 143 * @param offset2 second offset 144 * @param length2 second length 145 * @param ignoreTrailingNulls whether to ignore trailing nulls 146 * @return {@code true} if buffer1 and buffer2 have same contents, having regard to trailing nulls 147 */ 148 public static boolean isEqual( 149 final byte[] buffer1, final int offset1, final int length1, 150 final byte[] buffer2, final int offset2, final int length2, 151 boolean ignoreTrailingNulls){ 152 int minLen=length1 < length2 ? length1 : length2; 153 for (int i=0; i < minLen; i++){ 154 if (buffer1[offset1+i] != buffer2[offset2+i]){ 155 return false; 156 } 157 } 158 if (length1 == length2){ 159 return true; 160 } 161 if (ignoreTrailingNulls){ 162 if (length1 > length2){ 163 for(int i = length2; i < length1; i++){ 164 if (buffer1[offset1+i] != 0){ 165 return false; 166 } 167 } 168 } else { 169 for(int i = length1; i < length2; i++){ 170 if (buffer2[offset2+i] != 0){ 171 return false; 172 } 173 } 174 } 175 return true; 176 } 177 return false; 178 } 179 180 /** 181 * Compare byte buffers 182 * 183 * @param buffer1 the first buffer 184 * @param offset1 the first offset 185 * @param length1 the first length 186 * @param buffer2 the second buffer 187 * @param offset2 the second offset 188 * @param length2 the second length 189 * @return {@code true} if buffer1 and buffer2 have same contents 190 */ 191 public static boolean isEqual( 192 final byte[] buffer1, final int offset1, final int length1, 193 final byte[] buffer2, final int offset2, final int length2){ 194 return isEqual(buffer1, offset1, length1, buffer2, offset2, length2, false); 195 } 196 197 /** 198 * Compare byte buffers 199 * 200 * @param buffer1 the first buffer 201 * @param buffer2 the second buffer 202 * @return {@code true} if buffer1 and buffer2 have same contents 203 */ 204 public static boolean isEqual(final byte[] buffer1, final byte[] buffer2 ){ 205 return isEqual(buffer1, 0, buffer1.length, buffer2, 0, buffer2.length, false); 206 } 207 208 /** 209 * Compare byte buffers, optionally ignoring trailing nulls 210 * 211 * @param buffer1 the first buffer 212 * @param buffer2 the second buffer 213 * @param ignoreTrailingNulls whether to ignore tariling nulls 214 * @return {@code true} if buffer1 and buffer2 have same contents 215 */ 216 public static boolean isEqual(final byte[] buffer1, final byte[] buffer2, boolean ignoreTrailingNulls){ 217 return isEqual(buffer1, 0, buffer1.length, buffer2, 0, buffer2.length, ignoreTrailingNulls); 218 } 219 220 /** 221 * Compare byte buffers, ignoring trailing nulls 222 * 223 * @param buffer1 the first buffer 224 * @param offset1 the first offset 225 * @param length1 the first length 226 * @param buffer2 the second buffer 227 * @param offset2 the second offset 228 * @param length2 the second length 229 * @return {@code true} if buffer1 and buffer2 have same contents, having regard to trailing nulls 230 */ 231 public static boolean isEqualWithNull( 232 final byte[] buffer1, final int offset1, final int length1, 233 final byte[] buffer2, final int offset2, final int length2){ 234 return isEqual(buffer1, offset1, length1, buffer2, offset2, length2, true); 235 } 236 237 /** 238 * Returns true if the first N bytes of an array are all zero 239 * 240 * @param a 241 * The array to check 242 * @param size 243 * The number of characters to check (not the size of the array) 244 * @return true if the first N bytes are zero 245 */ 246 public static boolean isArrayZero(byte[] a, int size) { 247 for (int i = 0; i < size; i++) { 248 if (a[i] != 0) { 249 return false; 250 } 251 } 252 return true; 253 } 254}