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