• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }