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
021/**
022 * Simple placeholder for all those extra fields we don't want to deal
023 * with.
024 *
025 * <p>Assumes local file data and central directory entries are
026 * identical - unless told the opposite.</p>
027 * @NotThreadSafe
028 */
029public class UnrecognizedExtraField implements ZipExtraField {
030
031    /**
032     * The Header-ID.
033     */
034    private ZipShort headerId;
035
036    /**
037     * Set the header id.
038     * @param headerId the header id to use
039     */
040    public void setHeaderId(final ZipShort headerId) {
041        this.headerId = headerId;
042    }
043
044    /**
045     * Get the header id.
046     * @return the header id
047     */
048    @Override
049    public ZipShort getHeaderId() {
050        return headerId;
051    }
052
053    /**
054     * Extra field data in local file data - without
055     * Header-ID or length specifier.
056     */
057    private byte[] localData;
058
059    /**
060     * Set the extra field data in the local file data -
061     * without Header-ID or length specifier.
062     * @param data the field data to use
063     */
064    public void setLocalFileDataData(final byte[] data) {
065        localData = ZipUtil.copy(data);
066    }
067
068    /**
069     * Get the length of the local data.
070     * @return the length of the local data
071     */
072    @Override
073    public ZipShort getLocalFileDataLength() {
074        return new ZipShort(localData != null ? localData.length : 0);
075    }
076
077    /**
078     * Get the local data.
079     * @return the local data
080     */
081    @Override
082    public byte[] getLocalFileDataData() {
083        return ZipUtil.copy(localData);
084    }
085
086    /**
087     * Extra field data in central directory - without
088     * Header-ID or length specifier.
089     */
090    private byte[] centralData;
091
092    /**
093     * Set the extra field data in central directory.
094     * @param data the data to use
095     */
096    public void setCentralDirectoryData(final byte[] data) {
097        centralData = ZipUtil.copy(data);
098    }
099
100    /**
101     * Get the central data length.
102     * If there is no central data, get the local file data length.
103     * @return the central data length
104     */
105    @Override
106    public ZipShort getCentralDirectoryLength() {
107        if (centralData != null) {
108            return new ZipShort(centralData.length);
109        }
110        return getLocalFileDataLength();
111    }
112
113    /**
114     * Get the central data.
115     * @return the central data if present, else return the local file data
116     */
117    @Override
118    public byte[] getCentralDirectoryData() {
119        if (centralData != null) {
120            return ZipUtil.copy(centralData);
121        }
122        return getLocalFileDataData();
123    }
124
125    /**
126     * @param data the array of bytes.
127     * @param offset the source location in the data array.
128     * @param length the number of bytes to use in the data array.
129     * @see ZipExtraField#parseFromLocalFileData(byte[], int, int)
130     */
131    @Override
132    public void parseFromLocalFileData(final byte[] data, final int offset, final int length) {
133        final byte[] tmp = new byte[length];
134        System.arraycopy(data, offset, tmp, 0, length);
135        setLocalFileDataData(tmp);
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 = new byte[length];
148        System.arraycopy(data, offset, tmp, 0, length);
149        setCentralDirectoryData(tmp);
150        if (localData == null) {
151            setLocalFileDataData(tmp);
152        }
153    }
154
155}