    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
    019    package org.apache.commons.compress.utils;
    020
    021    import java.io.UnsupportedEncodingException;
    022
    023    import org.apache.commons.compress.archivers.ArchiveEntry;
    024
    025    /**
    026     * Generic Archive utilities
    027     */
    028    public 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</code> 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</code> 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         * Compare byte buffers, optionally ignoring trailing nulls
    119         *
    120         * @param buffer1
    121         * @param offset1
    122         * @param length1
    123         * @param buffer2
    124         * @param offset2
    125         * @param length2
    126         * @param ignoreTrailingNulls
    127         * @return <code>true</code> if buffer1 and buffer2 have same contents, having regard to trailing nulls
    128         */
    129        public static boolean isEqual(
    130                final byte[] buffer1, final int offset1, final int length1,
    131                final byte[] buffer2, final int offset2, final int length2,
    132                boolean ignoreTrailingNulls){
    133            int minLen=length1 < length2 ? length1 : length2;
    134            for (int i=0; i < minLen; i++){
    135                if (buffer1[offset1+i] != buffer2[offset2+i]){
    136                    return false;
    137                }
    138            }
    139            if (length1 == length2){
    140                return true;
    141            }
    142            if (ignoreTrailingNulls){
    143                if (length1 > length2){
    144                    for(int i = length2; i < length1; i++){
    145                        if (buffer1[offset1+i] != 0){
    146                            return false;
    147                        }
    148                    }
    149                } else {
    150                    for(int i = length1; i < length2; i++){
    151                        if (buffer2[offset2+i] != 0){
    152                            return false;
    153                        }
    154                    }
    155                }
    156                return true;
    157            }
    158            return false;
    159        }
    160
    161        /**
    162         * Compare byte buffers
    163         *
    164         * @param buffer1
    165         * @param offset1
    166         * @param length1
    167         * @param buffer2
    168         * @param offset2
    169         * @param length2
    170         * @return <code>true</code> if buffer1 and buffer2 have same contents
    171         */
    172        public static boolean isEqual(
    173                final byte[] buffer1, final int offset1, final int length1,
    174                final byte[] buffer2, final int offset2, final int length2){
    175            return isEqual(buffer1, offset1, length1, buffer2, offset2, length2, false);
    176        }
    177
    178        /**
    179         * Compare byte buffers
    180         *
    181         * @param buffer1
    182         * @param buffer2
    183         * @return <code>true</code> if buffer1 and buffer2 have same contents
    184         */
    185        public static boolean isEqual(final byte[] buffer1, final byte[] buffer2 ){
    186            return isEqual(buffer1, 0, buffer1.length, buffer2, 0, buffer2.length, false);
    187        }
    188
    189        /**
    190         * Compare byte buffers, optionally ignoring trailing nulls
    191         *
    192         * @param buffer1
    193         * @param buffer2
    194         * @param ignoreTrailingNulls
    195         * @return <code>true</code> if buffer1 and buffer2 have same contents
    196         */
    197        public static boolean isEqual(final byte[] buffer1, final byte[] buffer2, boolean ignoreTrailingNulls){
    198            return isEqual(buffer1, 0, buffer1.length, buffer2, 0, buffer2.length, ignoreTrailingNulls);
    199        }
    200
    201        /**
    202         * Compare byte buffers, ignoring trailing nulls
    203         *
    204         * @param buffer1
    205         * @param offset1
    206         * @param length1
    207         * @param buffer2
    208         * @param offset2
    209         * @param length2
    210         * @return <code>true</code> if buffer1 and buffer2 have same contents, having regard to trailing nulls
    211         */
    212        public static boolean isEqualWithNull(
    213                final byte[] buffer1, final int offset1, final int length1,
    214                final byte[] buffer2, final int offset2, final int length2){
    215            return isEqual(buffer1, offset1, length1, buffer2, offset2, length2, true);
    216        }
    217
    218    }