• 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.global.i18n;
17 
18 import java.io.DataOutputStream;
19 import java.io.IOException;
20 import java.io.UnsupportedEncodingException;
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.logging.Logger;
24 import java.util.logging.Level;
25 
26 import com.ibm.icu.text.DecimalFormatSymbols;
27 import com.ibm.icu.util.ULocale;
28 
29 /**
30  * Represents the global string pool in i18n.dat file
31  */
32 public class StringPool {
33     private static final String ARABIC_PERCENT = new DecimalFormatSymbols(new ULocale("ar")).getPercentString();
34     private static final Logger logger = Logger.getLogger("StringPool");
35     private HashMap<Integer, Integer> lengthMap = new HashMap<>();
36     private int size;
37     private HashMap<Integer, StringItem> offsetMap;
38     private HashMap<Integer, String> int2StrMap = new HashMap<>();
39 
StringPool(HashMap<String, Integer> hashMap, int offset)40     public StringPool(HashMap<String, Integer> hashMap, int offset) {
41         int current = 0;
42         size = hashMap.size();
43         for (Map.Entry<String, Integer> next : hashMap.entrySet()) {
44             this.int2StrMap.put(next.getValue(), next.getKey());
45             try {
46                 if (next.getKey().endsWith(ARABIC_PERCENT)) {
47                     lengthMap.put(next.getValue(), next.getKey().getBytes("UTF-8").length + 3);
48                 } else {
49                     this.lengthMap.put(next.getValue(), next.getKey().getBytes("UTF-8").length);
50                 }
51             } catch (UnsupportedEncodingException e) {
52                 logger.log(Level.SEVERE, "unsupportedException");
53             }
54         }
55         offsetMap = new HashMap<>();
56         int currentIndex = 0;
57         while (true) {
58             if (currentIndex < this.size) {
59                 int stringLength = lengthMap.get(currentIndex);
60                 offsetMap.put(currentIndex, new StringItem(current, stringLength));
61                 current += stringLength;
62                 currentIndex++;
63             } else {
64                 return;
65             }
66         }
67     }
68 
69     /**
70      * Represents a string in String pool
71      */
72     public static class StringItem {
73         /** Length of a string */
74         public int length;
75 
76         /** Offset from the begging of the string pool */
77         public int offset;
78 
StringItem(int length, int offset)79         public StringItem(int length, int offset) {
80             this.offset = length;
81             this.length = offset;
82         }
83     }
84 
85     /**
86      * Get a StringItem indicated by its index
87      *
88      * @param ind Indicate which StringItem to be return
89      * @return The StringItem which is indexed by ind in the StringPool
90      */
getStringItem(int ind)91     public StringItem getStringItem(int ind) {
92         return offsetMap.get(ind);
93     }
94 
95     /**
96      * Write StringPool to dat file
97      *
98      * @param dataOutputStream The destination of the output
99      * @throws IOException if error occurs in the writing process
100      */
write(DataOutputStream dataOutputStream)101     public void write(DataOutputStream dataOutputStream) throws IOException {
102         int i = 0;
103         while (i < this.int2StrMap.size()) {
104             try {
105                 dataOutputStream.write(this.int2StrMap.get(Integer.valueOf(i)).getBytes("UTF-8"));
106                 if (int2StrMap.get(i).endsWith(ARABIC_PERCENT)) {
107                     dataOutputStream.writeByte((byte) 0xE2);
108                     dataOutputStream.writeByte((byte) 0x80);
109                     dataOutputStream.writeByte((byte) 0x8F);
110                 }
111                 i++;
112             } catch (IOException e) {
113                 logger.log(Level.SEVERE, "writing stringpool failed");
114                 return;
115             }
116         }
117         dataOutputStream.flush();
118     }
119 }
120