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