• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 ohos;
17 
18 import com.alibaba.fastjson.JSONObject;
19 
20 import java.io.IOException;
21 import java.io.RandomAccessFile;
22 import java.util.Optional;
23 
24 /**
25  * bin file to hap tool main class.
26  *
27  */
28 public class CollectBinInfo {
29     private static final String JSON_FILE_NAME = "config.json";
30     private static final String PROFILE_KEY = "app";
31     private static final String VERSION_KEY = "version";
32     private static final String CODE_KEY = "code";
33     private static final String BIN_PATH = "--bin-path";
34     private static final String VERSION_CODE = "--version-code";
35     private static final int PARA_COUNT = 3;
36     private static final int MAGIC_NUMBER = 190;
37     private static final int INT_LENGTH = 4;
38     private static final int LONG_LENGTH = 8;
39     private static int bundleNameLen = 0;
40 
41     /**
42      * get versionCode from bin file
43      *
44      * @param binPath: bin path
45      * @return versionCode
46      */
getVersionCode(final String binPath)47     public static String getVersionCode(final String binPath) {
48         String versionCode = "";
49         if (!FileUtils.checkFileIsExists(binPath)) {
50             return versionCode;
51         }
52 
53         Optional<String> absBinPath = FileUtils.getFormatedPath(binPath);
54         RandomAccessFile binStream = null;
55         try {
56             binStream = new RandomAccessFile(absBinPath.get(), "r");
57             if (!readBinFileHeader(binStream)) {
58                 return versionCode;
59             }
60             long fileDataPos = 1 + INT_LENGTH + bundleNameLen;
61             byte [] fileDataByte = readBinFileData(JSON_FILE_NAME, binStream, fileDataPos);
62             if (fileDataByte == null) {
63                 return versionCode;
64             }
65             String fileData = new String(fileDataByte, "UTF-8");
66             JSONObject object = JSONObject.parseObject(fileData);
67             if (object == null || !object.containsKey(PROFILE_KEY)) {
68                 return versionCode;
69             }
70             object = object.getJSONObject(PROFILE_KEY);
71             if (object == null || !object.containsKey(VERSION_KEY)) {
72                 return versionCode;
73             }
74             object = object.getJSONObject(VERSION_KEY);
75             if (object != null) {
76                 versionCode = object.getInteger(CODE_KEY).toString();
77             }
78             return versionCode;
79         } catch (IOException msg) {
80             return versionCode;
81         } finally {
82             if (binStream != null) {
83                 FileUtils.closeStream(binStream);
84             }
85         }
86     }
87 
88     /**
89      * read bin file header
90      *
91      * @param binStream: bin randAccessFileStream
92      * @return true or false
93      */
readBinFileHeader(RandomAccessFile binStream)94     private static boolean readBinFileHeader(RandomAccessFile binStream) {
95         try {
96             byte magic = binStream.readByte();
97             if ((magic & 0xff) != MAGIC_NUMBER) {
98                 return false;
99             }
100             bundleNameLen = binStream.readInt();
101             if (bundleNameLen >= 0) {
102                 byte [] bundleNameByte = new byte[bundleNameLen];
103                 binStream.readFully(bundleNameByte, 0, bundleNameLen);
104                 return true;
105             }
106             return false;
107         } catch (IOException msg) {
108             return false;
109         }
110     }
111 
112     /**
113      * read bin file data
114      *
115      * @param fileName: file name
116      * @param binStream: bin randAccessFileStream
117      * @param fileDataPos: position which begin to read file data
118      * @return fileData byte
119      */
readBinFileData(final String fileName, RandomAccessFile binStream, long fileDataPos)120     private static byte [] readBinFileData(final String fileName, RandomAccessFile binStream, long fileDataPos) {
121         try {
122             long fileSize = binStream.length();
123             long pos = fileDataPos;
124             while (pos < fileSize) {
125                 int nameLen = binStream.readInt();
126                 if (nameLen <= 0) {
127                     return null;
128                 }
129                 byte [] fileNameByte = new byte[nameLen];
130                 binStream.readFully(fileNameByte, 0, nameLen);
131                 int relativePathLen = binStream.readInt();
132                 if (relativePathLen < 0) {
133                     return null;
134                 }
135                 binStream.seek(pos + INT_LENGTH + nameLen + INT_LENGTH + relativePathLen);
136                 long dataLen = binStream.readLong();
137                 if (dataLen > Integer.MAX_VALUE || dataLen <= 0) {
138                     return null;
139                 }
140                 byte [] fileData = new byte[(int) dataLen];
141                 binStream.readFully(fileData, 0, (int) dataLen);
142                 pos = pos + INT_LENGTH + nameLen + INT_LENGTH + relativePathLen + LONG_LENGTH + dataLen;
143                 String name = new String(fileNameByte, "UTF-8");
144                 if (name.equals(fileName)) {
145                     return fileData;
146                 }
147             }
148             return null;
149         } catch (IOException msg) {
150             return null;
151         }
152     }
153 
154     /**
155      * tool main function.
156      *
157      * @param args command line
158      */
main(String[] args)159     public static void main(String[] args) {
160         if (args.length != PARA_COUNT) {
161             return;
162         }
163         String binPath = "";
164         int count = 0;
165         boolean versionFlag = false;
166         for (String para : args) {
167             if (BIN_PATH.equals(para) && count < args.length - 1) {
168                 binPath = args[count + 1];
169             }
170             if (VERSION_CODE.equals(para) && count < args.length) {
171                 versionFlag = true;
172             }
173             count++;
174         }
175         if (!binPath.isEmpty() && versionFlag) {
176             String versionCode = getVersionCode(binPath);
177         }
178     }
179 }