• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <unicode/locid.h>
17 #include "error_util.h"
18 #include "i18n_hilog.h"
19 #include "utils.h"
20 #include "variable_convertor.h"
21 #include "entity_recognizer_addon.h"
22 
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 const size_t EntityRecognizerAddon::ENTITY_INFO_LEN = 2;
27 
EntityRecognizerAddon()28 EntityRecognizerAddon::EntityRecognizerAddon() {}
29 
~EntityRecognizerAddon()30 EntityRecognizerAddon::~EntityRecognizerAddon()
31 {
32 }
33 
Destructor(napi_env env,void * nativeObject,void * hint)34 void EntityRecognizerAddon::Destructor(napi_env env, void *nativeObject, void *hint)
35 {
36     if (!nativeObject) {
37         return;
38     }
39     delete reinterpret_cast<EntityRecognizerAddon *>(nativeObject);
40     nativeObject = nullptr;
41 }
42 
InitEntityRecognizer(napi_env env,napi_value exports)43 napi_value EntityRecognizerAddon::InitEntityRecognizer(napi_env env, napi_value exports)
44 {
45     napi_property_descriptor properties[] = {
46         DECLARE_NAPI_FUNCTION("findEntityInfo", FindEntityInfo)
47     };
48     napi_value entityConstructor = nullptr;
49     napi_status status = napi_define_class(env, "EntityRecognizer", NAPI_AUTO_LENGTH, constructor, nullptr,
50         sizeof(properties) / sizeof(napi_property_descriptor), properties, &entityConstructor);
51     if (status != napi_ok) {
52         HILOG_ERROR_I18N("Failed to define class EntityRecognizer at Init.");
53         return nullptr;
54     }
55     status = napi_set_named_property(env, exports, "EntityRecognizer", entityConstructor);
56     if (status != napi_ok) {
57         HILOG_ERROR_I18N("Set property failed when InitEntityRecognizer");
58         return nullptr;
59     }
60     return exports;
61 }
62 
constructor(napi_env env,napi_callback_info info)63 napi_value EntityRecognizerAddon::constructor(napi_env env, napi_callback_info info)
64 {
65     size_t argc = 1;
66     napi_value argv[1] = { nullptr };
67     napi_value thisVar = nullptr;
68     void *data = nullptr;
69     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
70     if (status != napi_ok) {
71         return nullptr;
72     }
73     std::string localeStr;
74     if (argc < 1) {
75         localeStr = LocaleConfig::GetEffectiveLocale();
76     } else {
77         napi_valuetype valueType = napi_valuetype::napi_undefined;
78         status = napi_typeof(env, argv[0], &valueType);
79         if (status != napi_ok) {
80             return nullptr;
81         }
82         if (valueType != napi_valuetype::napi_string) {
83             ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "string", true);
84             return nullptr;
85         }
86         int32_t code = 0;
87         localeStr = VariableConvertor::GetString(env, argv[0], code);
88         if (code != 0) {
89             return nullptr;
90         }
91     }
92     UErrorCode localeStatus = U_ZERO_ERROR;
93     icu::Locale locale = icu::Locale::forLanguageTag(localeStr, localeStatus);
94     if (U_FAILURE(localeStatus)) {
95         HILOG_ERROR_I18N("EntityRecognizerAddon::constructor: Create icu::Locale failed.");
96         return nullptr;
97     } else if (!IsValidLocaleTag(locale)) {
98         ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", true);
99         return nullptr;
100     }
101     std::unique_ptr<EntityRecognizerAddon> obj = std::make_unique<EntityRecognizerAddon>();
102     status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
103         EntityRecognizerAddon::Destructor, nullptr, nullptr);
104     if (status != napi_ok) {
105         return nullptr;
106     }
107     obj->entityRecognizer_ = std::make_unique<EntityRecognizer>(locale);
108     if (!obj->entityRecognizer_) {
109         return nullptr;
110     }
111     obj.release();
112     return thisVar;
113 }
114 
FindEntityInfo(napi_env env,napi_callback_info info)115 napi_value EntityRecognizerAddon::FindEntityInfo(napi_env env, napi_callback_info info)
116 {
117     size_t argc = 1;
118     napi_value argv[1] = { 0 };
119     napi_value thisVar = nullptr;
120     void *data = nullptr;
121     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
122     if (status != napi_ok) {
123         return nullptr;
124     } else if (argc < 1) {
125         ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "text", true);
126         return nullptr;
127     }
128     napi_valuetype valueType = napi_valuetype::napi_undefined;
129     status = napi_typeof(env, argv[0], &valueType);
130     if (status != napi_ok) {
131         return nullptr;
132     }
133     if (valueType != napi_valuetype::napi_string) {
134         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "text", "string", true);
135         return nullptr;
136     }
137     int32_t code = 0;
138     std::string message = VariableConvertor::GetString(env, argv[0], code);
139     if (code != 0) {
140         return nullptr;
141     }
142     EntityRecognizerAddon *obj = nullptr;
143     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
144     if (status != napi_ok || obj == nullptr || obj->entityRecognizer_ == nullptr) {
145         HILOG_ERROR_I18N("Get EntityRecognizer object failed");
146         return nullptr;
147     }
148     std::vector<std::vector<int>> entityInfo = obj->entityRecognizer_->FindEntityInfo(message);
149     napi_value result = GetEntityInfoItem(env, entityInfo);
150     return result;
151 }
152 
GetEntityInfoItem(napi_env env,std::vector<std::vector<int>> & entityInfo)153 napi_value EntityRecognizerAddon::GetEntityInfoItem(napi_env env, std::vector<std::vector<int>>& entityInfo)
154 {
155     napi_value result = nullptr;
156     napi_status status = napi_create_array_with_length(env, entityInfo[0][0] + entityInfo[1][0], &result);
157     if (status != napi_ok) {
158         HILOG_ERROR_I18N("create EntityInfo array failed.");
159         return nullptr;
160     }
161     std::vector<std::string> types = {"phone_number", "date"};
162     int index = 0;
163     for (std::string::size_type t = 0; t < types.size(); t++) {
164         for (int i = 0; i < entityInfo[t][0]; i++) {
165             size_t posBegin = ENTITY_INFO_LEN * static_cast<size_t>(i) + 1;
166             int begin = entityInfo[t][posBegin];
167             int end = entityInfo[t][posBegin + 1];
168             std::string type = types[t];
169             napi_value item = CreateEntityInfoItem(env, begin, end, type);
170             if (item == nullptr) {
171                 continue;
172             }
173             status = napi_set_element(env, result, index, item);
174             if (status != napi_ok) {
175                 HILOG_ERROR_I18N("Failed to set item element.");
176                 return nullptr;
177             }
178             index++;
179         }
180     }
181     return result;
182 }
183 
CreateEntityInfoItem(napi_env env,const int begin,const int end,const std::string & type)184 napi_value EntityRecognizerAddon::CreateEntityInfoItem(napi_env env, const int begin,
185     const int end, const std::string& type)
186 {
187     napi_value result;
188     napi_status status = napi_create_object(env, &result);
189     if (status != napi_ok) {
190         HILOG_ERROR_I18N("Create EntityInfoItem object failed.");
191         return nullptr;
192     }
193     status = napi_set_named_property(env, result, "begin",
194         VariableConvertor::CreateNumber(env, begin));
195     if (status != napi_ok) {
196         HILOG_ERROR_I18N("Failed to set element begin.");
197         return nullptr;
198     }
199     status = napi_set_named_property(env, result, "end",
200         VariableConvertor::CreateNumber(env, end));
201     if (status != napi_ok) {
202         HILOG_ERROR_I18N("Failed to set element end.");
203         return nullptr;
204     }
205     status = napi_set_named_property(env, result, "type",
206         VariableConvertor::CreateString(env, type));
207     if (status != napi_ok) {
208         HILOG_ERROR_I18N("Failed to set element type.");
209         return nullptr;
210     }
211     return result;
212 }
213 
214 } // namespace I18n
215 } // namespace Global
216 } // namespace OHOS