• 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.error.ZipException;
19 
20 import java.util.Arrays;
21 
22 /**
23  * ZipEntry and CentralDirectory data
24  *
25  * @since 2023/12/02
26  */
27 public class ZipEntry {
28     private ZipEntryData zipEntryData;
29 
30     private CentralDirectory fileEntryIncentralDirectory;
31 
32     /**
33      * alignment one entry
34      *
35      * @param alignNum  need align bytes length
36      * @return add bytes length
37      * @throws ZipException alignment exception
38      */
alignment(int alignNum)39     public int alignment(int alignNum) throws ZipException {
40         // if cd extra len bigger than entry extra len, make cd and entry extra length equals
41         int padding = calZeroPaddingLengthForEntryExtra();
42         int remainder = (int) ((zipEntryData.getZipEntryHeader().getLength()
43                 + fileEntryIncentralDirectory.getOffset()) % alignNum);
44 
45         if (remainder == 0) {
46             return padding;
47         }
48         int add = alignNum - remainder;
49         int newExtraLength = zipEntryData.getZipEntryHeader().getExtraLength() + add;
50         if (newExtraLength > UnsignedDecimalUtil.MAX_UNSIGNED_SHORT_VALUE) {
51             throw new ZipException("can not align " + zipEntryData.getZipEntryHeader().getFileName());
52         }
53         setEntryHeaderNewExtraLength(newExtraLength);
54         setCenterDirectoryNewExtraLength(newExtraLength);
55 
56         return add;
57     }
58 
calZeroPaddingLengthForEntryExtra()59     private int calZeroPaddingLengthForEntryExtra() throws ZipException {
60         int entryExtraLen = zipEntryData.getZipEntryHeader().getExtraLength();
61         int cdExtraLen = fileEntryIncentralDirectory.getExtraLength();
62         if (cdExtraLen > entryExtraLen) {
63             setEntryHeaderNewExtraLength(cdExtraLen);
64             return cdExtraLen - entryExtraLen;
65         }
66         if (cdExtraLen < entryExtraLen) {
67             setCenterDirectoryNewExtraLength(entryExtraLen);
68             return entryExtraLen - cdExtraLen;
69         }
70         return 0;
71     }
72 
setCenterDirectoryNewExtraLength(int newLength)73     private void setCenterDirectoryNewExtraLength(int newLength) throws ZipException {
74         byte[] newCDExtra = getAlignmentNewExtra(newLength, fileEntryIncentralDirectory.getExtraData());
75         fileEntryIncentralDirectory.setExtraData(newCDExtra);
76         fileEntryIncentralDirectory.setExtraLength(newLength);
77         fileEntryIncentralDirectory.setLength(CentralDirectory.CD_LENGTH
78                 + fileEntryIncentralDirectory.getFileNameLength()
79                 + fileEntryIncentralDirectory.getExtraLength() + fileEntryIncentralDirectory.getCommentLength());
80     }
81 
setEntryHeaderNewExtraLength(int newLength)82     private void setEntryHeaderNewExtraLength(int newLength) throws ZipException {
83         ZipEntryHeader zipEntryHeader = zipEntryData.getZipEntryHeader();
84         byte[] newExtra = getAlignmentNewExtra(newLength, zipEntryHeader.getExtraData());
85         zipEntryHeader.setExtraData(newExtra);
86         zipEntryHeader.setExtraLength(newLength);
87         zipEntryHeader.setLength(ZipEntryHeader.HEADER_LENGTH + zipEntryHeader.getExtraLength()
88                 + zipEntryHeader.getFileNameLength());
89         zipEntryData.setLength(zipEntryHeader.getLength() + zipEntryData.getFileSize()
90                 + (zipEntryData.getDataDescriptor() == null ? 0 : DataDescriptor.DES_LENGTH));
91     }
92 
getAlignmentNewExtra(int newLength, byte[] old)93     private byte[] getAlignmentNewExtra(int newLength, byte[] old) throws ZipException {
94         if (old == null) {
95             return new byte[newLength];
96         }
97         if (newLength < old.length) {
98             throw new ZipException("can not align " + zipEntryData.getZipEntryHeader().getFileName());
99         }
100         return Arrays.copyOf(old, newLength);
101     }
102 
getZipEntryData()103     public ZipEntryData getZipEntryData() {
104         return zipEntryData;
105     }
106 
setZipEntryData(ZipEntryData zipEntryData)107     public void setZipEntryData(ZipEntryData zipEntryData) {
108         this.zipEntryData = zipEntryData;
109     }
110 
getCentralDirectory()111     public CentralDirectory getCentralDirectory() {
112         return fileEntryIncentralDirectory;
113     }
114 
setCentralDirectory(CentralDirectory centralDirectory)115     public void setCentralDirectory(CentralDirectory centralDirectory) {
116         this.fileEntryIncentralDirectory = centralDirectory;
117     }
118 }