    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 * Wrapper for extra field data that doesn't conform to the recommended format of header-tag + size + data.
    023 *
    024 * <p>The header-id is artificial (and not listed as a known ID in <a
    025 * href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">APPNOTE.TXT</a>).  Since it isn't used anywhere
    026 * except to satisfy the ZipExtraField contract it shouldn't matter anyway.</p>
    027 *
    028 * @since 1.1
    029 * @NotThreadSafe
    030 */
    031public final class UnparseableExtraFieldData implements ZipExtraField {
    032    private static final ZipShort HEADER_ID = new ZipShort(0xACC1);
    033
    034    private byte[] localFileData;
    035    private byte[] centralDirectoryData;
    036
    037    /**
    038     * The Header-ID.
    039     *
    040     * @return a completely arbitrary value that should be ignored.
    041     */
    042    @Override
    043    public ZipShort getHeaderId() {
    044        return HEADER_ID;
    045    }
    046
    047    /**
    048     * Length of the complete extra field in the local file data.
    049     *
    050     * @return The LocalFileDataLength value
    051     */
    052    @Override
    053    public ZipShort getLocalFileDataLength() {
    054        return new ZipShort(localFileData == null ? 0 : localFileData.length);
    055    }
    056
    057    /**
    058     * Length of the complete extra field in the central directory.
    059     *
    060     * @return The CentralDirectoryLength value
    061     */
    062    @Override
    063    public ZipShort getCentralDirectoryLength() {
    064        return centralDirectoryData == null
    065            ? getLocalFileDataLength()
    066            : new ZipShort(centralDirectoryData.length);
    067    }
    068
    069    /**
    070     * The actual data to put into local file data.
    071     *
    072     * @return The LocalFileDataData value
    073     */
    074    @Override
    075    public byte[] getLocalFileDataData() {
    076        return ZipUtil.copy(localFileData);
    077    }
    078
    079    /**
    080     * The actual data to put into central directory.
    081     *
    082     * @return The CentralDirectoryData value
    083     */
    084    @Override
    085    public byte[] getCentralDirectoryData() {
    086        return centralDirectoryData == null
    087            ? getLocalFileDataData() : ZipUtil.copy(centralDirectoryData);
    088    }
    089
    090    /**
    091     * Populate data from this array as if it was in local file data.
    092     *
    093     * @param buffer the buffer to read data from
    094     * @param offset offset into buffer to read data
    095     * @param length the length of data
    096     */
    097    @Override
    098    public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length) {
    099        localFileData = new byte[length];
    100        System.arraycopy(buffer, offset, localFileData, 0, length);
    101    }
    102
    103    /**
    104     * Populate data from this array as if it was in central directory data.
    105     *
    106     * @param buffer the buffer to read data from
    107     * @param offset offset into buffer to read data
    108     * @param length the length of data
    109     */
    110    @Override
    111    public void parseFromCentralDirectoryData(final byte[] buffer, final int offset,
    112                                              final int length) {
    113        centralDirectoryData = new byte[length];
    114        System.arraycopy(buffer, offset, centralDirectoryData, 0, length);
    115        if (localFileData == null) {
    116            parseFromLocalFileData(buffer, offset, length);
    117        }
    118    }
    119
    120}