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