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