• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 #include "global.h"
17 
18 #include <fcntl.h>
19 #include <limits.h>
20 #include <securec.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include "global_utils.h"
27 
28 /*
29  * locale format as below, use '-' or '_' to link, e.g. en_Latn_US
30  * and needn't have all 3 elements, so max length is 13 including '\0'
31  * |   language  |   script  |        region          |
32  * | ----------- | --------- | ---------------------- |
33  * | 2-3 letters | 4 letters | 2 letters or 3 numbers |
34  */
35 
36 #define MAX_LOCALE_LENGTH 13
37 #define UI_LOCALE_ELEMENT_NUM 2
38 #define MAX_SCRIPT_LENGTH 5
39 static char g_locale[MAX_LOCALE_LENGTH] = {0};
40 
GLOBAL_ConfigLanguage(const char * appLanguage)41 void GLOBAL_ConfigLanguage(const char *appLanguage)
42 {
43     if (appLanguage == NULL) {
44         return;
45     }
46     // appLanguage is same as g_locale, needn't strcpy_s
47     if (strcmp(appLanguage, g_locale) == 0) {
48         return;
49     }
50     if (strcpy_s(g_locale, MAX_LOCALE_LENGTH, appLanguage) != EOK) {
51         return;
52     }
53 }
54 
GLOBAL_GetLanguage(char * language,uint8_t len)55 int32_t GLOBAL_GetLanguage(char *language, uint8_t len)
56 {
57     if (language == NULL || len == 0) {
58         return MC_FAILURE;
59     }
60     char *localeArray[LOCALE_ELEMENT_NUM] = {NULL};
61     char tempLocale[MAX_LOCALE_LENGTH] = {'\0'};
62     int32_t ret = strcpy_s(tempLocale, MAX_LOCALE_LENGTH, g_locale);
63     if (ret != EOK) {
64         return MC_FAILURE;
65     }
66     int32_t count = 0;
67     ret = GetGlobalUtilsImpl()->SplitLocale(tempLocale, localeArray, &count);
68     if (ret == MC_FAILURE || count != UI_LOCALE_ELEMENT_NUM) {
69         return MC_FAILURE;
70     }
71 
72     // language must be the element 0;
73     return (strncpy_s(language, len, localeArray[0], MAX_LANGUAGE_LENGTH - 1) != EOK) ? MC_FAILURE : MC_SUCCESS;
74 }
75 
GLOBAL_IsRTL(void)76 int32_t GLOBAL_IsRTL(void)
77 {
78     char *localeArray[LOCALE_ELEMENT_NUM] = { NULL };
79     char tempLocale[MAX_LOCALE_LENGTH] = { '\0' };
80     int32_t ret = strcpy_s(tempLocale, MAX_LOCALE_LENGTH, g_locale);
81     if (ret != EOK) {
82         return 0;
83     }
84     int32_t count = 0;
85     ret = GetGlobalUtilsImpl()->SplitLocale(tempLocale, localeArray, &count);
86     if (ret == MC_FAILURE || count != UI_LOCALE_ELEMENT_NUM) {
87         return 0;
88     }
89     char script[MAX_SCRIPT_LENGTH] = { 0 };
90     if (strncpy_s(script, MAX_SCRIPT_LENGTH, localeArray[1], MAX_SCRIPT_LENGTH - 1) != EOK) {
91         return 0;
92     }
93     // if script is set and script != arab or script != hebr, return false;
94     if ((strlen(script) == MAX_SCRIPT_LENGTH - 1) &&
95         (strcmp(script, "Arab") != 0) && (strcmp(script, "Hebr") != 0)) {
96         return 0;
97     }
98     char language[MAX_LANGUAGE_LENGTH] = { 0 };
99     if (strncpy_s(language, MAX_LANGUAGE_LENGTH, localeArray[0], MAX_LANGUAGE_LENGTH - 1) != EOK) {
100         return 0;
101     }
102     if ((strcmp(language, "fa") == 0) || (strcmp(language, "ar") == 0) || (strcmp(language, "ur") == 0) ||
103         (strcmp(language, "ug") == 0) || (strcmp(language, "he") == 0) || (strcmp(language, "iw") == 0)) {
104         return 1;
105     }
106     return 0;
107 }
108 
GLOBAL_GetRegion(char * region,uint8_t len)109 int32_t GLOBAL_GetRegion(char *region, uint8_t len)
110 {
111     if (region == NULL || len == 0) {
112         return MC_FAILURE;
113     }
114     char *localeArray[LOCALE_ELEMENT_NUM] = {NULL};
115     char tempLocale[MAX_LOCALE_LENGTH] = {'\0'};
116     int32_t ret = strcpy_s(tempLocale, MAX_LOCALE_LENGTH, g_locale);
117     if (ret != EOK) {
118         return MC_FAILURE;
119     }
120     int32_t count = 0;
121     ret = GetGlobalUtilsImpl()->SplitLocale(tempLocale, localeArray, &count);
122     if (ret == MC_FAILURE || count != UI_LOCALE_ELEMENT_NUM) {
123         return MC_FAILURE;
124     }
125 
126     // region must be the element 1
127     return (strncpy_s(region, len, localeArray[1], MAX_REGION_LENGTH - 1) != EOK) ? MC_FAILURE : MC_SUCCESS;
128 }
129 
FreeIdItem(IdItem * idItem)130 static void FreeIdItem(IdItem *idItem)
131 {
132     if (idItem == NULL) {
133         return;
134     }
135     free(idItem->value);
136     free(idItem->name);
137     idItem->value = NULL;
138     idItem->name = NULL;
139 }
140 
FreeValue(char ** value)141 static void FreeValue(char **value)
142 {
143     if (*value != NULL) {
144         free(*value);
145         *value = NULL;
146     }
147 }
148 
GLOBAL_GetValueByIdInternal(uint32_t id,const char * path,const char * locale,char ** value)149 static int32_t GLOBAL_GetValueByIdInternal(uint32_t id, const char *path, const char *locale, char **value)
150 {
151     char realResourcePath[PATH_MAX] = {'\0'};
152     GlobalUtilsImpl *utilsImpl = GetGlobalUtilsImpl();
153     if (utilsImpl->CheckFilePath(path, realResourcePath, PATH_MAX) == MC_FAILURE) {
154         return MC_FAILURE;
155     }
156 
157     uint32_t idHeaderOffset = utilsImpl->GetOffsetByLocale(realResourcePath, locale, MAX_LOCALE_LENGTH);
158     IdHeader idHeader = {0, NULL};
159     int32_t file = open(realResourcePath, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
160     if (file < 0) {
161         return MC_FAILURE;
162     }
163     int32_t ret = utilsImpl->GetIdHeaderByOffset(file, idHeaderOffset, &idHeader);
164     if (ret != MC_SUCCESS) {
165         close(file);
166         return ret;
167     }
168 
169     int32_t result = MC_FAILURE;
170     IdItem idItem = {0, INVALID_RES_TYPE, 0, 0, NULL, 0, NULL};
171     for (uint32_t i = 0; i < idHeader.count; i++) {
172         if (idHeader.idParams[i].id == id) {
173             ret = utilsImpl->GetIdItem(file, idHeader.idParams[i].offset, &idItem);
174             if (ret != MC_SUCCESS) {
175                 close(file);
176                 free(idHeader.idParams);
177                 return ret;
178             }
179             *value = (char *)malloc(idItem.valueLen);
180             if (*value == NULL || strcpy_s(*value, idItem.valueLen, idItem.value) != EOK) {
181                 close(file);
182                 free(idHeader.idParams);
183                 FreeIdItem(&idItem);
184                 FreeValue(value);
185                 return MC_FAILURE;
186             }
187             result = MC_SUCCESS;
188             break;
189         }
190     }
191     close(file);
192     free(idHeader.idParams);
193     FreeIdItem(&idItem);
194     return result;
195 }
196 
GLOBAL_GetValueById(uint32_t id,const char * path,char ** value)197 int32_t GLOBAL_GetValueById(uint32_t id, const char *path, char **value)
198 {
199     if (path == NULL || path[0] == '\0' || value == NULL) {
200         return MC_FAILURE;
201     }
202 
203     char tempLocale[MAX_LOCALE_LENGTH] = {'\0'};
204     int32_t ret = strcpy_s(tempLocale, MAX_LOCALE_LENGTH, g_locale);
205     if (ret != EOK) {
206         return MC_FAILURE;
207     }
208 
209     char *locales[] = {tempLocale, ""};
210     for (int i = 0; i < 2; i++) { // 2 current language and the default.
211         if (GLOBAL_GetValueByIdInternal(id, path, locales[i], value) == MC_SUCCESS) {
212             return MC_SUCCESS;
213         }
214     }
215     return MC_FAILURE;
216 }
217 
GLOBAL_GetValueByNameInternal(const char * name,const char * path,const char * locale,char ** value)218 static int32_t GLOBAL_GetValueByNameInternal(const char *name, const char *path, const char *locale, char **value)
219 {
220     char realResourcePath[PATH_MAX] = {'\0'};
221     GlobalUtilsImpl *utilsImpl = GetGlobalUtilsImpl();
222     if (utilsImpl->CheckFilePath(path, realResourcePath, PATH_MAX) == MC_FAILURE) {
223         return MC_FAILURE;
224     }
225     uint32_t idHeaderOffset = utilsImpl->GetOffsetByLocale(realResourcePath, locale, MAX_LOCALE_LENGTH);
226     IdHeader idHeader = {0, NULL};
227     int32_t file = open(realResourcePath, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
228     if (file < 0) {
229         return MC_FAILURE;
230     }
231     int32_t ret = utilsImpl->GetIdHeaderByOffset(file, idHeaderOffset, &idHeader);
232     if (ret != MC_SUCCESS) {
233         close(file);
234         return ret;
235     }
236 
237     int32_t result = MC_FAILURE;
238     IdItem idItem = {0, INVALID_RES_TYPE, 0, 0, NULL, 0, NULL};
239     for (uint32_t i = 0; i < idHeader.count; i++) {
240         ret = utilsImpl->GetIdItem(file, idHeader.idParams[i].offset, &idItem);
241         if (ret != MC_SUCCESS) {
242             close(file);
243             free(idHeader.idParams);
244             return ret;
245         }
246         if (strcmp(name, idItem.name) != 0) {
247             FreeIdItem(&idItem);
248             continue;
249         }
250         *value = (char *)malloc(idItem.valueLen);
251         if (*value == NULL || strcpy_s(*value, idItem.valueLen, idItem.value) != EOK) {
252             close(file);
253             free(idHeader.idParams);
254             FreeIdItem(&idItem);
255             FreeValue(value);
256             return MC_FAILURE;
257         }
258         result = MC_SUCCESS;
259         break;
260     }
261 
262     close(file);
263     free(idHeader.idParams);
264     FreeIdItem(&idItem);
265     return result;
266 }
267 
GLOBAL_GetValueByName(const char * name,const char * path,char ** value)268 int32_t GLOBAL_GetValueByName(const char *name, const char *path, char **value)
269 {
270     if (name == NULL || strlen(name) == 0 || path == NULL || strlen(path) == 0 || value == NULL) {
271         return MC_FAILURE;
272     }
273 
274     char tempLocale[MAX_LOCALE_LENGTH] = {'\0'};
275     int32_t ret = strcpy_s(tempLocale, MAX_LOCALE_LENGTH, g_locale);
276     if (ret != EOK) {
277         return MC_FAILURE;
278     }
279 
280     char *locales[] = {tempLocale, ""};
281     for (int i = 0; i < 2; i++) { // 2 current language and the default.
282         if (GLOBAL_GetValueByNameInternal(name, path, locales[i], value) == MC_SUCCESS) {
283             return MC_SUCCESS;
284         }
285     }
286     return MC_FAILURE;
287 }
288