    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 * http://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.commons.compress.archivers.zip;
    020
    021import java.util.Arrays;
    022
    023/**
    024 * Simple placeholder for all those extra fields we don't want to deal
    025 * with.
    026 *
    027 * <p>Assumes local file data and central directory entries are
    028 * identical - unless told the opposite.</p>
    029 * @NotThreadSafe
    030 */
    031public class UnrecognizedExtraField implements ZipExtraField {
    032
    033    /**
    034     * The Header-ID.
    035     */
    036    private ZipShort headerId;
    037
    038    /**
    039     * Extra field data in local file data - without
    040     * Header-ID or length specifier.
    041     */
    042    private byte[] localData;
    043
    044    /**
    045     * Extra field data in central directory - without
    046     * Header-ID or length specifier.
    047     */
    048    private byte[] centralData;
    049
    050    /**
    051     * Get the central data.
    052     * @return the central data if present, else return the local file data
    053     */
    054    @Override
    055    public byte[] getCentralDirectoryData() {
    056        if (centralData != null) {
    057            return ZipUtil.copy(centralData);
    058        }
    059        return getLocalFileDataData();
    060    }
    061
    062    /**
    063     * Get the central data length.
    064     * If there is no central data, get the local file data length.
    065     * @return the central data length
    066     */
    067    @Override
    068    public ZipShort getCentralDirectoryLength() {
    069        if (centralData != null) {
    070            return new ZipShort(centralData.length);
    071        }
    072        return getLocalFileDataLength();
    073    }
    074
    075    /**
    076     * Get the header id.
    077     * @return the header id
    078     */
    079    @Override
    080    public ZipShort getHeaderId() {
    081        return headerId;
    082    }
    083
    084    /**
    085     * Get the local data.
    086     * @return the local data
    087     */
    088    @Override
    089    public byte[] getLocalFileDataData() {
    090        return ZipUtil.copy(localData);
    091    }
    092
    093    /**
    094     * Get the length of the local data.
    095     * @return the length of the local data
    096     */
    097    @Override
    098    public ZipShort getLocalFileDataLength() {
    099        return new ZipShort(localData != null ? localData.length : 0);
    100    }
    101
    102    /**
    103     * @param data the array of bytes.
    104     * @param offset the source location in the data array.
    105     * @param length the number of bytes to use in the data array.
    106     * @see ZipExtraField#parseFromCentralDirectoryData(byte[], int, int)
    107     */
    108    @Override
    109    public void parseFromCentralDirectoryData(final byte[] data, final int offset,
    110                                              final int length) {
    111        final byte[] tmp = Arrays.copyOfRange(data, offset, offset + length);
    112        setCentralDirectoryData(tmp);
    113        if (localData == null) {
    114            setLocalFileDataData(tmp);
    115        }
    116    }
    117
    118    /**
    119     * @param data the array of bytes.
    120     * @param offset the source location in the data array.
    121     * @param length the number of bytes to use in the data array.
    122     * @see ZipExtraField#parseFromLocalFileData(byte[], int, int)
    123     */
    124    @Override
    125    public void parseFromLocalFileData(final byte[] data, final int offset, final int length) {
    126        setLocalFileDataData(Arrays.copyOfRange(data, offset, offset + length));
    127    }
    128
    129    /**
    130     * Set the extra field data in central directory.
    131     * @param data the data to use
    132     */
    133    public void setCentralDirectoryData(final byte[] data) {
    134        centralData = ZipUtil.copy(data);
    135    }
    136
    137    /**
    138     * Set the header id.
    139     * @param headerId the header id to use
    140     */
    141    public void setHeaderId(final ZipShort headerId) {
    142        this.headerId = headerId;
    143    }
    144
    145    /**
    146     * Set the extra field data in the local file data -
    147     * without Header-ID or length specifier.
    148     * @param data the field data to use
    149     */
    150    public void setLocalFileDataData(final byte[] data) {
    151        localData = ZipUtil.copy(data);
    152    }
    153
    154}