• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "utils/psue_manager.h"
17 
18 #include <algorithm>
19 #include <cctype>
20 #include <cstdlib>
21 #include <iostream>
22 #include <string>
23 #include <unzip.h>
24 #include <vector>
25 #include "hilog_wrapper.h"
26 #include "map"
27 #include "utils/errors.h"
28 #ifdef __WINNT__
29 #include <windows.h>
30 #undef ERROR
31 #endif
32 
33 namespace OHOS {
34 namespace Global {
35 namespace Resource {
36 using namespace std;
37 
38 namespace {
39 const float DEFAULT_EXTEND_RATIO = 0.3f;
40 
41 struct ExtendRatioTable {
42     int32_t count;
43     float ratio;
44 };
45 
46 const ExtendRatioTable EXTEND_RATIO_RABLE[] = {
47     {10, 2.0f},
48     {20, 1.0f},
49     {30, 0.8f},
50     {50, 0.6f},
51     {70, 0.4f},
52 };
53 const std::wstring PSUE_CONFIG_CHARS = {L"ReÇÉÄßÑ¿ÃóèìжДﺥ"};
54 
55 const map<wchar_t, wchar_t> REPLACE_TABLE {
56     {L'a', L'à'},
57     {L'A', L'À'},
58     {L'c', L'ć'},
59     {L'C', L'Ć'},
60     {L'i', L'ì'},
61     {L'I', L'Ì'},
62     {L'o', L'ó'},
63     {L'O', L'Ó'},
64     {L'u', L'ü'},
65     {L'U', L'Ü'},
66     {L'y', L'ÿ'},
67     {L'Y', L'Ÿ'},
68     {L'z', L'ž'},
69     {L'Z', L'Ž'},
70 };
71 }
72 
PsueManager()73 PsueManager::PsueManager()
74 {
75 }
76 
~PsueManager()77 PsueManager::~PsueManager()
78 {
79 }
80 
81 /**
82   PsuedoTranslation level default value is 3
83   1. Enclosed in brackets
84   2. Letter replacement
85   3. Lengthen string
86 */
87 int g_fakeLocaleLevel = 3;
88 
89 int g_levelForReplace = 2;
90 int g_levelForAppend = 3;
91 int g_levelForAddBracket = 1;
92 
Convert(const std::string & src,std::string & dest)93 std::string PsueManager::Convert(const std::string &src, std::string &dest)
94 {
95     if (isDigit(src)) {
96         return "";
97     }
98     std::wstring ws;
99     std::string wsStr = ToWstring(ws, src);
100     if (wsStr != "") {
101         return wsStr;
102     }
103     if (g_fakeLocaleLevel >= g_levelForReplace) {
104         // char replace
105         ToAccent(ws);
106     }
107     if (g_fakeLocaleLevel == g_levelForAppend) {
108         // enhance length
109         unsigned int len = src.length();
110         unsigned int extendCount = len * GetExtendRatio(len);
111         unsigned int loop = extendCount / PSUE_CONFIG_CHARS.length();
112         unsigned int left = extendCount % PSUE_CONFIG_CHARS.length();
113         for (unsigned int i = 0; i < loop ; i++) {
114             ws += PSUE_CONFIG_CHARS;
115         }
116         if (left > 0) {
117             ws += PSUE_CONFIG_CHARS.substr(0, left);
118         }
119     }
120     std::string tsStr = ToString(dest, ws);
121     if (tsStr != "") {
122         return tsStr;
123     }
124     if (g_fakeLocaleLevel >= g_levelForAddBracket) {
125         // add brackets
126         dest = '[' + dest + ']';
127     }
128     return "";
129 }
130 
isDigit(const std::string src)131 bool PsueManager::isDigit(const std::string src)
132 {
133     for (unsigned int i = 0 ; i < src.size() ; i++) {
134         if (!isdigit(src[i])) {
135             return false;
136         }
137     }
138     return true;
139 }
140 
GetExtendRatio(int32_t len) const141 float PsueManager::GetExtendRatio(int32_t len) const
142 {
143     for (size_t i = 0; i < sizeof(EXTEND_RATIO_RABLE) / sizeof(EXTEND_RATIO_RABLE[0]) ; i++) {
144         if (len <= EXTEND_RATIO_RABLE[i].count) {
145             return EXTEND_RATIO_RABLE[i].ratio;
146         }
147     }
148     return DEFAULT_EXTEND_RATIO;
149 }
150 
151 // letter replace
ToAccent(wstring & ws) const152 void PsueManager::ToAccent(wstring &ws) const
153 {
154     for (std::wstring::size_type i = 0 ; i < ws.length(); i++) {
155         if (ws[i] == L'%') {
156             i++;
157         } else if (ws[i] == L'{') {
158             while ((i + 1 < ws.length()) && (ws[++i] != L'}')) {}
159         } else {
160             auto iter = REPLACE_TABLE.find(ws[i]);
161             if (iter != REPLACE_TABLE.end()) {
162                 ws[i] = iter->second;
163             }
164         }
165     }
166 }
167 
ToWstring(std::wstring & dest,const std::string & src)168 std::string PsueManager::ToWstring(std::wstring &dest, const std::string &src)
169 {
170     char* result = setlocale(LC_CTYPE, "");
171     if (result == nullptr) {
172         return "set locale fail";
173     }
174     size_t destSize = mbstowcs(NULL, src.c_str(), 0);
175     if (destSize == size_t(-1)) {
176         return "get widechar size fail";
177     }
178     vector<wchar_t> buf(destSize + 1);
179     if (mbstowcs(&buf[0], src.c_str(), src.size()) == static_cast<size_t>(-1)) {
180         return "convert to widechar fail";
181     }
182 
183     dest.assign(buf.begin(), buf.end() - 1);
184     return "";
185 }
186 
ToString(std::string & dest,const std::wstring & src)187 std::string PsueManager::ToString(std::string &dest, const std::wstring &src)
188 {
189     size_t destSize = wcstombs(NULL, src.c_str(), 0);
190     if (destSize == size_t(-1)) {
191         return "get multibyte size fail";
192     }
193     vector<char> buf(destSize + 1);
194     if (wcstombs(&buf[0], src.c_str(), buf.size()) == static_cast<size_t>(-1)) {
195         return "convert to multibyte fail";
196     }
197 
198     dest.assign(buf.begin(), buf.end() - 1);
199     return "";
200 }
201 
SetFakeLocaleLevel(const int level)202 void PsueManager::SetFakeLocaleLevel(const int level)
203 {
204     if (level <= g_levelForAppend && level >= g_levelForAddBracket) {
205         g_fakeLocaleLevel = level;
206     }
207 }
208 
IsAsciiString(const std::string & src)209 bool PsueManager::IsAsciiString(const std::string &src)
210 {
211     bool isAscii = true;
212     for (size_t i = 0; i < src.length(); i++) {
213         if (src[i] < 0 || src[i] > 127) {  // 127 is the max value of ascii
214             isAscii = false;
215             break;
216         }
217     }
218     return isAscii;
219 }
220 
BidirectionConvert(std::string & src)221 std::string PsueManager::BidirectionConvert(std::string &src)
222 {
223     if (!IsAsciiString(src)) {
224         return src;
225     }
226     std::string result;
227     size_t start = 0;
228     size_t end = 0;
229     while (start < src.length()) {
230         while (start < src.length() && isspace(src[start])) {
231             start++;
232         }
233         if (start > end) {
234             result += src.substr(end, start - end);
235         }
236         end = start;
237         while (end < src.length() && !isspace(src[end])) {
238             end++;
239         }
240         if (start < src.length()) {
241             result += directionHead;
242             result += src.substr(start, end - start);
243             result += directionTail;
244         }
245         start = end;
246     }
247     return result;
248 }
249 } // namespace Resource
250 } // namespace Global
251 } // namespace OHOS