• 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 java.io.IOException;
19 import java.io.InputStream;
20 import java.nio.ByteBuffer;
21 import java.nio.ByteOrder;
22 import java.nio.charset.StandardCharsets;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Optional;
26 
27 /**
28  * Resources Parser.
29  *
30  */
31 public class ResourcesParser {
32     /**
33      * Parses resources default id.
34      */
35     public static final int RESOURCE_DEFAULT_ID = -1;
36 
37     private static final int VERSION_BYTE_LENGTH = 128;
38     private static final int TAG_BYTE_LENGTH = 4;
39     private static final Log LOG = new Log(ResourcesParser.class.toString());
40 
41     /**
42      * Key Param.
43      */
44     static class KeyParam {
45         int keyType;
46         int value;
47     }
48 
49     /**
50      * Config Index.
51      */
52     static class ConfigIndex {
53         String tag;
54         int offset;
55         int keyCount;
56         KeyParam[] params;
57     }
58 
59     /**
60      * Data Item.
61      */
62     static class DataItem {
63         int size;
64         int type;
65         int id;
66         String value;
67         String name;
68     }
69 
70     /**
71      * Get resource value by resource id.
72      *
73      * @param resourceId resource id
74      * @param data resource index data
75      * @return the resourceId value
76      * @throws BundleException IOException.
77      */
getResourceById(int resourceId, byte[] data)78     static String getResourceById(int resourceId, byte[] data) throws BundleException {
79         String resourceIdValue = "";
80         if (data == null || data.length <= 0 || resourceId == RESOURCE_DEFAULT_ID) {
81             LOG.error("ResourcesParser::getIconPath data byte or ResourceId is null");
82             return resourceIdValue;
83         }
84 
85         List<String> result = getResource(resourceId, data);
86         if (result != null && result.size() > 0 && result.get(0) != null && !"".equals(result.get(0))) {
87             resourceIdValue = result.get(0).substring(0, result.get(0).length() - 1);
88         }
89         return resourceIdValue;
90     }
91 
92     /**
93      * Get base resource value by resource id.
94      *
95      * @param resourceId resource id
96      * @param data resource index data
97      * @return the resource value
98      * @throws BundleException IOException.
99      */
getBaseResourceById(int resourceId, byte[] data)100     static String getBaseResourceById(int resourceId, byte[] data) throws BundleException {
101         String resourceIdValue = "";
102         if (data == null || data.length <= 0 || resourceId == RESOURCE_DEFAULT_ID) {
103             LOG.error("ResourcesParser::getBaseResourceById data byte or ResourceId is null");
104             return resourceIdValue;
105         }
106         resourceIdValue = getBaseResource(resourceId, data);
107         if (resourceIdValue != null && !"".equals(resourceIdValue)) {
108             resourceIdValue = resourceIdValue.substring(0, resourceIdValue.length() - 1);
109         }
110         return resourceIdValue;
111     }
112 
113     /**
114      * Get base resource.
115      *
116      * @param resId resource id
117      * @param data resource index data array
118      * @return the resource value
119      * @throws BundleException IOException.
120      */
getBaseResource(int resId, byte[] data)121     static String getBaseResource(int resId, byte[] data) {
122         ByteBuffer byteBuf = ByteBuffer.wrap(data);
123         byteBuf.order(ByteOrder.LITTLE_ENDIAN);
124         byte[] version = new byte[VERSION_BYTE_LENGTH];
125         byteBuf.get(version);
126         byteBuf.getInt();
127         int configCount = byteBuf.getInt();
128         Optional<ConfigIndex> optionalConfigIndex = loadBaseConfig(byteBuf, configCount);
129         if (!optionalConfigIndex.isPresent()) {
130             LOG.error("ResourcesParser::getBaseResource configIndex is null");
131             return "";
132         }
133         return readBaseItem(resId, optionalConfigIndex.get(), byteBuf);
134     }
135 
136     /**
137      * Load index config.
138      *
139      * @param bufBuf config byte buffer
140      * @param count config count
141      * @return the base config index
142      * @throws BundleException IOException.
143      */
loadBaseConfig(ByteBuffer bufBuf, int count)144     static  Optional<ConfigIndex> loadBaseConfig(ByteBuffer bufBuf, int count) {
145         for (int i = 0; i < count; i++) {
146             ConfigIndex cfg = new ConfigIndex();
147             byte[] tag = new byte[TAG_BYTE_LENGTH];
148             bufBuf.get(tag);
149             cfg.tag = new String(tag, StandardCharsets.UTF_8);
150             cfg.offset = bufBuf.getInt();
151             cfg.keyCount = bufBuf.getInt();
152             cfg.params = new KeyParam[cfg.keyCount];
153             for (int j = 0; j < cfg.keyCount; j++) {
154                 cfg.params[j] = new KeyParam();
155                 cfg.params[j].keyType = bufBuf.getInt();
156                 cfg.params[j].value = bufBuf.getInt();
157             }
158             if (cfg.keyCount == 0) {
159                 return Optional.of(cfg);
160             }
161         }
162         return Optional.empty();
163     }
164 
165     /**
166      * Read base config item.
167      *
168      * @param resId resource id
169      * @param configIndex the config index
170      * @param buf config byte buffer
171      * @return the base item
172      * @throws BundleException IOException.
173      */
readBaseItem(int resId, ConfigIndex configIndex, ByteBuffer buf)174     static String readBaseItem(int resId, ConfigIndex configIndex, ByteBuffer buf) {
175         buf.rewind();
176         buf.position(configIndex.offset);
177         byte[] tag = new byte[TAG_BYTE_LENGTH];
178         buf.get(tag);
179         int count = buf.getInt();
180         for (int i = 0; i < count; i++) {
181             int id = buf.getInt();
182             int offset = buf.getInt();
183             if (id == resId) {
184                 buf.rewind();
185                 buf.position(offset);
186                 DataItem item = readItem(buf);
187                 return item.value;
188             }
189         }
190         return "";
191     }
192 
193     /**
194      * Get Icon resource.
195      *
196      * @param resId resource id
197      * @param data resource index data array
198      * @return the result
199      * @throws BundleException IOException.
200      */
getResource(int resId, byte[] data)201     static List<String> getResource(int resId, byte[] data) {
202         ByteBuffer byteBuf = ByteBuffer.wrap(data);
203         byteBuf.order(ByteOrder.LITTLE_ENDIAN);
204         byte[] version = new byte[VERSION_BYTE_LENGTH];
205         byteBuf.get(version);
206         byteBuf.getInt();
207         int configCount = byteBuf.getInt();
208         List<ConfigIndex> cfg = loadConfig(byteBuf, configCount);
209         return readAllItem(resId, cfg, byteBuf);
210     }
211 
212     /**
213      * Load index config.
214      *
215      * @param bufBuf config byte buffer
216      * @param count config count
217      * @return the config list
218      * @throws BundleException IOException.
219      */
loadConfig(ByteBuffer bufBuf, int count)220     static List<ConfigIndex> loadConfig(ByteBuffer bufBuf, int count) {
221         List<ConfigIndex> configList = new ArrayList<>(count);
222         for (int i = 0; i < count; i++) {
223             ConfigIndex cfg = new ConfigIndex();
224             byte[] tag = new byte[TAG_BYTE_LENGTH];
225             bufBuf.get(tag);
226             cfg.tag = new String(tag, StandardCharsets.UTF_8);
227             cfg.offset = bufBuf.getInt();
228             cfg.keyCount = bufBuf.getInt();
229             cfg.params = new KeyParam[cfg.keyCount];
230             for (int j = 0; j < cfg.keyCount; j++) {
231                 cfg.params[j] = new KeyParam();
232                 cfg.params[j].keyType = bufBuf.getInt();
233                 cfg.params[j].value = bufBuf.getInt();
234             }
235 
236             configList.add(cfg);
237         }
238         return configList;
239     }
240 
241     /**
242      * Read all config item.
243      *
244      * @param resId resource id
245      * @param configs the config list
246      * @param buf config byte buffer
247      * @return the item list
248      * @throws BundleException IOException.
249      */
readAllItem(int resId, List<ConfigIndex> configs, ByteBuffer buf)250     static List<String> readAllItem(int resId, List<ConfigIndex> configs, ByteBuffer buf) {
251         List<String> result = new ArrayList<>();
252         for (ConfigIndex index : configs) {
253             buf.rewind();
254             buf.position(index.offset);
255             byte[] tag = new byte[TAG_BYTE_LENGTH];
256             buf.get(tag);
257             int count = buf.getInt();
258             for (int i = 0; i < count; i++) {
259                 int id = buf.getInt();
260                 int offset = buf.getInt();
261                 if (id == resId) {
262                     buf.rewind();
263                     buf.position(offset);
264                     DataItem item = readItem(buf);
265                     result.add(item.value);
266                     break;
267                 }
268             }
269         }
270         return result;
271     }
272 
273     /**
274      * Read the config item.
275      *
276      * @param buf config byte buffer
277      * @return the item info
278      * @throws BundleException IOException.
279      */
readItem(ByteBuffer buf)280     static DataItem readItem(ByteBuffer buf) {
281         DataItem item = new DataItem();
282         item.size = buf.getInt();
283         item.type = buf.getInt();
284         item.id = buf.getInt();
285         int len = buf.getShort();
286         byte[] value = new byte[len];
287         buf.get(value);
288         item.value = new String(value, StandardCharsets.UTF_8);
289         len = buf.getShort();
290         byte[] name = new byte[len];
291         buf.get(name);
292         item.name = new String(name, StandardCharsets.UTF_8);
293         return item;
294     }
295 }
296 
297