    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     * Set the header id.
    040     * @param headerId the header id to use
    041     */
    042    public void setHeaderId(final ZipShort headerId) {
    043        this.headerId = headerId;
    044    }
    045
    046    /**
    047     * Get the header id.
    048     * @return the header id
    049     */
    050    @Override
    051    public ZipShort getHeaderId() {
    052        return headerId;
    053    }
    054
    055    /**
    056     * Extra field data in local file data - without
    057     * Header-ID or length specifier.
    058     */
    059    private byte[] localData;
    060
    061    /**
    062     * Set the extra field data in the local file data -
    063     * without Header-ID or length specifier.
    064     * @param data the field data to use
    065     */
    066    public void setLocalFileDataData(final byte[] data) {
    067        localData = ZipUtil.copy(data);
    068    }
    069
    070    /**
    071     * Get the length of the local data.
    072     * @return the length of the local data
    073     */
    074    @Override
    075    public ZipShort getLocalFileDataLength() {
    076        return new ZipShort(localData != null ? localData.length : 0);
    077    }
    078
    079    /**
    080     * Get the local data.
    081     * @return the local data
    082     */
    083    @Override
    084    public byte[] getLocalFileDataData() {
    085        return ZipUtil.copy(localData);
    086    }
    087
    088    /**
    089     * Extra field data in central directory - without
    090     * Header-ID or length specifier.
    091     */
    092    private byte[] centralData;
    093
    094    /**
    095     * Set the extra field data in central directory.
    096     * @param data the data to use
    097     */
    098    public void setCentralDirectoryData(final byte[] data) {
    099        centralData = ZipUtil.copy(data);
    100    }
    101
    102    /**
    103     * Get the central data length.
    104     * If there is no central data, get the local file data length.
    105     * @return the central data length
    106     */
    107    @Override
    108    public ZipShort getCentralDirectoryLength() {
    109        if (centralData != null) {
    110            return new ZipShort(centralData.length);
    111        }
    112        return getLocalFileDataLength();
    113    }
    114
    115    /**
    116     * Get the central data.
    117     * @return the central data if present, else return the local file data
    118     */
    119    @Override
    120    public byte[] getCentralDirectoryData() {
    121        if (centralData != null) {
    122            return ZipUtil.copy(centralData);
    123        }
    124        return getLocalFileDataData();
    125    }
    126
    127    /**
    128     * @param data the array of bytes.
    129     * @param offset the source location in the data array.
    130     * @param length the number of bytes to use in the data array.
    131     * @see ZipExtraField#parseFromLocalFileData(byte[], int, int)
    132     */
    133    @Override
    134    public void parseFromLocalFileData(final byte[] data, final int offset, final int length) {
    135        setLocalFileDataData(Arrays.copyOfRange(data, offset, offset + length));
    136    }
    137
    138    /**
    139     * @param data the array of bytes.
    140     * @param offset the source location in the data array.
    141     * @param length the number of bytes to use in the data array.
    142     * @see ZipExtraField#parseFromCentralDirectoryData(byte[], int, int)
    143     */
    144    @Override
    145    public void parseFromCentralDirectoryData(final byte[] data, final int offset,
    146                                              final int length) {
    147        final byte[] tmp = Arrays.copyOfRange(data, offset, offset + length);
    148        setCentralDirectoryData(tmp);
    149        if (localData == null) {
    150            setLocalFileDataData(tmp);
    151        }
    152    }
    153
    154}