• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "locale_info_addon.h"
17 
18 #include "i18n_hilog.h"
19 #include "variable_converter.h"
20 
21 using namespace OHOS;
22 using namespace Global;
23 using namespace I18n;
24 
UnwrapAddon(ani_env * env,ani_object object,const std::string & name)25 LocaleInfoAddon* LocaleInfoAddon::UnwrapAddon(ani_env *env, ani_object object, const std::string &name)
26 {
27     ani_long ptr;
28     if (ANI_OK != env->Object_GetFieldByName_Long(object, name.c_str(), &ptr)) {
29         HILOG_ERROR_I18N("Get Long '%{public}s' failed", name.c_str());
30         return nullptr;
31     }
32     return reinterpret_cast<LocaleInfoAddon*>(ptr);
33 }
34 
35 template<typename T>
GetLocaleProperty(ani_env * env,ani_object object,const std::string & propertyName,T (LocaleInfo::* getter)()const)36 T LocaleInfoAddon::GetLocaleProperty(ani_env *env, ani_object object,
37     const std::string &propertyName, T (LocaleInfo::*getter)() const)
38 {
39     LocaleInfoAddon* obj = UnwrapAddon(env, object, "nativeLocale");
40     if (obj == nullptr || obj->locale_ == nullptr) {
41         HILOG_ERROR_I18N("%{public}s: Get Locale object failed", propertyName.c_str());
42         return T{};
43     }
44     return (obj->locale_.get()->*getter)();
45 }
46 
Locale_ToString(ani_env * env,ani_object object)47 ani_string LocaleInfoAddon::Locale_ToString(ani_env *env, ani_object object)
48 {
49     std::string value = GetLocaleProperty(env, object, "toString", &LocaleInfo::ToString);
50     return VariableConverter::StringToAniStr(env, value);
51 }
52 
Locale_Maximize(ani_env * env,ani_object object)53 ani_object LocaleInfoAddon::Locale_Maximize(ani_env *env, ani_object object)
54 {
55     LocaleInfoAddon* obj = UnwrapAddon(env, object, "nativeLocale");
56     if (obj == nullptr || obj->locale_ == nullptr) {
57         HILOG_ERROR_I18N("Maximize: Get Locale object failed");
58         return nullptr;
59     }
60 
61     std::string localeTag = obj->locale_->Maximize();
62     return Locale_CreateWithParam(env, nullptr, VariableConverter::StringToAniStr(env, localeTag), nullptr);
63 }
64 
Locale_Minimize(ani_env * env,ani_object object)65 ani_object LocaleInfoAddon::Locale_Minimize(ani_env *env, ani_object object)
66 {
67     LocaleInfoAddon* obj = UnwrapAddon(env, object, "nativeLocale");
68     if (obj == nullptr || obj->locale_ == nullptr) {
69         HILOG_ERROR_I18N("Minimize: Get Locale object failed");
70         return nullptr;
71     }
72 
73     std::string localeTag = obj->locale_->Minimize();
74     return Locale_CreateWithParam(env, nullptr, VariableConverter::StringToAniStr(env, localeTag), nullptr);
75 }
76 
Locale_GetLanguage(ani_env * env,ani_object object)77 ani_string LocaleInfoAddon::Locale_GetLanguage(ani_env *env, ani_object object)
78 {
79     std::string value = GetLocaleProperty(env, object, "getLanguage", &LocaleInfo::GetLanguage);
80     return VariableConverter::StringToAniStr(env, value);
81 }
82 
Locale_GetScript(ani_env * env,ani_object object)83 ani_string LocaleInfoAddon::Locale_GetScript(ani_env *env, ani_object object)
84 {
85     std::string value = GetLocaleProperty(env, object, "getScript", &LocaleInfo::GetScript);
86     return VariableConverter::StringToAniStr(env, value);
87 }
88 
Locale_GetRegion(ani_env * env,ani_object object)89 ani_string LocaleInfoAddon::Locale_GetRegion(ani_env *env, ani_object object)
90 {
91     std::string value = GetLocaleProperty(env, object, "getRegion", &LocaleInfo::GetRegion);
92     return VariableConverter::StringToAniStr(env, value);
93 }
94 
Locale_GetBaseName(ani_env * env,ani_object object)95 ani_string LocaleInfoAddon::Locale_GetBaseName(ani_env *env, ani_object object)
96 {
97     std::string value = GetLocaleProperty(env, object, "getBaseName", &LocaleInfo::GetBaseName);
98     return VariableConverter::StringToAniStr(env, value);
99 }
100 
Locale_GetCaseFirst(ani_env * env,ani_object object)101 ani_string LocaleInfoAddon::Locale_GetCaseFirst(ani_env *env, ani_object object)
102 {
103     std::string value = GetLocaleProperty(env, object, "getCaseFirst", &LocaleInfo::GetCaseFirst);
104     return VariableConverter::StringToAniStr(env, value);
105 }
106 
Locale_GetCalendar(ani_env * env,ani_object object)107 ani_string LocaleInfoAddon::Locale_GetCalendar(ani_env *env, ani_object object)
108 {
109     std::string value = GetLocaleProperty(env, object, "getCalendar", &LocaleInfo::GetCalendar);
110     return VariableConverter::StringToAniStr(env, value);
111 }
112 
Locale_GetCollation(ani_env * env,ani_object object)113 ani_string LocaleInfoAddon::Locale_GetCollation(ani_env *env, ani_object object)
114 {
115     std::string value = GetLocaleProperty(env, object, "getCollation", &LocaleInfo::GetCollation);
116     return VariableConverter::StringToAniStr(env, value);
117 }
118 
Locale_GetHourCycle(ani_env * env,ani_object object)119 ani_string LocaleInfoAddon::Locale_GetHourCycle(ani_env *env, ani_object object)
120 {
121     std::string value = GetLocaleProperty(env, object, "getHourCycle", &LocaleInfo::GetHourCycle);
122     return VariableConverter::StringToAniStr(env, value);
123 }
124 
Locale_GetNumberingSystem(ani_env * env,ani_object object)125 ani_string LocaleInfoAddon::Locale_GetNumberingSystem(ani_env *env, ani_object object)
126 {
127     std::string value = GetLocaleProperty(env, object, "getNumberingSystem", &LocaleInfo::GetNumberingSystem);
128     return VariableConverter::StringToAniStr(env, value);
129 }
130 
Locale_GetNumeric(ani_env * env,ani_object object)131 ani_boolean LocaleInfoAddon::Locale_GetNumeric(ani_env *env, ani_object object)
132 {
133     LocaleInfoAddon* obj = UnwrapAddon(env, object, "nativeLocale");
134     if (obj == nullptr || obj->locale_ == nullptr) {
135         HILOG_ERROR_I18N("getNumeric: Get Locale object failed");
136         return false;
137     }
138     return (obj->locale_->GetNumeric() == "true");
139 }
140 
Locale_Create(ani_env * env,ani_object object)141 ani_object LocaleInfoAddon::Locale_Create(ani_env *env, [[maybe_unused]] ani_object object)
142 {
143     std::map<std::string, std::string> map = {};
144     std::unique_ptr<LocaleInfoAddon> obj = std::make_unique<LocaleInfoAddon>();
145     obj->locale_ = std::make_unique<LocaleInfo>("", map);
146 
147     static const char *className = "L@ohos/intl/intl/Locale;";
148     ani_object localeObject = VariableConverter::CreateAniObject(env, className, obj.get());
149     obj.release();
150     return localeObject;
151 }
152 
Locale_CreateWithParam(ani_env * env,ani_object object,ani_string locale,ani_object options)153 ani_object LocaleInfoAddon::Locale_CreateWithParam(ani_env *env, [[maybe_unused]] ani_object object,
154     ani_string locale, ani_object options)
155 {
156     std::map<std::string, std::string> map = {};
157     ani_boolean isUndefined;
158     if (ANI_OK != env->Reference_IsUndefined(options, &isUndefined)) {
159         HILOG_ERROR_I18N("Reference IsUndefined failed");
160         return nullptr;
161     }
162     if (!isUndefined) {
163         const std::vector<std::string> keys = {
164             "calendar", "collation", "hourCycle", "numberingSystem", "caseFirst"
165         };
166 
167         for (const auto& key : keys) {
168             std::string value;
169             if (VariableConverter::GetStringMember(env, options, key, value)) {
170                 map.insert(std::make_pair(key, value));
171             }
172         }
173 
174         bool numeric;
175         if (VariableConverter::GetBooleanMember(env, options, "numeric", numeric)) {
176             map.insert(std::make_pair("numeric", numeric ? "true" : "false"));
177         }
178     }
179 
180     std::unique_ptr<LocaleInfoAddon> obj = std::make_unique<LocaleInfoAddon>();
181     obj->locale_ = std::make_unique<LocaleInfo>(VariableConverter::AniStrToString(env, locale), map);
182     static const char *className = "L@ohos/intl/intl/Locale;";
183     ani_object localeObject = VariableConverter::CreateAniObject(env, className, obj.get());
184     obj.release();
185     return localeObject;
186 }
187 
BindContext_Locale(ani_env * env)188 ani_status LocaleInfoAddon::BindContext_Locale(ani_env *env)
189 {
190     static const char *className = "L@ohos/intl/intl/Locale;";
191     ani_class cls;
192     if (ANI_OK != env->FindClass(className, &cls)) {
193         HILOG_ERROR_I18N("Find class '%{public}s' failed", className);
194         return ANI_ERROR;
195     }
196 
197     std::array methods = {
198         ani_native_function {"create", ":L@ohos/intl/intl/Locale;", reinterpret_cast<void *>(Locale_Create) },
199         ani_native_function {"create", "Lstd/core/String;L@ohos/intl/intl/LocaleOptions;:L@ohos/intl/intl/Locale;",
200             reinterpret_cast<void *>(Locale_CreateWithParam) },
201         ani_native_function {"toString", nullptr, reinterpret_cast<void *>(Locale_ToString) },
202         ani_native_function {"maximize", nullptr, reinterpret_cast<void *>(Locale_Maximize) },
203         ani_native_function {"minimize", nullptr, reinterpret_cast<void *>(Locale_Minimize) },
204         ani_native_function {"getLanguage", nullptr, reinterpret_cast<void *>(Locale_GetLanguage) },
205         ani_native_function {"getScript", nullptr, reinterpret_cast<void *>(Locale_GetScript) },
206         ani_native_function {"getRegion", nullptr, reinterpret_cast<void *>(Locale_GetRegion) },
207         ani_native_function {"getBaseName", nullptr, reinterpret_cast<void *>(Locale_GetBaseName) },
208         ani_native_function {"getCaseFirst", nullptr, reinterpret_cast<void *>(Locale_GetCaseFirst) },
209         ani_native_function {"getCalendar", nullptr, reinterpret_cast<void *>(Locale_GetCalendar) },
210         ani_native_function {"getCollation", nullptr, reinterpret_cast<void *>(Locale_GetCollation) },
211         ani_native_function {"getHourCycle", nullptr, reinterpret_cast<void *>(Locale_GetHourCycle) },
212         ani_native_function {"getNumberingSystem", nullptr, reinterpret_cast<void *>(Locale_GetNumberingSystem) },
213         ani_native_function {"getNumeric", nullptr, reinterpret_cast<void *>(Locale_GetNumeric) },
214     };
215 
216     if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) {
217         HILOG_ERROR_I18N("Cannot bind native methods to '%{public}s'", className);
218         return ANI_ERROR;
219     };
220     return ANI_OK;
221 }
222