15bebb993Sopenharmony_ci/* 25bebb993Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 35bebb993Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 45bebb993Sopenharmony_ci * you may not use this file except in compliance with the License. 55bebb993Sopenharmony_ci * You may obtain a copy of the License at 65bebb993Sopenharmony_ci * 75bebb993Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 85bebb993Sopenharmony_ci * 95bebb993Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 105bebb993Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 115bebb993Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125bebb993Sopenharmony_ci * See the License for the specific language governing permissions and 135bebb993Sopenharmony_ci * limitations under the License. 145bebb993Sopenharmony_ci */ 155bebb993Sopenharmony_ci 165bebb993Sopenharmony_ci#include "n_class.h" 175bebb993Sopenharmony_ci 185bebb993Sopenharmony_ci#include "filemgmt_libhilog.h" 195bebb993Sopenharmony_ci 205bebb993Sopenharmony_cinamespace OHOS { 215bebb993Sopenharmony_cinamespace FileManagement { 225bebb993Sopenharmony_cinamespace LibN { 235bebb993Sopenharmony_ciusing namespace std; 245bebb993Sopenharmony_ciNClass &NClass::GetInstance() 255bebb993Sopenharmony_ci{ 265bebb993Sopenharmony_ci static thread_local NClass nClass; 275bebb993Sopenharmony_ci return nClass; 285bebb993Sopenharmony_ci} 295bebb993Sopenharmony_ci 305bebb993Sopenharmony_cituple<bool, napi_value> NClass::DefineClass(napi_env env, 315bebb993Sopenharmony_ci string className, 325bebb993Sopenharmony_ci napi_callback constructor, 335bebb993Sopenharmony_ci vector<napi_property_descriptor> &&properties) 345bebb993Sopenharmony_ci{ 355bebb993Sopenharmony_ci napi_value classVal = nullptr; 365bebb993Sopenharmony_ci napi_status stat = napi_define_class(env, className.c_str(), className.length(), constructor, nullptr, 375bebb993Sopenharmony_ci properties.size(), properties.data(), &classVal); 385bebb993Sopenharmony_ci if (stat != napi_ok) { 395bebb993Sopenharmony_ci HILOGE("INNER BUG. Cannot define class %{public}s because of %{public}d", className.c_str(), stat); 405bebb993Sopenharmony_ci } 415bebb993Sopenharmony_ci 425bebb993Sopenharmony_ci return {stat == napi_ok, classVal}; 435bebb993Sopenharmony_ci} 445bebb993Sopenharmony_ci 455bebb993Sopenharmony_cibool NClass::SaveClass(napi_env env, string className, napi_value exClass) 465bebb993Sopenharmony_ci{ 475bebb993Sopenharmony_ci NClass &nClass = NClass::GetInstance(); 485bebb993Sopenharmony_ci lock_guard<std::mutex>(nClass.exClassMapLock); 495bebb993Sopenharmony_ci 505bebb993Sopenharmony_ci if (nClass.exClassMap.find(className) != nClass.exClassMap.end()) { 515bebb993Sopenharmony_ci return true; 525bebb993Sopenharmony_ci } 535bebb993Sopenharmony_ci 545bebb993Sopenharmony_ci napi_ref constructor; 555bebb993Sopenharmony_ci napi_status res = napi_create_reference(env, exClass, 1, &constructor); 565bebb993Sopenharmony_ci if (res == napi_ok) { 575bebb993Sopenharmony_ci nClass.exClassMap.insert({className, constructor}); 585bebb993Sopenharmony_ci } else { 595bebb993Sopenharmony_ci HILOGE("INNER BUG. Cannot ref class constructor %{public}s because of %{public}d", className.c_str(), res); 605bebb993Sopenharmony_ci } 615bebb993Sopenharmony_ci 625bebb993Sopenharmony_ci if (!nClass.addCleanHook) { 635bebb993Sopenharmony_ci napi_status status = napi_add_env_cleanup_hook(env, CleanClass, env); 645bebb993Sopenharmony_ci if (status != napi_ok) { 655bebb993Sopenharmony_ci HILOGE("INNER BUG. Cleanup_hook registation has failed because of %{public}d", res); 665bebb993Sopenharmony_ci } else { 675bebb993Sopenharmony_ci nClass.addCleanHook = true; 685bebb993Sopenharmony_ci } 695bebb993Sopenharmony_ci } 705bebb993Sopenharmony_ci return res == napi_ok; 715bebb993Sopenharmony_ci} 725bebb993Sopenharmony_ci 735bebb993Sopenharmony_civoid NClass::CleanClass(void *arg) 745bebb993Sopenharmony_ci{ 755bebb993Sopenharmony_ci napi_env env = reinterpret_cast<napi_env>(arg); 765bebb993Sopenharmony_ci NClass &nClass = NClass::GetInstance(); 775bebb993Sopenharmony_ci lock_guard<std::mutex>(nClass.exClassMapLock); 785bebb993Sopenharmony_ci 795bebb993Sopenharmony_ci napi_status res; 805bebb993Sopenharmony_ci for (auto it = nClass.exClassMap.begin(); it != nClass.exClassMap.end(); ++it) { 815bebb993Sopenharmony_ci res = napi_delete_reference(env, it->second); 825bebb993Sopenharmony_ci if (res != napi_ok) { 835bebb993Sopenharmony_ci HILOGE("Cannot del ref class constructor %{public}s because of %{public}d", it->first.c_str(), res); 845bebb993Sopenharmony_ci } 855bebb993Sopenharmony_ci } 865bebb993Sopenharmony_ci nClass.exClassMap.clear(); 875bebb993Sopenharmony_ci} 885bebb993Sopenharmony_ci 895bebb993Sopenharmony_cinapi_value NClass::InstantiateClass(napi_env env, const string& className, const vector<napi_value>& args) 905bebb993Sopenharmony_ci{ 915bebb993Sopenharmony_ci NClass &nClass = NClass::GetInstance(); 925bebb993Sopenharmony_ci lock_guard<std::mutex>(nClass.exClassMapLock); 935bebb993Sopenharmony_ci 945bebb993Sopenharmony_ci auto it = nClass.exClassMap.find(className); 955bebb993Sopenharmony_ci if (it == nClass.exClassMap.end()) { 965bebb993Sopenharmony_ci HILOGE("Class %{public}s hasn't been saved yet", className.c_str()); 975bebb993Sopenharmony_ci return nullptr; 985bebb993Sopenharmony_ci } 995bebb993Sopenharmony_ci 1005bebb993Sopenharmony_ci napi_value cons = nullptr; 1015bebb993Sopenharmony_ci napi_status status = napi_get_reference_value(env, it->second, &cons); 1025bebb993Sopenharmony_ci if (status != napi_ok) { 1035bebb993Sopenharmony_ci HILOGE("INNER BUG. Cannot deref class %{public}s because of %{public}d", className.c_str(), status); 1045bebb993Sopenharmony_ci return nullptr; 1055bebb993Sopenharmony_ci } 1065bebb993Sopenharmony_ci 1075bebb993Sopenharmony_ci napi_value instance = nullptr; 1085bebb993Sopenharmony_ci status = napi_new_instance(env, cons, args.size(), args.data(), &instance); 1095bebb993Sopenharmony_ci if (status != napi_ok) { 1105bebb993Sopenharmony_ci HILOGE("INNER BUG. Cannot instantiate the class %{public}s because of %{public}d", className.c_str(), status); 1115bebb993Sopenharmony_ci return nullptr; 1125bebb993Sopenharmony_ci } 1135bebb993Sopenharmony_ci 1145bebb993Sopenharmony_ci return instance; 1155bebb993Sopenharmony_ci} 1165bebb993Sopenharmony_ci} // namespace LibN 1175bebb993Sopenharmony_ci} // namespace FileManagement 1185bebb993Sopenharmony_ci} // namespace OHOS 119