1 /* 2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package com.ohos.hapsigntool.zip; 17 18 import com.ohos.hapsigntool.utils.FileUtils; 19 20 import java.io.File; 21 import java.io.FileInputStream; 22 import java.io.IOException; 23 24 /** 25 * resolve zip ZipEntry data 26 * 27 * @since 2023/12/04 28 */ 29 public class ZipEntryData { 30 /** 31 * data descriptor has or not mask 32 */ 33 public static final short HAS_DATA_DESCRIPTOR_MASK = 0x08; 34 35 /** 36 * data descriptor has or not flag mask 37 */ 38 public static final short NOT_HAS_DATA_DESCRIPTOR_FLAG = 0; 39 40 private ZipEntryHeader zipEntryHeader; 41 42 private long fileOffset; 43 44 private long fileSize; 45 46 private DataDescriptor dataDescriptor; 47 48 private long length; 49 getZipEntryHeader()50 public ZipEntryHeader getZipEntryHeader() { 51 return zipEntryHeader; 52 } 53 54 /** 55 * init zip entry by file 56 * 57 * @param file zip file 58 * @param entryOffset entry start offset 59 * @param fileSize compress file size 60 * @return zip entry 61 * @throws IOException read zip exception 62 */ getZipEntry(File file, long entryOffset, long fileSize)63 public static ZipEntryData getZipEntry(File file, long entryOffset, long fileSize) 64 throws IOException { 65 try (FileInputStream input = new FileInputStream(file)) { 66 long offset = entryOffset; 67 // read entry header by file and offset. 68 byte[] headBytes = FileUtils.readInputByOffsetAndLength(input, entryOffset, ZipEntryHeader.HEADER_LENGTH); 69 ZipEntryHeader entryHeader = ZipEntryHeader.getZipEntryHeader(headBytes); 70 offset += ZipEntryHeader.HEADER_LENGTH; 71 72 // read entry file name and extra by offset. 73 if (entryHeader.getFileNameLength() > 0) { 74 byte[] fileNameBytes = FileUtils.readInputByLength(input, entryHeader.getFileNameLength()); 75 entryHeader.readFileName(fileNameBytes); 76 offset += entryHeader.getFileNameLength(); 77 } 78 79 if (entryHeader.getExtraLength() > 0) { 80 byte[] extraBytes = FileUtils.readInputByLength(input, entryHeader.getExtraLength()); 81 entryHeader.readExtra(extraBytes); 82 offset += entryHeader.getExtraLength(); 83 } 84 85 // skip file data , save file offset and size. 86 ZipEntryData entry = new ZipEntryData(); 87 entry.setFileOffset(offset); 88 entry.setFileSize(fileSize); 89 input.skip(fileSize); 90 91 long entryLength = entryHeader.getLength() + fileSize; 92 short flag = entryHeader.getFlag(); 93 // set desc null flag 94 boolean hasDesc = (flag & HAS_DATA_DESCRIPTOR_MASK) != NOT_HAS_DATA_DESCRIPTOR_FLAG; 95 if (hasDesc) { 96 // if entry has data descriptor, read entry data descriptor. 97 byte[] desBytes = FileUtils.readInputByLength(input, DataDescriptor.DES_LENGTH); 98 DataDescriptor dataDesc = DataDescriptor.getDataDescriptor(desBytes); 99 entryLength += DataDescriptor.DES_LENGTH; 100 entry.setDataDescriptor(dataDesc); 101 } 102 entry.setZipEntryHeader(entryHeader); 103 entry.setLength(entryLength); 104 return entry; 105 } 106 } 107 setZipEntryHeader(ZipEntryHeader zipEntryHeader)108 public void setZipEntryHeader(ZipEntryHeader zipEntryHeader) { 109 this.zipEntryHeader = zipEntryHeader; 110 } 111 getDataDescriptor()112 public DataDescriptor getDataDescriptor() { 113 return dataDescriptor; 114 } 115 setDataDescriptor(DataDescriptor dataDescriptor)116 public void setDataDescriptor(DataDescriptor dataDescriptor) { 117 this.dataDescriptor = dataDescriptor; 118 } 119 getFileOffset()120 public long getFileOffset() { 121 return fileOffset; 122 } 123 setFileOffset(long fileOffset)124 public void setFileOffset(long fileOffset) { 125 this.fileOffset = fileOffset; 126 } 127 getFileSize()128 public long getFileSize() { 129 return fileSize; 130 } 131 setFileSize(long fileSize)132 public void setFileSize(long fileSize) { 133 this.fileSize = fileSize; 134 } 135 getLength()136 public long getLength() { 137 return length; 138 } 139 setLength(long length)140 public void setLength(long length) { 141 this.length = length; 142 } 143 }