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 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 }