    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         * 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</code> 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</code> 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</code> 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</code> 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</code> 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    }