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