19596a2c1Sopenharmony_ci/*
29596a2c1Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License.
59596a2c1Sopenharmony_ci * You may obtain a copy of the License at
69596a2c1Sopenharmony_ci *
79596a2c1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89596a2c1Sopenharmony_ci *
99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and
139596a2c1Sopenharmony_ci * limitations under the License.
149596a2c1Sopenharmony_ci */
159596a2c1Sopenharmony_ci
169596a2c1Sopenharmony_ci#include "intl_addon.h"
179596a2c1Sopenharmony_ci
189596a2c1Sopenharmony_ci#include <vector>
199596a2c1Sopenharmony_ci#include <set>
209596a2c1Sopenharmony_ci#include "error_util.h"
219596a2c1Sopenharmony_ci#include "i18n_hilog.h"
229596a2c1Sopenharmony_ci#include "js_utils.h"
239596a2c1Sopenharmony_ci#include "node_api.h"
249596a2c1Sopenharmony_ci#include "utils.h"
259596a2c1Sopenharmony_ci
269596a2c1Sopenharmony_cinamespace OHOS {
279596a2c1Sopenharmony_cinamespace Global {
289596a2c1Sopenharmony_cinamespace I18n {
299596a2c1Sopenharmony_cistatic thread_local napi_ref *g_constructor = nullptr;
309596a2c1Sopenharmony_ci
319596a2c1Sopenharmony_ciIntlAddon::IntlAddon() : env_(nullptr) {}
329596a2c1Sopenharmony_ci
339596a2c1Sopenharmony_ciIntlAddon::~IntlAddon()
349596a2c1Sopenharmony_ci{
359596a2c1Sopenharmony_ci}
369596a2c1Sopenharmony_ci
379596a2c1Sopenharmony_civoid IntlAddon::Destructor(napi_env env, void *nativeObject, void *hint)
389596a2c1Sopenharmony_ci{
399596a2c1Sopenharmony_ci    if (!nativeObject) {
409596a2c1Sopenharmony_ci        return;
419596a2c1Sopenharmony_ci    }
429596a2c1Sopenharmony_ci    delete reinterpret_cast<IntlAddon *>(nativeObject);
439596a2c1Sopenharmony_ci    nativeObject = nullptr;
449596a2c1Sopenharmony_ci}
459596a2c1Sopenharmony_ci
469596a2c1Sopenharmony_cinapi_value IntlAddon::SetProperty(napi_env env, napi_callback_info info)
479596a2c1Sopenharmony_ci{
489596a2c1Sopenharmony_ci    // do nothing but provided as an input parameter for DECLARE_NAPI_GETTER_SETTER;
499596a2c1Sopenharmony_ci    napi_value result = nullptr;
509596a2c1Sopenharmony_ci    NAPI_CALL(env, napi_get_undefined(env, &result));
519596a2c1Sopenharmony_ci    return result;
529596a2c1Sopenharmony_ci}
539596a2c1Sopenharmony_ci
549596a2c1Sopenharmony_cinapi_value IntlAddon::InitLocale(napi_env env, napi_value exports)
559596a2c1Sopenharmony_ci{
569596a2c1Sopenharmony_ci    napi_status status = napi_ok;
579596a2c1Sopenharmony_ci    napi_property_descriptor properties[] = {
589596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("language", GetLanguage, SetProperty),
599596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("baseName", GetBaseName, SetProperty),
609596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("region", GetRegion, SetProperty),
619596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("script", GetScript, SetProperty),
629596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("calendar", GetCalendar, SetProperty),
639596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("collation", GetCollation, SetProperty),
649596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("hourCycle", GetHourCycle, SetProperty),
659596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("numberingSystem", GetNumberingSystem, SetProperty),
669596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("numeric", GetNumeric, SetProperty),
679596a2c1Sopenharmony_ci        DECLARE_NAPI_GETTER_SETTER("caseFirst", GetCaseFirst, SetProperty),
689596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("toString", ToString),
699596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("minimize", Minimize),
709596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("maximize", Maximize),
719596a2c1Sopenharmony_ci    };
729596a2c1Sopenharmony_ci
739596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
749596a2c1Sopenharmony_ci    status = napi_define_class(env, "Locale", NAPI_AUTO_LENGTH, LocaleConstructor, nullptr,
759596a2c1Sopenharmony_ci        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
769596a2c1Sopenharmony_ci    if (status != napi_ok) {
779596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Define class failed when InitLocale");
789596a2c1Sopenharmony_ci        return nullptr;
799596a2c1Sopenharmony_ci    }
809596a2c1Sopenharmony_ci
819596a2c1Sopenharmony_ci    status = napi_set_named_property(env, exports, "Locale", constructor);
829596a2c1Sopenharmony_ci    if (status != napi_ok) {
839596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Set property failed when InitLocale");
849596a2c1Sopenharmony_ci        return nullptr;
859596a2c1Sopenharmony_ci    }
869596a2c1Sopenharmony_ci    g_constructor = new (std::nothrow) napi_ref;
879596a2c1Sopenharmony_ci    if (!g_constructor) {
889596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Failed to create ref at init");
899596a2c1Sopenharmony_ci        return nullptr;
909596a2c1Sopenharmony_ci    }
919596a2c1Sopenharmony_ci    status = napi_create_reference(env, constructor, 1, g_constructor);
929596a2c1Sopenharmony_ci    if (status != napi_ok) {
939596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Failed to create reference at init");
949596a2c1Sopenharmony_ci        return nullptr;
959596a2c1Sopenharmony_ci    }
969596a2c1Sopenharmony_ci    return exports;
979596a2c1Sopenharmony_ci}
989596a2c1Sopenharmony_ci
999596a2c1Sopenharmony_cinapi_value IntlAddon::InitDateTimeFormat(napi_env env, napi_value exports)
1009596a2c1Sopenharmony_ci{
1019596a2c1Sopenharmony_ci    napi_status status = napi_ok;
1029596a2c1Sopenharmony_ci    napi_property_descriptor properties[] = {
1039596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("format", FormatDateTime),
1049596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("formatRange", FormatDateTimeRange),
1059596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("resolvedOptions", GetDateTimeResolvedOptions)
1069596a2c1Sopenharmony_ci    };
1079596a2c1Sopenharmony_ci
1089596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
1099596a2c1Sopenharmony_ci    status = napi_define_class(env, "DateTimeFormat", NAPI_AUTO_LENGTH, DateTimeFormatConstructor, nullptr,
1109596a2c1Sopenharmony_ci        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1119596a2c1Sopenharmony_ci    if (status != napi_ok) {
1129596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Define class failed when InitDateTimeFormat");
1139596a2c1Sopenharmony_ci        return nullptr;
1149596a2c1Sopenharmony_ci    }
1159596a2c1Sopenharmony_ci
1169596a2c1Sopenharmony_ci    status = napi_set_named_property(env, exports, "DateTimeFormat", constructor);
1179596a2c1Sopenharmony_ci    if (status != napi_ok) {
1189596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Set property failed when InitDateTimeFormat");
1199596a2c1Sopenharmony_ci        return nullptr;
1209596a2c1Sopenharmony_ci    }
1219596a2c1Sopenharmony_ci    return exports;
1229596a2c1Sopenharmony_ci}
1239596a2c1Sopenharmony_ci
1249596a2c1Sopenharmony_cinapi_value IntlAddon::InitRelativeTimeFormat(napi_env env, napi_value exports)
1259596a2c1Sopenharmony_ci{
1269596a2c1Sopenharmony_ci    napi_status status = napi_ok;
1279596a2c1Sopenharmony_ci    napi_property_descriptor properties[] = {
1289596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("format", FormatRelativeTime),
1299596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("formatToParts", FormatToParts),
1309596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("resolvedOptions", GetRelativeTimeResolvedOptions)
1319596a2c1Sopenharmony_ci    };
1329596a2c1Sopenharmony_ci
1339596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
1349596a2c1Sopenharmony_ci    status = napi_define_class(env, "RelativeTimeFormat", NAPI_AUTO_LENGTH, RelativeTimeFormatConstructor, nullptr,
1359596a2c1Sopenharmony_ci        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1369596a2c1Sopenharmony_ci    if (status != napi_ok) {
1379596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Define class failed when InitRelativeTimeFormat");
1389596a2c1Sopenharmony_ci        return nullptr;
1399596a2c1Sopenharmony_ci    }
1409596a2c1Sopenharmony_ci
1419596a2c1Sopenharmony_ci    status = napi_set_named_property(env, exports, "RelativeTimeFormat", constructor);
1429596a2c1Sopenharmony_ci    if (status != napi_ok) {
1439596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Set property failed when InitRelativeTimeFormat");
1449596a2c1Sopenharmony_ci        return nullptr;
1459596a2c1Sopenharmony_ci    }
1469596a2c1Sopenharmony_ci    return exports;
1479596a2c1Sopenharmony_ci}
1489596a2c1Sopenharmony_ci
1499596a2c1Sopenharmony_cinapi_value IntlAddon::InitNumberFormat(napi_env env, napi_value exports)
1509596a2c1Sopenharmony_ci{
1519596a2c1Sopenharmony_ci    napi_status status = napi_ok;
1529596a2c1Sopenharmony_ci    napi_property_descriptor properties[] = {
1539596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("format", FormatNumber),
1549596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("resolvedOptions", GetNumberResolvedOptions)
1559596a2c1Sopenharmony_ci    };
1569596a2c1Sopenharmony_ci
1579596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
1589596a2c1Sopenharmony_ci    status = napi_define_class(env, "NumberFormat", NAPI_AUTO_LENGTH, NumberFormatConstructor, nullptr,
1599596a2c1Sopenharmony_ci        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
1609596a2c1Sopenharmony_ci    if (status != napi_ok) {
1619596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Define class failed when InitNumberFormat");
1629596a2c1Sopenharmony_ci        return nullptr;
1639596a2c1Sopenharmony_ci    }
1649596a2c1Sopenharmony_ci
1659596a2c1Sopenharmony_ci    status = napi_set_named_property(env, exports, "NumberFormat", constructor);
1669596a2c1Sopenharmony_ci    if (status != napi_ok) {
1679596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Set property failed when InitNumberFormat");
1689596a2c1Sopenharmony_ci        return nullptr;
1699596a2c1Sopenharmony_ci    }
1709596a2c1Sopenharmony_ci    return exports;
1719596a2c1Sopenharmony_ci}
1729596a2c1Sopenharmony_ci
1739596a2c1Sopenharmony_civoid GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
1749596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
1759596a2c1Sopenharmony_ci{
1769596a2c1Sopenharmony_ci    napi_value optionValue = nullptr;
1779596a2c1Sopenharmony_ci    napi_valuetype type = napi_undefined;
1789596a2c1Sopenharmony_ci    napi_status status = napi_typeof(env, options, &type);
1799596a2c1Sopenharmony_ci    if (status != napi_ok && type != napi_object) {
1809596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get option failed, option is not an object");
1819596a2c1Sopenharmony_ci        return;
1829596a2c1Sopenharmony_ci    }
1839596a2c1Sopenharmony_ci    bool hasProperty = false;
1849596a2c1Sopenharmony_ci    napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
1859596a2c1Sopenharmony_ci    if (propStatus == napi_ok && hasProperty) {
1869596a2c1Sopenharmony_ci        status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
1879596a2c1Sopenharmony_ci        if (status == napi_ok) {
1889596a2c1Sopenharmony_ci            size_t len = 0;
1899596a2c1Sopenharmony_ci            napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
1909596a2c1Sopenharmony_ci            std::vector<char> optionBuf(len + 1);
1919596a2c1Sopenharmony_ci            status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
1929596a2c1Sopenharmony_ci            if (status != napi_ok) {
1939596a2c1Sopenharmony_ci                return;
1949596a2c1Sopenharmony_ci            }
1959596a2c1Sopenharmony_ci            map.insert(make_pair(optionName, optionBuf.data()));
1969596a2c1Sopenharmony_ci        }
1979596a2c1Sopenharmony_ci    }
1989596a2c1Sopenharmony_ci}
1999596a2c1Sopenharmony_ci
2009596a2c1Sopenharmony_ciint64_t GetIntegerOptionValue(napi_env env, napi_value options, const std::string &optionName,
2019596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
2029596a2c1Sopenharmony_ci{
2039596a2c1Sopenharmony_ci    napi_value optionValue = nullptr;
2049596a2c1Sopenharmony_ci    int64_t integerValue = -1;
2059596a2c1Sopenharmony_ci    napi_valuetype type = napi_undefined;
2069596a2c1Sopenharmony_ci    napi_status status = napi_typeof(env, options, &type);
2079596a2c1Sopenharmony_ci    if (status != napi_ok && type != napi_object) {
2089596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetIntegerOptionValue: Set option failed, option is not an object");
2099596a2c1Sopenharmony_ci        return integerValue;
2109596a2c1Sopenharmony_ci    }
2119596a2c1Sopenharmony_ci    bool hasProperty = false;
2129596a2c1Sopenharmony_ci    napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
2139596a2c1Sopenharmony_ci    if (propStatus == napi_ok && hasProperty) {
2149596a2c1Sopenharmony_ci        status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
2159596a2c1Sopenharmony_ci        if (status == napi_ok) {
2169596a2c1Sopenharmony_ci            status = napi_get_value_int64(env, optionValue, &integerValue);
2179596a2c1Sopenharmony_ci            if (status == napi_ok) {
2189596a2c1Sopenharmony_ci                map.insert(make_pair(optionName, std::to_string(integerValue)));
2199596a2c1Sopenharmony_ci            }
2209596a2c1Sopenharmony_ci        }
2219596a2c1Sopenharmony_ci    }
2229596a2c1Sopenharmony_ci    return integerValue;
2239596a2c1Sopenharmony_ci}
2249596a2c1Sopenharmony_ci
2259596a2c1Sopenharmony_civoid GetBoolOptionValue(napi_env env, napi_value options, const std::string &optionName,
2269596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
2279596a2c1Sopenharmony_ci{
2289596a2c1Sopenharmony_ci    napi_value optionValue = nullptr;
2299596a2c1Sopenharmony_ci    napi_valuetype type = napi_undefined;
2309596a2c1Sopenharmony_ci    napi_status status = napi_typeof(env, options, &type);
2319596a2c1Sopenharmony_ci    if (status != napi_ok && type != napi_object) {
2329596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetBoolOptionValue: Set option failed, option is not an object");
2339596a2c1Sopenharmony_ci        return;
2349596a2c1Sopenharmony_ci    }
2359596a2c1Sopenharmony_ci    bool hasProperty = false;
2369596a2c1Sopenharmony_ci    napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
2379596a2c1Sopenharmony_ci    if (propStatus == napi_ok && hasProperty) {
2389596a2c1Sopenharmony_ci        status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
2399596a2c1Sopenharmony_ci        if (status == napi_ok) {
2409596a2c1Sopenharmony_ci            bool boolValue = false;
2419596a2c1Sopenharmony_ci            napi_get_value_bool(env, optionValue, &boolValue);
2429596a2c1Sopenharmony_ci            std::string value = boolValue ? "true" : "false";
2439596a2c1Sopenharmony_ci            map.insert(make_pair(optionName, value));
2449596a2c1Sopenharmony_ci        }
2459596a2c1Sopenharmony_ci    }
2469596a2c1Sopenharmony_ci}
2479596a2c1Sopenharmony_ci
2489596a2c1Sopenharmony_civoid GetDateOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map)
2499596a2c1Sopenharmony_ci{
2509596a2c1Sopenharmony_ci    GetOptionValue(env, options, "calendar", map);
2519596a2c1Sopenharmony_ci    GetOptionValue(env, options, "dateStyle", map);
2529596a2c1Sopenharmony_ci    GetOptionValue(env, options, "timeStyle", map);
2539596a2c1Sopenharmony_ci    GetOptionValue(env, options, "hourCycle", map);
2549596a2c1Sopenharmony_ci    GetOptionValue(env, options, "timeZone", map);
2559596a2c1Sopenharmony_ci    GetOptionValue(env, options, "timeZoneName", map);
2569596a2c1Sopenharmony_ci    GetOptionValue(env, options, "numberingSystem", map);
2579596a2c1Sopenharmony_ci    GetBoolOptionValue(env, options, "hour12", map);
2589596a2c1Sopenharmony_ci    GetOptionValue(env, options, "weekday", map);
2599596a2c1Sopenharmony_ci    GetOptionValue(env, options, "era", map);
2609596a2c1Sopenharmony_ci    GetOptionValue(env, options, "year", map);
2619596a2c1Sopenharmony_ci    GetOptionValue(env, options, "month", map);
2629596a2c1Sopenharmony_ci    GetOptionValue(env, options, "day", map);
2639596a2c1Sopenharmony_ci    GetOptionValue(env, options, "hour", map);
2649596a2c1Sopenharmony_ci    GetOptionValue(env, options, "minute", map);
2659596a2c1Sopenharmony_ci    GetOptionValue(env, options, "second", map);
2669596a2c1Sopenharmony_ci    GetOptionValue(env, options, "localeMatcher", map);
2679596a2c1Sopenharmony_ci    GetOptionValue(env, options, "formatMatcher", map);
2689596a2c1Sopenharmony_ci    GetOptionValue(env, options, "dayPeriod", map);
2699596a2c1Sopenharmony_ci}
2709596a2c1Sopenharmony_ci
2719596a2c1Sopenharmony_civoid GetRelativeTimeOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map)
2729596a2c1Sopenharmony_ci{
2739596a2c1Sopenharmony_ci    GetOptionValue(env, options, "localeMatcher", map);
2749596a2c1Sopenharmony_ci    GetOptionValue(env, options, "numeric", map);
2759596a2c1Sopenharmony_ci    GetOptionValue(env, options, "style", map);
2769596a2c1Sopenharmony_ci}
2779596a2c1Sopenharmony_ci
2789596a2c1Sopenharmony_cistd::string GetLocaleTag(napi_env env, napi_value argv)
2799596a2c1Sopenharmony_ci{
2809596a2c1Sopenharmony_ci    std::string localeTag = "";
2819596a2c1Sopenharmony_ci    std::vector<char> buf;
2829596a2c1Sopenharmony_ci    if (argv != nullptr) {
2839596a2c1Sopenharmony_ci        napi_valuetype valueType = napi_valuetype::napi_undefined;
2849596a2c1Sopenharmony_ci        napi_typeof(env, argv, &valueType);
2859596a2c1Sopenharmony_ci        if (valueType != napi_valuetype::napi_string) {
2869596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("GetLocaleTag: Parameter type does not match");
2879596a2c1Sopenharmony_ci            return "";
2889596a2c1Sopenharmony_ci        }
2899596a2c1Sopenharmony_ci        size_t len = 0;
2909596a2c1Sopenharmony_ci        napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
2919596a2c1Sopenharmony_ci        if (status != napi_ok) {
2929596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("GetLocaleTag -> string: Get locale tag length failed");
2939596a2c1Sopenharmony_ci            return "";
2949596a2c1Sopenharmony_ci        }
2959596a2c1Sopenharmony_ci        buf.resize(len + 1);
2969596a2c1Sopenharmony_ci        status = napi_get_value_string_utf8(env, argv, buf.data(), len + 1, &len);
2979596a2c1Sopenharmony_ci        if (status != napi_ok) {
2989596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("GetLocaleTag: Get locale tag failed");
2999596a2c1Sopenharmony_ci            return "";
3009596a2c1Sopenharmony_ci        }
3019596a2c1Sopenharmony_ci        localeTag = buf.data();
3029596a2c1Sopenharmony_ci    } else {
3039596a2c1Sopenharmony_ci        localeTag = "";
3049596a2c1Sopenharmony_ci    }
3059596a2c1Sopenharmony_ci    return localeTag;
3069596a2c1Sopenharmony_ci}
3079596a2c1Sopenharmony_ci
3089596a2c1Sopenharmony_cinapi_value IntlAddon::LocaleConstructor(napi_env env, napi_callback_info info)
3099596a2c1Sopenharmony_ci{
3109596a2c1Sopenharmony_ci    size_t argc = 2;
3119596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
3129596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
3139596a2c1Sopenharmony_ci    void *data = nullptr;
3149596a2c1Sopenharmony_ci    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3159596a2c1Sopenharmony_ci    if (status != napi_ok) {
3169596a2c1Sopenharmony_ci        return nullptr;
3179596a2c1Sopenharmony_ci    }
3189596a2c1Sopenharmony_ci    std::string localeTag = GetLocaleTag(env, argc > 0 ? argv[0] : nullptr);
3199596a2c1Sopenharmony_ci
3209596a2c1Sopenharmony_ci    std::map<std::string, std::string> map = {};
3219596a2c1Sopenharmony_ci    if (argc > 1) {
3229596a2c1Sopenharmony_ci        GetOptionValue(env, argv[1], "calendar", map);
3239596a2c1Sopenharmony_ci        GetOptionValue(env, argv[1], "collation", map);
3249596a2c1Sopenharmony_ci        GetOptionValue(env, argv[1], "hourCycle", map);
3259596a2c1Sopenharmony_ci        GetOptionValue(env, argv[1], "numberingSystem", map);
3269596a2c1Sopenharmony_ci        GetBoolOptionValue(env, argv[1], "numeric", map);
3279596a2c1Sopenharmony_ci        GetOptionValue(env, argv[1], "caseFirst", map);
3289596a2c1Sopenharmony_ci    }
3299596a2c1Sopenharmony_ci    std::unique_ptr<IntlAddon> obj = nullptr;
3309596a2c1Sopenharmony_ci    obj = std::make_unique<IntlAddon>();
3319596a2c1Sopenharmony_ci    status =
3329596a2c1Sopenharmony_ci        napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), IntlAddon::Destructor, nullptr, nullptr);
3339596a2c1Sopenharmony_ci    if (status != napi_ok) {
3349596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("LocaleConstructor: Wrap IntlAddon failed");
3359596a2c1Sopenharmony_ci        return nullptr;
3369596a2c1Sopenharmony_ci    }
3379596a2c1Sopenharmony_ci    if (!obj->InitLocaleContext(env, info, localeTag, map)) {
3389596a2c1Sopenharmony_ci        return nullptr;
3399596a2c1Sopenharmony_ci    }
3409596a2c1Sopenharmony_ci    obj.release();
3419596a2c1Sopenharmony_ci    return thisVar;
3429596a2c1Sopenharmony_ci}
3439596a2c1Sopenharmony_ci
3449596a2c1Sopenharmony_cibool IntlAddon::InitLocaleContext(napi_env env, napi_callback_info info, const std::string localeTag,
3459596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
3469596a2c1Sopenharmony_ci{
3479596a2c1Sopenharmony_ci    napi_value global = nullptr;
3489596a2c1Sopenharmony_ci    napi_status status = napi_get_global(env, &global);
3499596a2c1Sopenharmony_ci    if (status != napi_ok) {
3509596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("InitLocaleContext: Get global failed");
3519596a2c1Sopenharmony_ci        return false;
3529596a2c1Sopenharmony_ci    }
3539596a2c1Sopenharmony_ci    env_ = env;
3549596a2c1Sopenharmony_ci    locale_ = std::make_unique<LocaleInfo>(localeTag, map);
3559596a2c1Sopenharmony_ci
3569596a2c1Sopenharmony_ci    return locale_ != nullptr;
3579596a2c1Sopenharmony_ci}
3589596a2c1Sopenharmony_ci
3599596a2c1Sopenharmony_civoid GetLocaleTags(napi_env env, napi_value rawLocaleTag, std::vector<std::string> &localeTags)
3609596a2c1Sopenharmony_ci{
3619596a2c1Sopenharmony_ci    size_t len = 0;
3629596a2c1Sopenharmony_ci    napi_status status = napi_get_value_string_utf8(env, rawLocaleTag, nullptr, 0, &len);
3639596a2c1Sopenharmony_ci    if (status != napi_ok) {
3649596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetLocaleTag -> void: Get locale tag length failed");
3659596a2c1Sopenharmony_ci        return;
3669596a2c1Sopenharmony_ci    }
3679596a2c1Sopenharmony_ci    std::vector<char> buf(len + 1);
3689596a2c1Sopenharmony_ci    status = napi_get_value_string_utf8(env, rawLocaleTag, buf.data(), len + 1, &len);
3699596a2c1Sopenharmony_ci    if (status != napi_ok) {
3709596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetLocaleTags: Get locale tag failed");
3719596a2c1Sopenharmony_ci        return;
3729596a2c1Sopenharmony_ci    }
3739596a2c1Sopenharmony_ci    localeTags.push_back(buf.data());
3749596a2c1Sopenharmony_ci}
3759596a2c1Sopenharmony_ci
3769596a2c1Sopenharmony_cinapi_value IntlAddon::DateTimeFormatConstructor(napi_env env, napi_callback_info info)
3779596a2c1Sopenharmony_ci{
3789596a2c1Sopenharmony_ci    size_t argc = 2;
3799596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
3809596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
3819596a2c1Sopenharmony_ci    void *data = nullptr;
3829596a2c1Sopenharmony_ci    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
3839596a2c1Sopenharmony_ci    if (status != napi_ok) {
3849596a2c1Sopenharmony_ci        return nullptr;
3859596a2c1Sopenharmony_ci    }
3869596a2c1Sopenharmony_ci    std::vector<std::string> localeTags;
3879596a2c1Sopenharmony_ci    if (argc > 0) {
3889596a2c1Sopenharmony_ci        napi_valuetype valueType = napi_valuetype::napi_undefined;
3899596a2c1Sopenharmony_ci        napi_typeof(env, argv[0], &valueType);
3909596a2c1Sopenharmony_ci        bool isArray = false;
3919596a2c1Sopenharmony_ci        napi_is_array(env, argv[0], &isArray);
3929596a2c1Sopenharmony_ci        if (valueType == napi_valuetype::napi_string) {
3939596a2c1Sopenharmony_ci            GetLocaleTags(env, argv[0], localeTags);
3949596a2c1Sopenharmony_ci        } else if (isArray) {
3959596a2c1Sopenharmony_ci            uint32_t arrayLength = 0;
3969596a2c1Sopenharmony_ci            napi_get_array_length(env, argv[0], &arrayLength);
3979596a2c1Sopenharmony_ci            napi_value element = nullptr;
3989596a2c1Sopenharmony_ci            for (uint32_t i = 0; i < arrayLength; i++) {
3999596a2c1Sopenharmony_ci                napi_get_element(env, argv[0], i, &element);
4009596a2c1Sopenharmony_ci                GetLocaleTags(env, element, localeTags);
4019596a2c1Sopenharmony_ci            }
4029596a2c1Sopenharmony_ci        }
4039596a2c1Sopenharmony_ci    }
4049596a2c1Sopenharmony_ci    std::map<std::string, std::string> map = {};
4059596a2c1Sopenharmony_ci    if (argc > 1) {
4069596a2c1Sopenharmony_ci        GetDateOptionValues(env, argv[1], map);
4079596a2c1Sopenharmony_ci    }
4089596a2c1Sopenharmony_ci    std::unique_ptr<IntlAddon> obj = nullptr;
4099596a2c1Sopenharmony_ci    obj = std::make_unique<IntlAddon>();
4109596a2c1Sopenharmony_ci    status =
4119596a2c1Sopenharmony_ci        napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), IntlAddon::Destructor, nullptr, nullptr);
4129596a2c1Sopenharmony_ci    if (status != napi_ok) {
4139596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("DateTimeFormatConstructor: Wrap IntlAddon failed");
4149596a2c1Sopenharmony_ci        return nullptr;
4159596a2c1Sopenharmony_ci    }
4169596a2c1Sopenharmony_ci    if (!obj->InitDateTimeFormatContext(env, info, localeTags, map)) {
4179596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("DateTimeFormatConstructor: Init DateTimeFormat failed");
4189596a2c1Sopenharmony_ci        return nullptr;
4199596a2c1Sopenharmony_ci    }
4209596a2c1Sopenharmony_ci    obj.release();
4219596a2c1Sopenharmony_ci    return thisVar;
4229596a2c1Sopenharmony_ci}
4239596a2c1Sopenharmony_ci
4249596a2c1Sopenharmony_cibool IntlAddon::InitDateTimeFormatContext(napi_env env, napi_callback_info info, std::vector<std::string> localeTags,
4259596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
4269596a2c1Sopenharmony_ci{
4279596a2c1Sopenharmony_ci    napi_value global = nullptr;
4289596a2c1Sopenharmony_ci    napi_status status = napi_get_global(env, &global);
4299596a2c1Sopenharmony_ci    if (status != napi_ok) {
4309596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("InitDateTimeFormatContext: Get global failed");
4319596a2c1Sopenharmony_ci        return false;
4329596a2c1Sopenharmony_ci    }
4339596a2c1Sopenharmony_ci    env_ = env;
4349596a2c1Sopenharmony_ci    datefmt_ = DateTimeFormat::CreateInstance(localeTags, map);
4359596a2c1Sopenharmony_ci
4369596a2c1Sopenharmony_ci    return datefmt_ != nullptr;
4379596a2c1Sopenharmony_ci}
4389596a2c1Sopenharmony_ci
4399596a2c1Sopenharmony_cinapi_value IntlAddon::RelativeTimeFormatConstructor(napi_env env, napi_callback_info info)
4409596a2c1Sopenharmony_ci{
4419596a2c1Sopenharmony_ci    size_t argc = 2;
4429596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
4439596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
4449596a2c1Sopenharmony_ci    void *data = nullptr;
4459596a2c1Sopenharmony_ci    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
4469596a2c1Sopenharmony_ci    if (status != napi_ok) {
4479596a2c1Sopenharmony_ci        return nullptr;
4489596a2c1Sopenharmony_ci    }
4499596a2c1Sopenharmony_ci    std::vector<std::string> localeTags;
4509596a2c1Sopenharmony_ci    if (argc > 0) {
4519596a2c1Sopenharmony_ci        napi_valuetype valueType = napi_valuetype::napi_undefined;
4529596a2c1Sopenharmony_ci        napi_typeof(env, argv[0], &valueType);
4539596a2c1Sopenharmony_ci        bool isArray = false;
4549596a2c1Sopenharmony_ci        napi_is_array(env, argv[0], &isArray);
4559596a2c1Sopenharmony_ci        if (valueType == napi_valuetype::napi_string) {
4569596a2c1Sopenharmony_ci            GetLocaleTags(env, argv[0], localeTags);
4579596a2c1Sopenharmony_ci        } else if (isArray) {
4589596a2c1Sopenharmony_ci            uint32_t arrayLength = 0;
4599596a2c1Sopenharmony_ci            napi_get_array_length(env, argv[0], &arrayLength);
4609596a2c1Sopenharmony_ci            napi_value element = nullptr;
4619596a2c1Sopenharmony_ci            for (uint32_t i = 0; i < arrayLength; i++) {
4629596a2c1Sopenharmony_ci                napi_get_element(env, argv[0], i, &element);
4639596a2c1Sopenharmony_ci                GetLocaleTags(env, element, localeTags);
4649596a2c1Sopenharmony_ci            }
4659596a2c1Sopenharmony_ci        }
4669596a2c1Sopenharmony_ci    }
4679596a2c1Sopenharmony_ci    std::map<std::string, std::string> map = {};
4689596a2c1Sopenharmony_ci    if (argc > 1) {
4699596a2c1Sopenharmony_ci        GetRelativeTimeOptionValues(env, argv[1], map);
4709596a2c1Sopenharmony_ci    }
4719596a2c1Sopenharmony_ci    std::unique_ptr<IntlAddon> obj = nullptr;
4729596a2c1Sopenharmony_ci    obj = std::make_unique<IntlAddon>();
4739596a2c1Sopenharmony_ci    status =
4749596a2c1Sopenharmony_ci        napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), IntlAddon::Destructor, nullptr, nullptr);
4759596a2c1Sopenharmony_ci    if (status != napi_ok) {
4769596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("RelativeTimeFormatConstructor: Wrap IntlAddon failed");
4779596a2c1Sopenharmony_ci        return nullptr;
4789596a2c1Sopenharmony_ci    }
4799596a2c1Sopenharmony_ci    if (!obj->InitRelativeTimeFormatContext(env, info, localeTags, map)) {
4809596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Init RelativeTimeFormat failed");
4819596a2c1Sopenharmony_ci        return nullptr;
4829596a2c1Sopenharmony_ci    }
4839596a2c1Sopenharmony_ci    obj.release();
4849596a2c1Sopenharmony_ci    return thisVar;
4859596a2c1Sopenharmony_ci}
4869596a2c1Sopenharmony_ci
4879596a2c1Sopenharmony_cibool IntlAddon::InitRelativeTimeFormatContext(napi_env env, napi_callback_info info,
4889596a2c1Sopenharmony_ci    std::vector<std::string> localeTags, std::map<std::string, std::string> &map)
4899596a2c1Sopenharmony_ci{
4909596a2c1Sopenharmony_ci    env_ = env;
4919596a2c1Sopenharmony_ci    relativetimefmt_ = std::make_unique<RelativeTimeFormat>(localeTags, map);
4929596a2c1Sopenharmony_ci
4939596a2c1Sopenharmony_ci    return relativetimefmt_ != nullptr;
4949596a2c1Sopenharmony_ci}
4959596a2c1Sopenharmony_ci
4969596a2c1Sopenharmony_cinapi_value IntlAddon::FormatDateTime(napi_env env, napi_callback_info info)
4979596a2c1Sopenharmony_ci{
4989596a2c1Sopenharmony_ci    size_t argc = 1;
4999596a2c1Sopenharmony_ci    napi_value argv[1] = { 0 };
5009596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
5019596a2c1Sopenharmony_ci    void *data = nullptr;
5029596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
5039596a2c1Sopenharmony_ci
5049596a2c1Sopenharmony_ci    int64_t milliseconds = GetMilliseconds(env, argv, 0);
5059596a2c1Sopenharmony_ci    if (milliseconds == -1) {
5069596a2c1Sopenharmony_ci        return nullptr;
5079596a2c1Sopenharmony_ci    }
5089596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
5099596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
5109596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->datefmt_) {
5119596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatDateTime: Get DateTimeFormat object failed");
5129596a2c1Sopenharmony_ci        return nullptr;
5139596a2c1Sopenharmony_ci    }
5149596a2c1Sopenharmony_ci    std::string value = obj->datefmt_->Format(milliseconds);
5159596a2c1Sopenharmony_ci    napi_value result = nullptr;
5169596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
5179596a2c1Sopenharmony_ci    if (status != napi_ok) {
5189596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatDateTime: Create format string failed");
5199596a2c1Sopenharmony_ci        return nullptr;
5209596a2c1Sopenharmony_ci    }
5219596a2c1Sopenharmony_ci    return result;
5229596a2c1Sopenharmony_ci}
5239596a2c1Sopenharmony_ci
5249596a2c1Sopenharmony_cinapi_value IntlAddon::FormatDateTimeRange(napi_env env, napi_callback_info info)
5259596a2c1Sopenharmony_ci{
5269596a2c1Sopenharmony_ci    size_t argc = 2;
5279596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
5289596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
5299596a2c1Sopenharmony_ci    void *data = nullptr;
5309596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
5319596a2c1Sopenharmony_ci    if (argc < FUNC_ARGS_COUNT) {
5329596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Parameter wrong");
5339596a2c1Sopenharmony_ci        return nullptr;
5349596a2c1Sopenharmony_ci    }
5359596a2c1Sopenharmony_ci    int64_t firstMilliseconds = GetMilliseconds(env, argv, 0);
5369596a2c1Sopenharmony_ci    int64_t secondMilliseconds = GetMilliseconds(env, argv, 1);
5379596a2c1Sopenharmony_ci    if (firstMilliseconds == -1 || secondMilliseconds == -1) {
5389596a2c1Sopenharmony_ci        return nullptr;
5399596a2c1Sopenharmony_ci    }
5409596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
5419596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
5429596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->datefmt_) {
5439596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatDateTimeRange: Get DateTimeFormat object failed");
5449596a2c1Sopenharmony_ci        return nullptr;
5459596a2c1Sopenharmony_ci    }
5469596a2c1Sopenharmony_ci    std::string value = obj->datefmt_->FormatRange(firstMilliseconds, secondMilliseconds);
5479596a2c1Sopenharmony_ci    napi_value result = nullptr;
5489596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
5499596a2c1Sopenharmony_ci    if (status != napi_ok) {
5509596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatDateTimeRange: Create format string failed");
5519596a2c1Sopenharmony_ci        return nullptr;
5529596a2c1Sopenharmony_ci    }
5539596a2c1Sopenharmony_ci    return result;
5549596a2c1Sopenharmony_ci}
5559596a2c1Sopenharmony_ci
5569596a2c1Sopenharmony_civoid GetNumberOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map)
5579596a2c1Sopenharmony_ci{
5589596a2c1Sopenharmony_ci    GetOptionValue(env, options, "currency", map);
5599596a2c1Sopenharmony_ci    GetOptionValue(env, options, "currencySign", map);
5609596a2c1Sopenharmony_ci    GetOptionValue(env, options, "currencyDisplay", map);
5619596a2c1Sopenharmony_ci    GetOptionValue(env, options, "unit", map);
5629596a2c1Sopenharmony_ci    GetOptionValue(env, options, "unitDisplay", map);
5639596a2c1Sopenharmony_ci    GetOptionValue(env, options, "compactDisplay", map);
5649596a2c1Sopenharmony_ci    GetOptionValue(env, options, "signDisplay", map);
5659596a2c1Sopenharmony_ci    GetOptionValue(env, options, "localeMatcher", map);
5669596a2c1Sopenharmony_ci    GetOptionValue(env, options, "style", map);
5679596a2c1Sopenharmony_ci    GetOptionValue(env, options, "numberingSystem", map);
5689596a2c1Sopenharmony_ci    GetOptionValue(env, options, "notation", map);
5699596a2c1Sopenharmony_ci    GetOptionValue(env, options, "unitUsage", map);
5709596a2c1Sopenharmony_ci    GetBoolOptionValue(env, options, "useGrouping", map);
5719596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "minimumIntegerDigits", map);
5729596a2c1Sopenharmony_ci    int64_t minFd = GetIntegerOptionValue(env, options, "minimumFractionDigits", map);
5739596a2c1Sopenharmony_ci    int64_t maxFd = GetIntegerOptionValue(env, options, "maximumFractionDigits", map);
5749596a2c1Sopenharmony_ci    if (minFd != -1 && maxFd != -1 && minFd > maxFd) {
5759596a2c1Sopenharmony_ci        HILOG_ERROR_I18N(
5769596a2c1Sopenharmony_ci            "GetNumberOptionValues: Invalid parameter value: minimumFractionDigits > maximumFractionDigits");
5779596a2c1Sopenharmony_ci    }
5789596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "minimumSignificantDigits", map);
5799596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "maximumSignificantDigits", map);
5809596a2c1Sopenharmony_ci}
5819596a2c1Sopenharmony_ci
5829596a2c1Sopenharmony_cinapi_value IntlAddon::NumberFormatConstructor(napi_env env, napi_callback_info info)
5839596a2c1Sopenharmony_ci{
5849596a2c1Sopenharmony_ci    size_t argc = 2;
5859596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
5869596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
5879596a2c1Sopenharmony_ci    void *data = nullptr;
5889596a2c1Sopenharmony_ci    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
5899596a2c1Sopenharmony_ci    if (status != napi_ok) {
5909596a2c1Sopenharmony_ci        return nullptr;
5919596a2c1Sopenharmony_ci    }
5929596a2c1Sopenharmony_ci    std::vector<std::string> localeTags;
5939596a2c1Sopenharmony_ci    if (argc > 0) {
5949596a2c1Sopenharmony_ci        napi_valuetype valueType = napi_valuetype::napi_undefined;
5959596a2c1Sopenharmony_ci        napi_typeof(env, argv[0], &valueType);
5969596a2c1Sopenharmony_ci        bool isArray = false;
5979596a2c1Sopenharmony_ci        napi_is_array(env, argv[0], &isArray);
5989596a2c1Sopenharmony_ci
5999596a2c1Sopenharmony_ci        if (valueType == napi_valuetype::napi_string) {
6009596a2c1Sopenharmony_ci            GetLocaleTags(env, argv[0], localeTags);
6019596a2c1Sopenharmony_ci        } else if (isArray) {
6029596a2c1Sopenharmony_ci            uint32_t arrayLength = 0;
6039596a2c1Sopenharmony_ci            napi_get_array_length(env, argv[0], &arrayLength);
6049596a2c1Sopenharmony_ci            napi_value element = nullptr;
6059596a2c1Sopenharmony_ci            for (uint32_t i = 0; i < arrayLength; i++) {
6069596a2c1Sopenharmony_ci                napi_get_element(env, argv[0], i, &element);
6079596a2c1Sopenharmony_ci                GetLocaleTags(env, element, localeTags);
6089596a2c1Sopenharmony_ci            }
6099596a2c1Sopenharmony_ci        }
6109596a2c1Sopenharmony_ci    }
6119596a2c1Sopenharmony_ci    std::map<std::string, std::string> map = {};
6129596a2c1Sopenharmony_ci    if (argc > 1) {
6139596a2c1Sopenharmony_ci        GetNumberOptionValues(env, argv[1], map);
6149596a2c1Sopenharmony_ci    }
6159596a2c1Sopenharmony_ci    std::unique_ptr<IntlAddon> obj = nullptr;
6169596a2c1Sopenharmony_ci    obj = std::make_unique<IntlAddon>();
6179596a2c1Sopenharmony_ci    status =
6189596a2c1Sopenharmony_ci        napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), IntlAddon::Destructor, nullptr, nullptr);
6199596a2c1Sopenharmony_ci    if (status != napi_ok) {
6209596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("NumberFormatConstructor: Wrap IntlAddon failed");
6219596a2c1Sopenharmony_ci        return nullptr;
6229596a2c1Sopenharmony_ci    }
6239596a2c1Sopenharmony_ci    if (!obj->InitNumberFormatContext(env, info, localeTags, map)) {
6249596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Init NumberFormat failed");
6259596a2c1Sopenharmony_ci        return nullptr;
6269596a2c1Sopenharmony_ci    }
6279596a2c1Sopenharmony_ci    obj.release();
6289596a2c1Sopenharmony_ci    return thisVar;
6299596a2c1Sopenharmony_ci}
6309596a2c1Sopenharmony_ci
6319596a2c1Sopenharmony_cibool IntlAddon::InitNumberFormatContext(napi_env env, napi_callback_info info, std::vector<std::string> localeTags,
6329596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
6339596a2c1Sopenharmony_ci{
6349596a2c1Sopenharmony_ci    napi_value global = nullptr;
6359596a2c1Sopenharmony_ci    napi_status status = napi_get_global(env, &global);
6369596a2c1Sopenharmony_ci    if (status != napi_ok) {
6379596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("InitNumberFormatContext: Get global failed");
6389596a2c1Sopenharmony_ci        return false;
6399596a2c1Sopenharmony_ci    }
6409596a2c1Sopenharmony_ci    env_ = env;
6419596a2c1Sopenharmony_ci    numberfmt_ = std::make_unique<NumberFormat>(localeTags, map);
6429596a2c1Sopenharmony_ci
6439596a2c1Sopenharmony_ci    return numberfmt_ != nullptr;
6449596a2c1Sopenharmony_ci}
6459596a2c1Sopenharmony_ci
6469596a2c1Sopenharmony_ciint64_t IntlAddon::GetMilliseconds(napi_env env, napi_value *argv, int index)
6479596a2c1Sopenharmony_ci{
6489596a2c1Sopenharmony_ci    napi_value funcGetDateInfo = nullptr;
6499596a2c1Sopenharmony_ci    napi_status status = napi_get_named_property(env, argv[index], "getTime", &funcGetDateInfo);
6509596a2c1Sopenharmony_ci    if (status != napi_ok) {
6519596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get Milliseconds property failed");
6529596a2c1Sopenharmony_ci        return -1;
6539596a2c1Sopenharmony_ci    }
6549596a2c1Sopenharmony_ci    napi_value ret_value = nullptr;
6559596a2c1Sopenharmony_ci    status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
6569596a2c1Sopenharmony_ci    if (status != napi_ok) {
6579596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get Milliseconds function failed");
6589596a2c1Sopenharmony_ci        return -1;
6599596a2c1Sopenharmony_ci    }
6609596a2c1Sopenharmony_ci    int64_t milliseconds = 0;
6619596a2c1Sopenharmony_ci    status = napi_get_value_int64(env, ret_value, &milliseconds);
6629596a2c1Sopenharmony_ci    if (status != napi_ok) {
6639596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get Milliseconds failed");
6649596a2c1Sopenharmony_ci        return -1;
6659596a2c1Sopenharmony_ci    }
6669596a2c1Sopenharmony_ci    return milliseconds;
6679596a2c1Sopenharmony_ci}
6689596a2c1Sopenharmony_ci
6699596a2c1Sopenharmony_cinapi_value IntlAddon::GetLanguage(napi_env env, napi_callback_info info)
6709596a2c1Sopenharmony_ci{
6719596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
6729596a2c1Sopenharmony_ci    void *data = nullptr;
6739596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
6749596a2c1Sopenharmony_ci
6759596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
6769596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
6779596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
6789596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetLanguage: Get Locale object failed");
6799596a2c1Sopenharmony_ci        return nullptr;
6809596a2c1Sopenharmony_ci    }
6819596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetLanguage();
6829596a2c1Sopenharmony_ci
6839596a2c1Sopenharmony_ci    napi_value result = nullptr;
6849596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
6859596a2c1Sopenharmony_ci    if (status != napi_ok) {
6869596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetLanguage: Create language string failed");
6879596a2c1Sopenharmony_ci        return nullptr;
6889596a2c1Sopenharmony_ci    }
6899596a2c1Sopenharmony_ci    return result;
6909596a2c1Sopenharmony_ci}
6919596a2c1Sopenharmony_ci
6929596a2c1Sopenharmony_cinapi_value IntlAddon::GetScript(napi_env env, napi_callback_info info)
6939596a2c1Sopenharmony_ci{
6949596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
6959596a2c1Sopenharmony_ci    void *data = nullptr;
6969596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
6979596a2c1Sopenharmony_ci
6989596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
6999596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
7009596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
7019596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetScript: Get Locale object failed");
7029596a2c1Sopenharmony_ci        return nullptr;
7039596a2c1Sopenharmony_ci    }
7049596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetScript();
7059596a2c1Sopenharmony_ci
7069596a2c1Sopenharmony_ci    napi_value result = nullptr;
7079596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
7089596a2c1Sopenharmony_ci    if (status != napi_ok) {
7099596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Create script string failed");
7109596a2c1Sopenharmony_ci        return nullptr;
7119596a2c1Sopenharmony_ci    }
7129596a2c1Sopenharmony_ci    return result;
7139596a2c1Sopenharmony_ci}
7149596a2c1Sopenharmony_ci
7159596a2c1Sopenharmony_cinapi_value IntlAddon::GetRegion(napi_env env, napi_callback_info info)
7169596a2c1Sopenharmony_ci{
7179596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
7189596a2c1Sopenharmony_ci    void *data = nullptr;
7199596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
7209596a2c1Sopenharmony_ci
7219596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
7229596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
7239596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
7249596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetRegion: Get Locale object failed");
7259596a2c1Sopenharmony_ci        return nullptr;
7269596a2c1Sopenharmony_ci    }
7279596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetRegion();
7289596a2c1Sopenharmony_ci
7299596a2c1Sopenharmony_ci    napi_value result = nullptr;
7309596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
7319596a2c1Sopenharmony_ci    if (status != napi_ok) {
7329596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Create region string failed");
7339596a2c1Sopenharmony_ci        return nullptr;
7349596a2c1Sopenharmony_ci    }
7359596a2c1Sopenharmony_ci    return result;
7369596a2c1Sopenharmony_ci}
7379596a2c1Sopenharmony_ci
7389596a2c1Sopenharmony_cinapi_value IntlAddon::GetBaseName(napi_env env, napi_callback_info info)
7399596a2c1Sopenharmony_ci{
7409596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
7419596a2c1Sopenharmony_ci    void *data = nullptr;
7429596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
7439596a2c1Sopenharmony_ci
7449596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
7459596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
7469596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
7479596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetBaseName: Get Locale object failed");
7489596a2c1Sopenharmony_ci        return nullptr;
7499596a2c1Sopenharmony_ci    }
7509596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetBaseName();
7519596a2c1Sopenharmony_ci
7529596a2c1Sopenharmony_ci    napi_value result = nullptr;
7539596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
7549596a2c1Sopenharmony_ci    if (status != napi_ok) {
7559596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetBaseName: Create base name string failed");
7569596a2c1Sopenharmony_ci        return nullptr;
7579596a2c1Sopenharmony_ci    }
7589596a2c1Sopenharmony_ci    return result;
7599596a2c1Sopenharmony_ci}
7609596a2c1Sopenharmony_ci
7619596a2c1Sopenharmony_cinapi_value IntlAddon::GetCalendar(napi_env env, napi_callback_info info)
7629596a2c1Sopenharmony_ci{
7639596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
7649596a2c1Sopenharmony_ci    void *data = nullptr;
7659596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
7669596a2c1Sopenharmony_ci
7679596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
7689596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
7699596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
7709596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetCalendar: Get Locale object failed");
7719596a2c1Sopenharmony_ci        return nullptr;
7729596a2c1Sopenharmony_ci    }
7739596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetCalendar();
7749596a2c1Sopenharmony_ci
7759596a2c1Sopenharmony_ci    napi_value result = nullptr;
7769596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
7779596a2c1Sopenharmony_ci    if (status != napi_ok) {
7789596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetCalendar: Create base name string failed");
7799596a2c1Sopenharmony_ci        return nullptr;
7809596a2c1Sopenharmony_ci    }
7819596a2c1Sopenharmony_ci    return result;
7829596a2c1Sopenharmony_ci}
7839596a2c1Sopenharmony_ci
7849596a2c1Sopenharmony_cinapi_value IntlAddon::GetCollation(napi_env env, napi_callback_info info)
7859596a2c1Sopenharmony_ci{
7869596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
7879596a2c1Sopenharmony_ci    void *data = nullptr;
7889596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
7899596a2c1Sopenharmony_ci
7909596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
7919596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
7929596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
7939596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetCollation: Get Locale object failed");
7949596a2c1Sopenharmony_ci        return nullptr;
7959596a2c1Sopenharmony_ci    }
7969596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetCollation();
7979596a2c1Sopenharmony_ci
7989596a2c1Sopenharmony_ci    napi_value result = nullptr;
7999596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
8009596a2c1Sopenharmony_ci    if (status != napi_ok) {
8019596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetCollation: Create base name string failed");
8029596a2c1Sopenharmony_ci        return nullptr;
8039596a2c1Sopenharmony_ci    }
8049596a2c1Sopenharmony_ci    return result;
8059596a2c1Sopenharmony_ci}
8069596a2c1Sopenharmony_ci
8079596a2c1Sopenharmony_cinapi_value IntlAddon::GetHourCycle(napi_env env, napi_callback_info info)
8089596a2c1Sopenharmony_ci{
8099596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
8109596a2c1Sopenharmony_ci    void *data = nullptr;
8119596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
8129596a2c1Sopenharmony_ci
8139596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
8149596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
8159596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
8169596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetHourCycle: Get Locale object failed");
8179596a2c1Sopenharmony_ci        return nullptr;
8189596a2c1Sopenharmony_ci    }
8199596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetHourCycle();
8209596a2c1Sopenharmony_ci
8219596a2c1Sopenharmony_ci    napi_value result = nullptr;
8229596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
8239596a2c1Sopenharmony_ci    if (status != napi_ok) {
8249596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetHourCycle: Create base name string failed");
8259596a2c1Sopenharmony_ci        return nullptr;
8269596a2c1Sopenharmony_ci    }
8279596a2c1Sopenharmony_ci    return result;
8289596a2c1Sopenharmony_ci}
8299596a2c1Sopenharmony_ci
8309596a2c1Sopenharmony_cinapi_value IntlAddon::GetNumberingSystem(napi_env env, napi_callback_info info)
8319596a2c1Sopenharmony_ci{
8329596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
8339596a2c1Sopenharmony_ci    void *data = nullptr;
8349596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
8359596a2c1Sopenharmony_ci
8369596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
8379596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
8389596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
8399596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetNumberingSystem: Get Locale object failed");
8409596a2c1Sopenharmony_ci        return nullptr;
8419596a2c1Sopenharmony_ci    }
8429596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetNumberingSystem();
8439596a2c1Sopenharmony_ci
8449596a2c1Sopenharmony_ci    napi_value result = nullptr;
8459596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
8469596a2c1Sopenharmony_ci    if (status != napi_ok) {
8479596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetNumberingSystem: Create base name string failed");
8489596a2c1Sopenharmony_ci        return nullptr;
8499596a2c1Sopenharmony_ci    }
8509596a2c1Sopenharmony_ci    return result;
8519596a2c1Sopenharmony_ci}
8529596a2c1Sopenharmony_ci
8539596a2c1Sopenharmony_cinapi_value IntlAddon::GetNumeric(napi_env env, napi_callback_info info)
8549596a2c1Sopenharmony_ci{
8559596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
8569596a2c1Sopenharmony_ci    void *data = nullptr;
8579596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
8589596a2c1Sopenharmony_ci
8599596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
8609596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
8619596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
8629596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetNumeric: Get Locale object failed");
8639596a2c1Sopenharmony_ci        return nullptr;
8649596a2c1Sopenharmony_ci    }
8659596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetNumeric();
8669596a2c1Sopenharmony_ci    bool optionBoolValue = (value == "true");
8679596a2c1Sopenharmony_ci    napi_value result = nullptr;
8689596a2c1Sopenharmony_ci    status = napi_get_boolean(env, optionBoolValue, &result);
8699596a2c1Sopenharmony_ci    if (status != napi_ok) {
8709596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Create numeric boolean value failed");
8719596a2c1Sopenharmony_ci        return nullptr;
8729596a2c1Sopenharmony_ci    }
8739596a2c1Sopenharmony_ci    return result;
8749596a2c1Sopenharmony_ci}
8759596a2c1Sopenharmony_ci
8769596a2c1Sopenharmony_cinapi_value IntlAddon::GetCaseFirst(napi_env env, napi_callback_info info)
8779596a2c1Sopenharmony_ci{
8789596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
8799596a2c1Sopenharmony_ci    void *data = nullptr;
8809596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
8819596a2c1Sopenharmony_ci
8829596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
8839596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
8849596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
8859596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetCaseFirst: Get Locale object failed");
8869596a2c1Sopenharmony_ci        return nullptr;
8879596a2c1Sopenharmony_ci    }
8889596a2c1Sopenharmony_ci    std::string value = obj->locale_->GetCaseFirst();
8899596a2c1Sopenharmony_ci    napi_value result = nullptr;
8909596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
8919596a2c1Sopenharmony_ci    if (status != napi_ok) {
8929596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Create caseFirst string failed");
8939596a2c1Sopenharmony_ci        return nullptr;
8949596a2c1Sopenharmony_ci    }
8959596a2c1Sopenharmony_ci    return result;
8969596a2c1Sopenharmony_ci}
8979596a2c1Sopenharmony_ci
8989596a2c1Sopenharmony_cinapi_value IntlAddon::ToString(napi_env env, napi_callback_info info)
8999596a2c1Sopenharmony_ci{
9009596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
9019596a2c1Sopenharmony_ci    void *data = nullptr;
9029596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
9039596a2c1Sopenharmony_ci
9049596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
9059596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
9069596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
9079596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("ToString: Get Locale object failed");
9089596a2c1Sopenharmony_ci        return nullptr;
9099596a2c1Sopenharmony_ci    }
9109596a2c1Sopenharmony_ci    std::string value = obj->locale_->ToString();
9119596a2c1Sopenharmony_ci
9129596a2c1Sopenharmony_ci    napi_value result = nullptr;
9139596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
9149596a2c1Sopenharmony_ci    if (status != napi_ok) {
9159596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("ToString: Create language string failed");
9169596a2c1Sopenharmony_ci        return nullptr;
9179596a2c1Sopenharmony_ci    }
9189596a2c1Sopenharmony_ci    return result;
9199596a2c1Sopenharmony_ci}
9209596a2c1Sopenharmony_ci
9219596a2c1Sopenharmony_cinapi_value IntlAddon::Maximize(napi_env env, napi_callback_info info)
9229596a2c1Sopenharmony_ci{
9239596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
9249596a2c1Sopenharmony_ci    void *data = nullptr;
9259596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
9269596a2c1Sopenharmony_ci
9279596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
9289596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
9299596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
9309596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Maximize: Get Locale object failed");
9319596a2c1Sopenharmony_ci        return nullptr;
9329596a2c1Sopenharmony_ci    }
9339596a2c1Sopenharmony_ci    std::string localeTag = obj->locale_->Maximize();
9349596a2c1Sopenharmony_ci
9359596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
9369596a2c1Sopenharmony_ci    status = napi_get_reference_value(env, *g_constructor, &constructor);
9379596a2c1Sopenharmony_ci    if (status != napi_ok) {
9389596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Maximize: Get locale constructor reference failed");
9399596a2c1Sopenharmony_ci        return nullptr;
9409596a2c1Sopenharmony_ci    }
9419596a2c1Sopenharmony_ci    napi_value result = nullptr;
9429596a2c1Sopenharmony_ci    napi_value arg = nullptr;
9439596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, localeTag.c_str(), NAPI_AUTO_LENGTH, &arg);
9449596a2c1Sopenharmony_ci    if (status != napi_ok) {
9459596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Maximize: Create localeTag string failed");
9469596a2c1Sopenharmony_ci        return nullptr;
9479596a2c1Sopenharmony_ci    }
9489596a2c1Sopenharmony_ci    status = napi_new_instance(env, constructor, 1, &arg, &result);
9499596a2c1Sopenharmony_ci    if (status != napi_ok) {
9509596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Maximize: Create new locale instance failed");
9519596a2c1Sopenharmony_ci        return nullptr;
9529596a2c1Sopenharmony_ci    }
9539596a2c1Sopenharmony_ci    return result;
9549596a2c1Sopenharmony_ci}
9559596a2c1Sopenharmony_ci
9569596a2c1Sopenharmony_cinapi_value IntlAddon::Minimize(napi_env env, napi_callback_info info)
9579596a2c1Sopenharmony_ci{
9589596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
9599596a2c1Sopenharmony_ci    void *data = nullptr;
9609596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
9619596a2c1Sopenharmony_ci
9629596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
9639596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
9649596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->locale_) {
9659596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Minimize: Get Locale object failed");
9669596a2c1Sopenharmony_ci        return nullptr;
9679596a2c1Sopenharmony_ci    }
9689596a2c1Sopenharmony_ci    std::string localeTag = obj->locale_->Minimize();
9699596a2c1Sopenharmony_ci
9709596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
9719596a2c1Sopenharmony_ci    status = napi_get_reference_value(env, *g_constructor, &constructor);
9729596a2c1Sopenharmony_ci    if (status != napi_ok) {
9739596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Minimize: Get locale constructor reference failed");
9749596a2c1Sopenharmony_ci        return nullptr;
9759596a2c1Sopenharmony_ci    }
9769596a2c1Sopenharmony_ci    napi_value result = nullptr;
9779596a2c1Sopenharmony_ci    napi_value arg = nullptr;
9789596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, localeTag.c_str(), NAPI_AUTO_LENGTH, &arg);
9799596a2c1Sopenharmony_ci    if (status != napi_ok) {
9809596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Minimize: Create localeTag string failed");
9819596a2c1Sopenharmony_ci        return nullptr;
9829596a2c1Sopenharmony_ci    }
9839596a2c1Sopenharmony_ci    status = napi_new_instance(env, constructor, 1, &arg, &result);
9849596a2c1Sopenharmony_ci    if (status != napi_ok) {
9859596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Minimize: Create new locale instance failed");
9869596a2c1Sopenharmony_ci        return nullptr;
9879596a2c1Sopenharmony_ci    }
9889596a2c1Sopenharmony_ci    return result;
9899596a2c1Sopenharmony_ci}
9909596a2c1Sopenharmony_ci
9919596a2c1Sopenharmony_civoid SetOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
9929596a2c1Sopenharmony_ci    const std::string &option)
9939596a2c1Sopenharmony_ci{
9949596a2c1Sopenharmony_ci    if (options.count(option) > 0) {
9959596a2c1Sopenharmony_ci        std::string optionValue = options[option];
9969596a2c1Sopenharmony_ci        napi_value optionJsValue = nullptr;
9979596a2c1Sopenharmony_ci        napi_create_string_utf8(env, optionValue.c_str(), NAPI_AUTO_LENGTH, &optionJsValue);
9989596a2c1Sopenharmony_ci        napi_set_named_property(env, result, option.c_str(), optionJsValue);
9999596a2c1Sopenharmony_ci    } else {
10009596a2c1Sopenharmony_ci        napi_value undefined = nullptr;
10019596a2c1Sopenharmony_ci        napi_get_undefined(env, &undefined);
10029596a2c1Sopenharmony_ci        napi_set_named_property(env, result, option.c_str(), undefined);
10039596a2c1Sopenharmony_ci    }
10049596a2c1Sopenharmony_ci}
10059596a2c1Sopenharmony_ci
10069596a2c1Sopenharmony_civoid SetIntegerOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
10079596a2c1Sopenharmony_ci    const std::string &option)
10089596a2c1Sopenharmony_ci{
10099596a2c1Sopenharmony_ci    if (options.count(option) > 0) {
10109596a2c1Sopenharmony_ci        std::string optionValue = options[option];
10119596a2c1Sopenharmony_ci        napi_value optionJsValue = nullptr;
10129596a2c1Sopenharmony_ci        int32_t status = 0;
10139596a2c1Sopenharmony_ci        int64_t integerValue = ConvertString2Int(optionValue, status);
10149596a2c1Sopenharmony_ci        if (status != -1) {
10159596a2c1Sopenharmony_ci            napi_create_int64(env, integerValue, &optionJsValue);
10169596a2c1Sopenharmony_ci            napi_set_named_property(env, result, option.c_str(), optionJsValue);
10179596a2c1Sopenharmony_ci            return;
10189596a2c1Sopenharmony_ci        }
10199596a2c1Sopenharmony_ci    }
10209596a2c1Sopenharmony_ci    napi_value undefined = nullptr;
10219596a2c1Sopenharmony_ci    napi_get_undefined(env, &undefined);
10229596a2c1Sopenharmony_ci    napi_set_named_property(env, result, option.c_str(), undefined);
10239596a2c1Sopenharmony_ci}
10249596a2c1Sopenharmony_ci
10259596a2c1Sopenharmony_civoid SetBooleanOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
10269596a2c1Sopenharmony_ci    const std::string &option)
10279596a2c1Sopenharmony_ci{
10289596a2c1Sopenharmony_ci    if (options.count(option) > 0) {
10299596a2c1Sopenharmony_ci        std::string optionValue = options[option];
10309596a2c1Sopenharmony_ci        bool optionBoolValue = (optionValue == "true");
10319596a2c1Sopenharmony_ci        napi_value optionJsValue = nullptr;
10329596a2c1Sopenharmony_ci        napi_get_boolean(env, optionBoolValue, &optionJsValue);
10339596a2c1Sopenharmony_ci        napi_set_named_property(env, result, option.c_str(), optionJsValue);
10349596a2c1Sopenharmony_ci    } else {
10359596a2c1Sopenharmony_ci        napi_value undefined = nullptr;
10369596a2c1Sopenharmony_ci        napi_get_undefined(env, &undefined);
10379596a2c1Sopenharmony_ci        napi_set_named_property(env, result, option.c_str(), undefined);
10389596a2c1Sopenharmony_ci    }
10399596a2c1Sopenharmony_ci}
10409596a2c1Sopenharmony_ci
10419596a2c1Sopenharmony_cinapi_value IntlAddon::GetRelativeTimeResolvedOptions(napi_env env, napi_callback_info info)
10429596a2c1Sopenharmony_ci{
10439596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
10449596a2c1Sopenharmony_ci    void *data = nullptr;
10459596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
10469596a2c1Sopenharmony_ci
10479596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
10489596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
10499596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->relativetimefmt_) {
10509596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetRelativeTimeResolvedOptions: Get RelativeTimeFormat object failed");
10519596a2c1Sopenharmony_ci        return nullptr;
10529596a2c1Sopenharmony_ci    }
10539596a2c1Sopenharmony_ci    napi_value result = nullptr;
10549596a2c1Sopenharmony_ci    napi_create_object(env, &result);
10559596a2c1Sopenharmony_ci    std::map<std::string, std::string> options = {};
10569596a2c1Sopenharmony_ci    obj->relativetimefmt_->GetResolvedOptions(options);
10579596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "locale");
10589596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "style");
10599596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "numeric");
10609596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "numberingSystem");
10619596a2c1Sopenharmony_ci    return result;
10629596a2c1Sopenharmony_ci}
10639596a2c1Sopenharmony_ci
10649596a2c1Sopenharmony_cinapi_value IntlAddon::GetDateTimeResolvedOptions(napi_env env, napi_callback_info info)
10659596a2c1Sopenharmony_ci{
10669596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
10679596a2c1Sopenharmony_ci    void *data = nullptr;
10689596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
10699596a2c1Sopenharmony_ci
10709596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
10719596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
10729596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->datefmt_) {
10739596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetDateTimeResolvedOptions: Get DateTimeFormat object failed");
10749596a2c1Sopenharmony_ci        return nullptr;
10759596a2c1Sopenharmony_ci    }
10769596a2c1Sopenharmony_ci    napi_value result = nullptr;
10779596a2c1Sopenharmony_ci    napi_create_object(env, &result);
10789596a2c1Sopenharmony_ci    std::map<std::string, std::string> options = {};
10799596a2c1Sopenharmony_ci    obj->datefmt_->GetResolvedOptions(options);
10809596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "locale");
10819596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "calendar");
10829596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "dateStyle");
10839596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "timeStyle");
10849596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "hourCycle");
10859596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "timeZone");
10869596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "timeZoneName");
10879596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "numberingSystem");
10889596a2c1Sopenharmony_ci    SetBooleanOptionProperties(env, result, options, "hour12");
10899596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "weekday");
10909596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "era");
10919596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "year");
10929596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "month");
10939596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "day");
10949596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "hour");
10959596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "minute");
10969596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "second");
10979596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "dayPeriod");
10989596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "localeMatcher");
10999596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "formatMatcher");
11009596a2c1Sopenharmony_ci    return result;
11019596a2c1Sopenharmony_ci}
11029596a2c1Sopenharmony_ci
11039596a2c1Sopenharmony_cinapi_value IntlAddon::GetNumberResolvedOptions(napi_env env, napi_callback_info info)
11049596a2c1Sopenharmony_ci{
11059596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
11069596a2c1Sopenharmony_ci    void *data = nullptr;
11079596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
11089596a2c1Sopenharmony_ci
11099596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
11109596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
11119596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->numberfmt_) {
11129596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetNumberResolvedOptions: Get NumberFormat object failed");
11139596a2c1Sopenharmony_ci        return nullptr;
11149596a2c1Sopenharmony_ci    }
11159596a2c1Sopenharmony_ci    napi_value result = nullptr;
11169596a2c1Sopenharmony_ci    napi_create_object(env, &result);
11179596a2c1Sopenharmony_ci    std::map<std::string, std::string> options = {};
11189596a2c1Sopenharmony_ci    obj->numberfmt_->GetResolvedOptions(options);
11199596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "locale");
11209596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "currency");
11219596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "currencySign");
11229596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "currencyDisplay");
11239596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "unit");
11249596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "unitDisplay");
11259596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "signDisplay");
11269596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "compactDisplay");
11279596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "notation");
11289596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "style");
11299596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "numberingSystem");
11309596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "unitUsage");
11319596a2c1Sopenharmony_ci    SetBooleanOptionProperties(env, result, options, "useGrouping");
11329596a2c1Sopenharmony_ci    SetIntegerOptionProperties(env, result, options, "minimumIntegerDigits");
11339596a2c1Sopenharmony_ci    SetIntegerOptionProperties(env, result, options, "minimumFractionDigits");
11349596a2c1Sopenharmony_ci    SetIntegerOptionProperties(env, result, options, "maximumFractionDigits");
11359596a2c1Sopenharmony_ci    SetIntegerOptionProperties(env, result, options, "minimumSignificantDigits");
11369596a2c1Sopenharmony_ci    SetIntegerOptionProperties(env, result, options, "maximumSignificantDigits");
11379596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "localeMatcher");
11389596a2c1Sopenharmony_ci    return result;
11399596a2c1Sopenharmony_ci}
11409596a2c1Sopenharmony_ci
11419596a2c1Sopenharmony_cinapi_value IntlAddon::FormatNumber(napi_env env, napi_callback_info info)
11429596a2c1Sopenharmony_ci{
11439596a2c1Sopenharmony_ci    size_t argc = 1;
11449596a2c1Sopenharmony_ci    napi_value argv[1] = { 0 };
11459596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
11469596a2c1Sopenharmony_ci    void *data = nullptr;
11479596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
11489596a2c1Sopenharmony_ci    double number = 0;
11499596a2c1Sopenharmony_ci    napi_get_value_double(env, argv[0], &number);
11509596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
11519596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
11529596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->numberfmt_) {
11539596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatNumber: Get NumberFormat object failed");
11549596a2c1Sopenharmony_ci        return nullptr;
11559596a2c1Sopenharmony_ci    }
11569596a2c1Sopenharmony_ci    std::string value = obj->numberfmt_->Format(number);
11579596a2c1Sopenharmony_ci    napi_value result = nullptr;
11589596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
11599596a2c1Sopenharmony_ci    if (status != napi_ok) {
11609596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatNumber: Create format string failed");
11619596a2c1Sopenharmony_ci        return nullptr;
11629596a2c1Sopenharmony_ci    }
11639596a2c1Sopenharmony_ci    return result;
11649596a2c1Sopenharmony_ci}
11659596a2c1Sopenharmony_ci
11669596a2c1Sopenharmony_civoid GetCollatorLocaleMatcher(napi_env env, napi_value options, std::map<std::string, std::string> &map)
11679596a2c1Sopenharmony_ci{
11689596a2c1Sopenharmony_ci    GetOptionValue(env, options, "localeMatcher", map);
11699596a2c1Sopenharmony_ci    auto it = map.find("localeMatcher");
11709596a2c1Sopenharmony_ci    if (it != map.end()) {
11719596a2c1Sopenharmony_ci        std::string localeMatcher = it->second;
11729596a2c1Sopenharmony_ci        if (localeMatcher != "lookup" && localeMatcher != "best fit") {
11739596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid localeMatcher");
11749596a2c1Sopenharmony_ci            return;
11759596a2c1Sopenharmony_ci        }
11769596a2c1Sopenharmony_ci    } else {
11779596a2c1Sopenharmony_ci        map.insert(std::make_pair("localeMatcher", "best fit"));
11789596a2c1Sopenharmony_ci    }
11799596a2c1Sopenharmony_ci}
11809596a2c1Sopenharmony_ci
11819596a2c1Sopenharmony_civoid GetCollatorUsage(napi_env env, napi_value options, std::map<std::string, std::string> &map)
11829596a2c1Sopenharmony_ci{
11839596a2c1Sopenharmony_ci    GetOptionValue(env, options, "usage", map);
11849596a2c1Sopenharmony_ci    auto it = map.find("usage");
11859596a2c1Sopenharmony_ci    if (it != map.end()) {
11869596a2c1Sopenharmony_ci        std::string usage = it->second;
11879596a2c1Sopenharmony_ci        if (usage != "sort" && usage != "search") {
11889596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid usage");
11899596a2c1Sopenharmony_ci            return;
11909596a2c1Sopenharmony_ci        }
11919596a2c1Sopenharmony_ci    } else {
11929596a2c1Sopenharmony_ci        map.insert(std::make_pair("usage", "sort"));
11939596a2c1Sopenharmony_ci    }
11949596a2c1Sopenharmony_ci}
11959596a2c1Sopenharmony_ci
11969596a2c1Sopenharmony_civoid GetCollatorSensitivity(napi_env env, napi_value options, std::map<std::string, std::string> &map)
11979596a2c1Sopenharmony_ci{
11989596a2c1Sopenharmony_ci    GetOptionValue(env, options, "sensitivity", map);
11999596a2c1Sopenharmony_ci    auto it = map.find("sensitivity");
12009596a2c1Sopenharmony_ci    if (it != map.end()) {
12019596a2c1Sopenharmony_ci        std::string sensitivity = it->second;
12029596a2c1Sopenharmony_ci        if (sensitivity != "base" && sensitivity != "accent" && sensitivity != "case" && sensitivity != "variant") {
12039596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid sensitivity");
12049596a2c1Sopenharmony_ci            return;
12059596a2c1Sopenharmony_ci        }
12069596a2c1Sopenharmony_ci    } else {
12079596a2c1Sopenharmony_ci        map.insert(std::make_pair("sensitivity", "variant"));
12089596a2c1Sopenharmony_ci    }
12099596a2c1Sopenharmony_ci}
12109596a2c1Sopenharmony_ci
12119596a2c1Sopenharmony_civoid GetCollatorIgnorePunctuation(napi_env env, napi_value options, std::map<std::string, std::string> &map)
12129596a2c1Sopenharmony_ci{
12139596a2c1Sopenharmony_ci    GetBoolOptionValue(env, options, "ignorePunctuation", map);
12149596a2c1Sopenharmony_ci    auto it = map.find("ignorePunctuation");
12159596a2c1Sopenharmony_ci    if (it != map.end()) {
12169596a2c1Sopenharmony_ci        std::string ignorePunctuation = it->second;
12179596a2c1Sopenharmony_ci        if (ignorePunctuation != "true" && ignorePunctuation != "false") {
12189596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid ignorePunctuation");
12199596a2c1Sopenharmony_ci            return;
12209596a2c1Sopenharmony_ci        }
12219596a2c1Sopenharmony_ci    } else {
12229596a2c1Sopenharmony_ci        map.insert(std::make_pair("ignorePunctuation", "false"));
12239596a2c1Sopenharmony_ci    }
12249596a2c1Sopenharmony_ci}
12259596a2c1Sopenharmony_ci
12269596a2c1Sopenharmony_civoid GetCollatorNumeric(napi_env env, napi_value options, std::map<std::string, std::string> &map)
12279596a2c1Sopenharmony_ci{
12289596a2c1Sopenharmony_ci    GetBoolOptionValue(env, options, "numeric", map);
12299596a2c1Sopenharmony_ci    auto it = map.find("numeric");
12309596a2c1Sopenharmony_ci    if (it != map.end()) {
12319596a2c1Sopenharmony_ci        std::string numeric = it->second;
12329596a2c1Sopenharmony_ci        if (numeric != "true" && numeric != "false") {
12339596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid numeric");
12349596a2c1Sopenharmony_ci            return;
12359596a2c1Sopenharmony_ci        }
12369596a2c1Sopenharmony_ci    }
12379596a2c1Sopenharmony_ci}
12389596a2c1Sopenharmony_ci
12399596a2c1Sopenharmony_civoid GetCollatorCaseFirst(napi_env env, napi_value options, std::map<std::string, std::string> &map)
12409596a2c1Sopenharmony_ci{
12419596a2c1Sopenharmony_ci    GetOptionValue(env, options, "caseFirst", map);
12429596a2c1Sopenharmony_ci    auto it = map.find("caseFirst");
12439596a2c1Sopenharmony_ci    if (it != map.end()) {
12449596a2c1Sopenharmony_ci        std::string caseFirst = it->second;
12459596a2c1Sopenharmony_ci        if (caseFirst != "upper" && caseFirst != "lower" && caseFirst != "false") {
12469596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid caseFirst");
12479596a2c1Sopenharmony_ci            return;
12489596a2c1Sopenharmony_ci        }
12499596a2c1Sopenharmony_ci    }
12509596a2c1Sopenharmony_ci}
12519596a2c1Sopenharmony_ci
12529596a2c1Sopenharmony_civoid GetCollatorCollation(napi_env env, napi_value options, std::map<std::string, std::string> &map)
12539596a2c1Sopenharmony_ci{
12549596a2c1Sopenharmony_ci    GetOptionValue(env, options, "collation", map);
12559596a2c1Sopenharmony_ci    auto it = map.find("collation");
12569596a2c1Sopenharmony_ci    if (it != map.end()) {
12579596a2c1Sopenharmony_ci        std::string collation = it->second;
12589596a2c1Sopenharmony_ci        std::set<std::string> validCollation;
12599596a2c1Sopenharmony_ci        validCollation.insert("big5han");
12609596a2c1Sopenharmony_ci        validCollation.insert("compat");
12619596a2c1Sopenharmony_ci        validCollation.insert("dict");
12629596a2c1Sopenharmony_ci        validCollation.insert("direct");
12639596a2c1Sopenharmony_ci        validCollation.insert("ducet");
12649596a2c1Sopenharmony_ci        validCollation.insert("eor");
12659596a2c1Sopenharmony_ci        validCollation.insert("gb2312");
12669596a2c1Sopenharmony_ci        validCollation.insert("phonebk");
12679596a2c1Sopenharmony_ci        validCollation.insert("phonetic");
12689596a2c1Sopenharmony_ci        validCollation.insert("pinyin");
12699596a2c1Sopenharmony_ci        validCollation.insert("reformed");
12709596a2c1Sopenharmony_ci        validCollation.insert("searchjl");
12719596a2c1Sopenharmony_ci        validCollation.insert("stroke");
12729596a2c1Sopenharmony_ci        validCollation.insert("trad");
12739596a2c1Sopenharmony_ci        validCollation.insert("unihan");
12749596a2c1Sopenharmony_ci        validCollation.insert("zhuyin");
12759596a2c1Sopenharmony_ci        if (validCollation.find(collation) == validCollation.end()) {
12769596a2c1Sopenharmony_ci            map["collation"] = "default";
12779596a2c1Sopenharmony_ci        }
12789596a2c1Sopenharmony_ci    }
12799596a2c1Sopenharmony_ci}
12809596a2c1Sopenharmony_ci
12819596a2c1Sopenharmony_civoid GetCollatorOptionValue(napi_env env, napi_value options, std::map<std::string, std::string> &map)
12829596a2c1Sopenharmony_ci{
12839596a2c1Sopenharmony_ci    GetCollatorLocaleMatcher(env, options, map);
12849596a2c1Sopenharmony_ci    GetCollatorUsage(env, options, map);
12859596a2c1Sopenharmony_ci    GetCollatorSensitivity(env, options, map);
12869596a2c1Sopenharmony_ci    GetCollatorIgnorePunctuation(env, options, map);
12879596a2c1Sopenharmony_ci    GetCollatorNumeric(env, options, map);
12889596a2c1Sopenharmony_ci    GetCollatorCaseFirst(env, options, map);
12899596a2c1Sopenharmony_ci    GetCollatorCollation(env, options, map);
12909596a2c1Sopenharmony_ci}
12919596a2c1Sopenharmony_ci
12929596a2c1Sopenharmony_cinapi_value IntlAddon::InitCollator(napi_env env, napi_value exports)
12939596a2c1Sopenharmony_ci{
12949596a2c1Sopenharmony_ci    napi_status status = napi_ok;
12959596a2c1Sopenharmony_ci    napi_property_descriptor properties[] = {
12969596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("compare", CompareString),
12979596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("resolvedOptions", GetCollatorResolvedOptions)
12989596a2c1Sopenharmony_ci    };
12999596a2c1Sopenharmony_ci
13009596a2c1Sopenharmony_ci    napi_value constructor;
13019596a2c1Sopenharmony_ci    status = napi_define_class(env, "Collator", NAPI_AUTO_LENGTH, CollatorConstructor, nullptr,
13029596a2c1Sopenharmony_ci        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
13039596a2c1Sopenharmony_ci    if (status != napi_ok) {
13049596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Define class failed when InitCollator");
13059596a2c1Sopenharmony_ci        return nullptr;
13069596a2c1Sopenharmony_ci    }
13079596a2c1Sopenharmony_ci
13089596a2c1Sopenharmony_ci    status = napi_set_named_property(env, exports, "Collator", constructor);
13099596a2c1Sopenharmony_ci    if (status != napi_ok) {
13109596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Set property failed when InitCollator");
13119596a2c1Sopenharmony_ci        return nullptr;
13129596a2c1Sopenharmony_ci    }
13139596a2c1Sopenharmony_ci    return exports;
13149596a2c1Sopenharmony_ci}
13159596a2c1Sopenharmony_ci
13169596a2c1Sopenharmony_cinapi_value IntlAddon::CollatorConstructor(napi_env env, napi_callback_info info)
13179596a2c1Sopenharmony_ci{
13189596a2c1Sopenharmony_ci    size_t argc = 2;
13199596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
13209596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
13219596a2c1Sopenharmony_ci    void *data = nullptr;
13229596a2c1Sopenharmony_ci    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
13239596a2c1Sopenharmony_ci    if (status != napi_ok) {
13249596a2c1Sopenharmony_ci        return nullptr;
13259596a2c1Sopenharmony_ci    }
13269596a2c1Sopenharmony_ci    std::vector<std::string> localeTags;
13279596a2c1Sopenharmony_ci    if (argc > 0) {
13289596a2c1Sopenharmony_ci        napi_valuetype valueType = napi_valuetype::napi_undefined;
13299596a2c1Sopenharmony_ci        napi_typeof(env, argv[0], &valueType);
13309596a2c1Sopenharmony_ci        bool isArray = false;
13319596a2c1Sopenharmony_ci        napi_is_array(env, argv[0], &isArray);
13329596a2c1Sopenharmony_ci        if (valueType == napi_valuetype::napi_string) {
13339596a2c1Sopenharmony_ci            GetLocaleTags(env, argv[0], localeTags);
13349596a2c1Sopenharmony_ci        } else if (isArray) {
13359596a2c1Sopenharmony_ci            uint32_t arrayLength = 0;
13369596a2c1Sopenharmony_ci            napi_get_array_length(env, argv[0], &arrayLength);
13379596a2c1Sopenharmony_ci            napi_value element = nullptr;
13389596a2c1Sopenharmony_ci            for (uint32_t i = 0; i < arrayLength; i++) {
13399596a2c1Sopenharmony_ci                napi_get_element(env, argv[0], i, &element);
13409596a2c1Sopenharmony_ci                GetLocaleTags(env, element, localeTags);
13419596a2c1Sopenharmony_ci            }
13429596a2c1Sopenharmony_ci        }
13439596a2c1Sopenharmony_ci    }
13449596a2c1Sopenharmony_ci    std::map<std::string, std::string> map = {};
13459596a2c1Sopenharmony_ci    if (argc > 1) {
13469596a2c1Sopenharmony_ci        GetCollatorOptionValue(env, argv[1], map);
13479596a2c1Sopenharmony_ci    }
13489596a2c1Sopenharmony_ci    std::unique_ptr<IntlAddon> obj = nullptr;
13499596a2c1Sopenharmony_ci    obj = std::make_unique<IntlAddon>();
13509596a2c1Sopenharmony_ci    status =
13519596a2c1Sopenharmony_ci        napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), IntlAddon::Destructor, nullptr, nullptr);
13529596a2c1Sopenharmony_ci    if (status != napi_ok) {
13539596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("CollatorConstructor: Wrap IntlAddon failed");
13549596a2c1Sopenharmony_ci        return nullptr;
13559596a2c1Sopenharmony_ci    }
13569596a2c1Sopenharmony_ci    if (!obj->InitCollatorContext(env, info, localeTags, map)) {
13579596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("CollatorConstructor: Init DateTimeFormat failed");
13589596a2c1Sopenharmony_ci        return nullptr;
13599596a2c1Sopenharmony_ci    }
13609596a2c1Sopenharmony_ci    obj.release();
13619596a2c1Sopenharmony_ci    return thisVar;
13629596a2c1Sopenharmony_ci}
13639596a2c1Sopenharmony_ci
13649596a2c1Sopenharmony_cibool IntlAddon::InitCollatorContext(napi_env env, napi_callback_info info, std::vector<std::string> localeTags,
13659596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
13669596a2c1Sopenharmony_ci{
13679596a2c1Sopenharmony_ci    napi_value global = nullptr;
13689596a2c1Sopenharmony_ci    napi_status status = napi_get_global(env, &global);
13699596a2c1Sopenharmony_ci    if (status != napi_ok) {
13709596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("InitCollatorContext: Get global failed");
13719596a2c1Sopenharmony_ci        return false;
13729596a2c1Sopenharmony_ci    }
13739596a2c1Sopenharmony_ci    env_ = env;
13749596a2c1Sopenharmony_ci    collator_ = std::make_unique<Collator>(localeTags, map);
13759596a2c1Sopenharmony_ci
13769596a2c1Sopenharmony_ci    return collator_ != nullptr;
13779596a2c1Sopenharmony_ci}
13789596a2c1Sopenharmony_ci
13799596a2c1Sopenharmony_cibool GetStringParameter(napi_env env, napi_value value, std::vector<char> &buf)
13809596a2c1Sopenharmony_ci{
13819596a2c1Sopenharmony_ci    napi_valuetype valueType = napi_valuetype::napi_undefined;
13829596a2c1Sopenharmony_ci    napi_typeof(env, value, &valueType);
13839596a2c1Sopenharmony_ci    if (valueType != napi_valuetype::napi_string) {
13849596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Parameter type does not match");
13859596a2c1Sopenharmony_ci        return false;
13869596a2c1Sopenharmony_ci    }
13879596a2c1Sopenharmony_ci    size_t len = 0;
13889596a2c1Sopenharmony_ci    napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
13899596a2c1Sopenharmony_ci    if (status != napi_ok) {
13909596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get first length failed");
13919596a2c1Sopenharmony_ci        return false;
13929596a2c1Sopenharmony_ci    }
13939596a2c1Sopenharmony_ci    buf.resize(len + 1);
13949596a2c1Sopenharmony_ci    status = napi_get_value_string_utf8(env, value, buf.data(), len + 1, &len);
13959596a2c1Sopenharmony_ci    if (status != napi_ok) {
13969596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get first failed");
13979596a2c1Sopenharmony_ci        return false;
13989596a2c1Sopenharmony_ci    }
13999596a2c1Sopenharmony_ci
14009596a2c1Sopenharmony_ci    return true;
14019596a2c1Sopenharmony_ci}
14029596a2c1Sopenharmony_ci
14039596a2c1Sopenharmony_cinapi_value IntlAddon::FormatRelativeTime(napi_env env, napi_callback_info info)
14049596a2c1Sopenharmony_ci{
14059596a2c1Sopenharmony_ci    size_t argc = 2;
14069596a2c1Sopenharmony_ci    napi_value argv[2] = { 0 };
14079596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
14089596a2c1Sopenharmony_ci    void *data = nullptr;
14099596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
14109596a2c1Sopenharmony_ci    napi_status status;
14119596a2c1Sopenharmony_ci    double number;
14129596a2c1Sopenharmony_ci    status = napi_get_value_double(env, argv[0], &number);
14139596a2c1Sopenharmony_ci    if (status != napi_ok) {
14149596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatRelativeTime: Get number failed");
14159596a2c1Sopenharmony_ci        return nullptr;
14169596a2c1Sopenharmony_ci    }
14179596a2c1Sopenharmony_ci    std::vector<char> unit;
14189596a2c1Sopenharmony_ci    if (!GetStringParameter(env, argv[1], unit)) {
14199596a2c1Sopenharmony_ci        return nullptr;
14209596a2c1Sopenharmony_ci    }
14219596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
14229596a2c1Sopenharmony_ci    status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
14239596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->relativetimefmt_) {
14249596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatRelativeTime: Get RelativeTimeFormat object failed");
14259596a2c1Sopenharmony_ci        return nullptr;
14269596a2c1Sopenharmony_ci    }
14279596a2c1Sopenharmony_ci    std::string value = obj->relativetimefmt_->Format(number, unit.data());
14289596a2c1Sopenharmony_ci    napi_value result = nullptr;
14299596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
14309596a2c1Sopenharmony_ci    if (status != napi_ok) {
14319596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatRelativeTime: Create format string failed");
14329596a2c1Sopenharmony_ci        return nullptr;
14339596a2c1Sopenharmony_ci    }
14349596a2c1Sopenharmony_ci    return result;
14359596a2c1Sopenharmony_ci}
14369596a2c1Sopenharmony_ci
14379596a2c1Sopenharmony_civoid IntlAddon::FillInArrayElement(napi_env env, napi_value &result, napi_status &status,
14389596a2c1Sopenharmony_ci    const std::vector<std::vector<std::string>> &timeVector)
14399596a2c1Sopenharmony_ci{
14409596a2c1Sopenharmony_ci    for (size_t i = 0; i < timeVector.size(); i++) {
14419596a2c1Sopenharmony_ci        napi_value value = nullptr;
14429596a2c1Sopenharmony_ci        status = napi_create_string_utf8(env, timeVector[i][1].c_str(), NAPI_AUTO_LENGTH, &value);
14439596a2c1Sopenharmony_ci        if (status != napi_ok) {
14449596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("Failed to create string item imeVector[i][1].");
14459596a2c1Sopenharmony_ci            return;
14469596a2c1Sopenharmony_ci        }
14479596a2c1Sopenharmony_ci        napi_value type = nullptr;
14489596a2c1Sopenharmony_ci        status = napi_create_string_utf8(env, timeVector[i][0].c_str(), NAPI_AUTO_LENGTH, &type);
14499596a2c1Sopenharmony_ci        if (status != napi_ok) {
14509596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("Failed to create string item timeVector[i][0].");
14519596a2c1Sopenharmony_ci            return;
14529596a2c1Sopenharmony_ci        }
14539596a2c1Sopenharmony_ci        napi_value unit = nullptr;
14549596a2c1Sopenharmony_ci        size_t unitIndex = 2;
14559596a2c1Sopenharmony_ci        if (timeVector[i].size() > unitIndex) {
14569596a2c1Sopenharmony_ci            status = napi_create_string_utf8(env, timeVector[i][unitIndex].c_str(), NAPI_AUTO_LENGTH, &unit);
14579596a2c1Sopenharmony_ci            if (status != napi_ok) {
14589596a2c1Sopenharmony_ci                HILOG_ERROR_I18N("Failed to create string item timeVector[i][unitIndex].");
14599596a2c1Sopenharmony_ci                return;
14609596a2c1Sopenharmony_ci            }
14619596a2c1Sopenharmony_ci        } else {
14629596a2c1Sopenharmony_ci            napi_get_undefined(env, &unit);
14639596a2c1Sopenharmony_ci        }
14649596a2c1Sopenharmony_ci        napi_value formatInfo;
14659596a2c1Sopenharmony_ci        status = napi_create_object(env, &formatInfo);
14669596a2c1Sopenharmony_ci        if (status != napi_ok) {
14679596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("Failed to create format info object.");
14689596a2c1Sopenharmony_ci            return;
14699596a2c1Sopenharmony_ci        }
14709596a2c1Sopenharmony_ci        napi_set_named_property(env, formatInfo, "type", type);
14719596a2c1Sopenharmony_ci        napi_set_named_property(env, formatInfo, "value", value);
14729596a2c1Sopenharmony_ci        napi_set_named_property(env, formatInfo, "unit", unit);
14739596a2c1Sopenharmony_ci        status = napi_set_element(env, result, i, formatInfo);
14749596a2c1Sopenharmony_ci        if (status != napi_ok) {
14759596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("Failed to set array item");
14769596a2c1Sopenharmony_ci            return;
14779596a2c1Sopenharmony_ci        }
14789596a2c1Sopenharmony_ci    }
14799596a2c1Sopenharmony_ci}
14809596a2c1Sopenharmony_ci
14819596a2c1Sopenharmony_cinapi_value IntlAddon::FormatToParts(napi_env env, napi_callback_info info)
14829596a2c1Sopenharmony_ci{
14839596a2c1Sopenharmony_ci    size_t argc = 2;
14849596a2c1Sopenharmony_ci    napi_value argv[2] = { 0 };
14859596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
14869596a2c1Sopenharmony_ci    void *data = nullptr;
14879596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
14889596a2c1Sopenharmony_ci    double number = 0;
14899596a2c1Sopenharmony_ci    napi_get_value_double(env, argv[0], &number);
14909596a2c1Sopenharmony_ci    std::vector<char> unit;
14919596a2c1Sopenharmony_ci    if (!GetStringParameter(env, argv[1], unit)) {
14929596a2c1Sopenharmony_ci        return nullptr;
14939596a2c1Sopenharmony_ci    }
14949596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
14959596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
14969596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->relativetimefmt_) {
14979596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FormatToParts: Get RelativeTimeFormat object failed");
14989596a2c1Sopenharmony_ci        return nullptr;
14999596a2c1Sopenharmony_ci    }
15009596a2c1Sopenharmony_ci    std::vector<std::vector<std::string>> timeVector;
15019596a2c1Sopenharmony_ci    obj->relativetimefmt_->FormatToParts(number, unit.data(), timeVector);
15029596a2c1Sopenharmony_ci    napi_value result = nullptr;
15039596a2c1Sopenharmony_ci    status = napi_create_array_with_length(env, timeVector.size(), &result);
15049596a2c1Sopenharmony_ci    if (status != napi_ok) {
15059596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Failed to create array");
15069596a2c1Sopenharmony_ci        return nullptr;
15079596a2c1Sopenharmony_ci    }
15089596a2c1Sopenharmony_ci    FillInArrayElement(env, result, status, timeVector);
15099596a2c1Sopenharmony_ci    return result;
15109596a2c1Sopenharmony_ci}
15119596a2c1Sopenharmony_ci
15129596a2c1Sopenharmony_cinapi_value IntlAddon::CompareString(napi_env env, napi_callback_info info)
15139596a2c1Sopenharmony_ci{
15149596a2c1Sopenharmony_ci    size_t argc = 2;
15159596a2c1Sopenharmony_ci    napi_value argv[2] = { 0 };
15169596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
15179596a2c1Sopenharmony_ci    void *data = nullptr;
15189596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
15199596a2c1Sopenharmony_ci
15209596a2c1Sopenharmony_ci    std::vector<char> first;
15219596a2c1Sopenharmony_ci    if (!GetStringParameter(env, argv[0], first)) {
15229596a2c1Sopenharmony_ci        return nullptr;
15239596a2c1Sopenharmony_ci    }
15249596a2c1Sopenharmony_ci
15259596a2c1Sopenharmony_ci    std::vector<char> second;
15269596a2c1Sopenharmony_ci    if (!GetStringParameter(env, argv[1], second)) {
15279596a2c1Sopenharmony_ci        return nullptr;
15289596a2c1Sopenharmony_ci    }
15299596a2c1Sopenharmony_ci
15309596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
15319596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
15329596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->collator_) {
15339596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("CompareString: Get Collator object failed");
15349596a2c1Sopenharmony_ci        return nullptr;
15359596a2c1Sopenharmony_ci    }
15369596a2c1Sopenharmony_ci
15379596a2c1Sopenharmony_ci    CompareResult compareResult = obj->collator_->Compare(first.data(), second.data());
15389596a2c1Sopenharmony_ci    napi_value result = nullptr;
15399596a2c1Sopenharmony_ci    status = napi_create_int32(env, compareResult, &result);
15409596a2c1Sopenharmony_ci    if (status != napi_ok) {
15419596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Create compare result failed");
15429596a2c1Sopenharmony_ci        return nullptr;
15439596a2c1Sopenharmony_ci    }
15449596a2c1Sopenharmony_ci
15459596a2c1Sopenharmony_ci    return result;
15469596a2c1Sopenharmony_ci}
15479596a2c1Sopenharmony_ci
15489596a2c1Sopenharmony_cinapi_value IntlAddon::GetCollatorResolvedOptions(napi_env env, napi_callback_info info)
15499596a2c1Sopenharmony_ci{
15509596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
15519596a2c1Sopenharmony_ci    void *data = nullptr;
15529596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
15539596a2c1Sopenharmony_ci
15549596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
15559596a2c1Sopenharmony_ci    napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
15569596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->collator_) {
15579596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("GetCollatorResolvedOptions: Get Collator object failed");
15589596a2c1Sopenharmony_ci        return nullptr;
15599596a2c1Sopenharmony_ci    }
15609596a2c1Sopenharmony_ci    napi_value result = nullptr;
15619596a2c1Sopenharmony_ci    napi_create_object(env, &result);
15629596a2c1Sopenharmony_ci    std::map<std::string, std::string> options = {};
15639596a2c1Sopenharmony_ci    obj->collator_->ResolvedOptions(options);
15649596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "localeMatcher");
15659596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "locale");
15669596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "usage");
15679596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "sensitivity");
15689596a2c1Sopenharmony_ci    SetBooleanOptionProperties(env, result, options, "ignorePunctuation");
15699596a2c1Sopenharmony_ci    SetBooleanOptionProperties(env, result, options, "numeric");
15709596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "caseFirst");
15719596a2c1Sopenharmony_ci    SetOptionProperties(env, result, options, "collation");
15729596a2c1Sopenharmony_ci    return result;
15739596a2c1Sopenharmony_ci}
15749596a2c1Sopenharmony_ci
15759596a2c1Sopenharmony_civoid GetPluralRulesType(napi_env env, napi_value options, std::map<std::string, std::string> &map)
15769596a2c1Sopenharmony_ci{
15779596a2c1Sopenharmony_ci    GetOptionValue(env, options, "type", map);
15789596a2c1Sopenharmony_ci    auto it = map.find("type");
15799596a2c1Sopenharmony_ci    if (it != map.end()) {
15809596a2c1Sopenharmony_ci        std::string type = it->second;
15819596a2c1Sopenharmony_ci        if (type != "cardinal" && type != "ordinal") {
15829596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid type");
15839596a2c1Sopenharmony_ci            return;
15849596a2c1Sopenharmony_ci        }
15859596a2c1Sopenharmony_ci    } else {
15869596a2c1Sopenharmony_ci        map.insert(std::make_pair("type", "cardinal"));
15879596a2c1Sopenharmony_ci    }
15889596a2c1Sopenharmony_ci}
15899596a2c1Sopenharmony_ci
15909596a2c1Sopenharmony_civoid GetPluralRulesInteger(napi_env env, napi_value options, std::map<std::string, std::string> &map)
15919596a2c1Sopenharmony_ci{
15929596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "minimumIntegerDigits", map);
15939596a2c1Sopenharmony_ci    auto it = map.find("minimumIntegerDigits");
15949596a2c1Sopenharmony_ci    if (it != map.end()) {
15959596a2c1Sopenharmony_ci        std::string minimumIntegerDigits = it->second;
15969596a2c1Sopenharmony_ci        int32_t status = 0;
15979596a2c1Sopenharmony_ci        int n = ConvertString2Int(minimumIntegerDigits, status);
15989596a2c1Sopenharmony_ci        if (status == -1 || n < 1 || n > 21) {  // the valid range of minimumIntegerDigits is [1, 21]
15999596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid minimumIntegerDigits");
16009596a2c1Sopenharmony_ci            return;
16019596a2c1Sopenharmony_ci        }
16029596a2c1Sopenharmony_ci    } else {
16039596a2c1Sopenharmony_ci        map.insert(std::make_pair("minimumIntegerDigits", std::to_string(1)));
16049596a2c1Sopenharmony_ci    }
16059596a2c1Sopenharmony_ci}
16069596a2c1Sopenharmony_ci
16079596a2c1Sopenharmony_civoid GetPluralRulesFractions(napi_env env, napi_value options, std::map<std::string, std::string> &map)
16089596a2c1Sopenharmony_ci{
16099596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "minimumFractionDigits", map);
16109596a2c1Sopenharmony_ci    auto it = map.find("minimumFractionDigits");
16119596a2c1Sopenharmony_ci    if (it != map.end()) {
16129596a2c1Sopenharmony_ci        std::string minimumFractionDigits = it->second;
16139596a2c1Sopenharmony_ci        int32_t status = 0;
16149596a2c1Sopenharmony_ci        int n = ConvertString2Int(minimumFractionDigits, status);
16159596a2c1Sopenharmony_ci        if (status == -1 || n < 0 || n > 20) {  // the valid range of minimumFractionDigits is [0, 20]
16169596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid minimumFractionDigits");
16179596a2c1Sopenharmony_ci            return;
16189596a2c1Sopenharmony_ci        }
16199596a2c1Sopenharmony_ci    }
16209596a2c1Sopenharmony_ci
16219596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "maximumFractionDigits", map);
16229596a2c1Sopenharmony_ci    it = map.find("maximumFractionDigits");
16239596a2c1Sopenharmony_ci    if (it != map.end()) {
16249596a2c1Sopenharmony_ci        std::string maximumFractionDigits = it->second;
16259596a2c1Sopenharmony_ci        int32_t status = 0;
16269596a2c1Sopenharmony_ci        int n = ConvertString2Int(maximumFractionDigits, status);
16279596a2c1Sopenharmony_ci        if (status == -1 || n < 0 || n > 20) {  // the valid range of maximumFractionDigits is [0, 20]
16289596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid maximumFractionDigits");
16299596a2c1Sopenharmony_ci            return;
16309596a2c1Sopenharmony_ci        }
16319596a2c1Sopenharmony_ci    }
16329596a2c1Sopenharmony_ci}
16339596a2c1Sopenharmony_ci
16349596a2c1Sopenharmony_civoid GetPluralRulesSignificant(napi_env env, napi_value options, std::map<std::string, std::string> &map)
16359596a2c1Sopenharmony_ci{
16369596a2c1Sopenharmony_ci    int minSignificant = -1;
16379596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "minimumSignificantDigits", map);
16389596a2c1Sopenharmony_ci    auto it = map.find("minimumSignificantDigits");
16399596a2c1Sopenharmony_ci    if (it != map.end()) {
16409596a2c1Sopenharmony_ci        std::string minSignificantStr = it->second;
16419596a2c1Sopenharmony_ci        int32_t status = 0;
16429596a2c1Sopenharmony_ci        int minSignificantInt = ConvertString2Int(minSignificantStr, status);
16439596a2c1Sopenharmony_ci        // the valid range of minSignificantInt is [1, 21]
16449596a2c1Sopenharmony_ci        if (status == -1 || minSignificantInt < 1 || minSignificantInt > 21) {
16459596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid minimumSignificantDigits");
16469596a2c1Sopenharmony_ci            return;
16479596a2c1Sopenharmony_ci        }
16489596a2c1Sopenharmony_ci        minSignificant = minSignificantInt;
16499596a2c1Sopenharmony_ci    } else {
16509596a2c1Sopenharmony_ci        minSignificant = 1;
16519596a2c1Sopenharmony_ci    }
16529596a2c1Sopenharmony_ci
16539596a2c1Sopenharmony_ci    GetIntegerOptionValue(env, options, "maximumSignificantDigits", map);
16549596a2c1Sopenharmony_ci    it = map.find("maximumSignificantDigits");
16559596a2c1Sopenharmony_ci    if (it != map.end()) {
16569596a2c1Sopenharmony_ci        std::string maxSignificantStr = it->second;
16579596a2c1Sopenharmony_ci        int32_t status = 0;
16589596a2c1Sopenharmony_ci        int maxSignificant = ConvertString2Int(maxSignificantStr, status);
16599596a2c1Sopenharmony_ci        // the valid range of minSignificant is [minSignificant, 21]
16609596a2c1Sopenharmony_ci        if (status == -1 || maxSignificant < minSignificant || maxSignificant > 21) {
16619596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("invalid maximumSignificantDigits");
16629596a2c1Sopenharmony_ci            return;
16639596a2c1Sopenharmony_ci        }
16649596a2c1Sopenharmony_ci    }
16659596a2c1Sopenharmony_ci}
16669596a2c1Sopenharmony_ci
16679596a2c1Sopenharmony_civoid GetPluralRulesOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map)
16689596a2c1Sopenharmony_ci{
16699596a2c1Sopenharmony_ci    GetCollatorLocaleMatcher(env, options, map);
16709596a2c1Sopenharmony_ci    GetPluralRulesType(env, options, map);
16719596a2c1Sopenharmony_ci    GetPluralRulesInteger(env, options, map);
16729596a2c1Sopenharmony_ci    GetPluralRulesFractions(env, options, map);
16739596a2c1Sopenharmony_ci    GetPluralRulesSignificant(env, options, map);
16749596a2c1Sopenharmony_ci}
16759596a2c1Sopenharmony_ci
16769596a2c1Sopenharmony_cinapi_value IntlAddon::InitPluralRules(napi_env env, napi_value exports)
16779596a2c1Sopenharmony_ci{
16789596a2c1Sopenharmony_ci    napi_status status = napi_ok;
16799596a2c1Sopenharmony_ci    napi_property_descriptor properties[] = {
16809596a2c1Sopenharmony_ci        DECLARE_NAPI_FUNCTION("select", Select)
16819596a2c1Sopenharmony_ci    };
16829596a2c1Sopenharmony_ci
16839596a2c1Sopenharmony_ci    napi_value constructor = nullptr;
16849596a2c1Sopenharmony_ci    status = napi_define_class(env, "PluralRules", NAPI_AUTO_LENGTH, PluralRulesConstructor, nullptr,
16859596a2c1Sopenharmony_ci        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
16869596a2c1Sopenharmony_ci    if (status != napi_ok) {
16879596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Define class failed when InitPluralRules");
16889596a2c1Sopenharmony_ci        return nullptr;
16899596a2c1Sopenharmony_ci    }
16909596a2c1Sopenharmony_ci
16919596a2c1Sopenharmony_ci    status = napi_set_named_property(env, exports, "PluralRules", constructor);
16929596a2c1Sopenharmony_ci    if (status != napi_ok) {
16939596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Set property failed when InitPluralRules");
16949596a2c1Sopenharmony_ci        return nullptr;
16959596a2c1Sopenharmony_ci    }
16969596a2c1Sopenharmony_ci    return exports;
16979596a2c1Sopenharmony_ci}
16989596a2c1Sopenharmony_ci
16999596a2c1Sopenharmony_cinapi_value IntlAddon::PluralRulesConstructor(napi_env env, napi_callback_info info)
17009596a2c1Sopenharmony_ci{
17019596a2c1Sopenharmony_ci    size_t argc = 2;
17029596a2c1Sopenharmony_ci    napi_value argv[2] = { nullptr };
17039596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
17049596a2c1Sopenharmony_ci    void *data = nullptr;
17059596a2c1Sopenharmony_ci    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
17069596a2c1Sopenharmony_ci    if (status != napi_ok) {
17079596a2c1Sopenharmony_ci        return nullptr;
17089596a2c1Sopenharmony_ci    }
17099596a2c1Sopenharmony_ci    napi_valuetype valueType = napi_valuetype::napi_undefined;
17109596a2c1Sopenharmony_ci    std::vector<std::string> localeTags;
17119596a2c1Sopenharmony_ci    if (argc > 0) {
17129596a2c1Sopenharmony_ci        napi_typeof(env, argv[0], &valueType);
17139596a2c1Sopenharmony_ci        bool isArray = false;
17149596a2c1Sopenharmony_ci        napi_is_array(env, argv[0], &isArray);
17159596a2c1Sopenharmony_ci        if (valueType == napi_valuetype::napi_string) {
17169596a2c1Sopenharmony_ci            GetLocaleTags(env, argv[0], localeTags);
17179596a2c1Sopenharmony_ci        } else if (isArray) {
17189596a2c1Sopenharmony_ci            uint32_t arrayLength = 0;
17199596a2c1Sopenharmony_ci            napi_get_array_length(env, argv[0], &arrayLength);
17209596a2c1Sopenharmony_ci            napi_value element = nullptr;
17219596a2c1Sopenharmony_ci            for (uint32_t i = 0; i < arrayLength; i++) {
17229596a2c1Sopenharmony_ci                napi_get_element(env, argv[0], i, &element);
17239596a2c1Sopenharmony_ci                GetLocaleTags(env, element, localeTags);
17249596a2c1Sopenharmony_ci            }
17259596a2c1Sopenharmony_ci        }
17269596a2c1Sopenharmony_ci    }
17279596a2c1Sopenharmony_ci    std::map<std::string, std::string> map = {};
17289596a2c1Sopenharmony_ci    if (argc > 1) {
17299596a2c1Sopenharmony_ci        GetPluralRulesOptionValues(env, argv[1], map);
17309596a2c1Sopenharmony_ci    }
17319596a2c1Sopenharmony_ci    std::unique_ptr<IntlAddon> obj = nullptr;
17329596a2c1Sopenharmony_ci    obj = std::make_unique<IntlAddon>();
17339596a2c1Sopenharmony_ci    status =
17349596a2c1Sopenharmony_ci        napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), IntlAddon::Destructor, nullptr, nullptr);
17359596a2c1Sopenharmony_ci    if (status != napi_ok) {
17369596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("PluralRulesConstructor: Wrap IntlAddon failed");
17379596a2c1Sopenharmony_ci        return nullptr;
17389596a2c1Sopenharmony_ci    }
17399596a2c1Sopenharmony_ci    if (!obj->InitPluralRulesContext(env, info, localeTags, map)) {
17409596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("PluralRulesConstructor: Init DateTimeFormat failed");
17419596a2c1Sopenharmony_ci        return nullptr;
17429596a2c1Sopenharmony_ci    }
17439596a2c1Sopenharmony_ci    obj.release();
17449596a2c1Sopenharmony_ci    return thisVar;
17459596a2c1Sopenharmony_ci}
17469596a2c1Sopenharmony_ci
17479596a2c1Sopenharmony_cibool IntlAddon::InitPluralRulesContext(napi_env env, napi_callback_info info, std::vector<std::string> localeTags,
17489596a2c1Sopenharmony_ci    std::map<std::string, std::string> &map)
17499596a2c1Sopenharmony_ci{
17509596a2c1Sopenharmony_ci    napi_value global = nullptr;
17519596a2c1Sopenharmony_ci    napi_status status = napi_get_global(env, &global);
17529596a2c1Sopenharmony_ci    if (status != napi_ok) {
17539596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("InitPluralRulesContext: Get global failed");
17549596a2c1Sopenharmony_ci        return false;
17559596a2c1Sopenharmony_ci    }
17569596a2c1Sopenharmony_ci    env_ = env;
17579596a2c1Sopenharmony_ci    pluralrules_ = std::make_unique<PluralRules>(localeTags, map);
17589596a2c1Sopenharmony_ci
17599596a2c1Sopenharmony_ci    return pluralrules_ != nullptr;
17609596a2c1Sopenharmony_ci}
17619596a2c1Sopenharmony_ci
17629596a2c1Sopenharmony_cinapi_value IntlAddon::Select(napi_env env, napi_callback_info info)
17639596a2c1Sopenharmony_ci{
17649596a2c1Sopenharmony_ci    size_t argc = 1;
17659596a2c1Sopenharmony_ci    napi_value argv[1] = { 0 };
17669596a2c1Sopenharmony_ci    napi_value thisVar = nullptr;
17679596a2c1Sopenharmony_ci    void *data = nullptr;
17689596a2c1Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
17699596a2c1Sopenharmony_ci    napi_valuetype valueType = napi_valuetype::napi_undefined;
17709596a2c1Sopenharmony_ci    napi_typeof(env, argv[0], &valueType);
17719596a2c1Sopenharmony_ci    if (valueType != napi_valuetype::napi_number) {
17729596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Select: Parameter type does not match");
17739596a2c1Sopenharmony_ci        return nullptr;
17749596a2c1Sopenharmony_ci    }
17759596a2c1Sopenharmony_ci
17769596a2c1Sopenharmony_ci    double number = 0;
17779596a2c1Sopenharmony_ci    napi_status status = napi_get_value_double(env, argv[0], &number);
17789596a2c1Sopenharmony_ci    if (status != napi_ok) {
17799596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Select: Get number failed");
17809596a2c1Sopenharmony_ci        return nullptr;
17819596a2c1Sopenharmony_ci    }
17829596a2c1Sopenharmony_ci
17839596a2c1Sopenharmony_ci    IntlAddon *obj = nullptr;
17849596a2c1Sopenharmony_ci    status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
17859596a2c1Sopenharmony_ci    if (status != napi_ok || !obj || !obj->pluralrules_) {
17869596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("Get PluralRules object failed");
17879596a2c1Sopenharmony_ci        return nullptr;
17889596a2c1Sopenharmony_ci    }
17899596a2c1Sopenharmony_ci
17909596a2c1Sopenharmony_ci    std::string res = obj->pluralrules_->Select(number);
17919596a2c1Sopenharmony_ci    napi_value result = nullptr;
17929596a2c1Sopenharmony_ci    status = napi_create_string_utf8(env, res.c_str(), NAPI_AUTO_LENGTH, &result);
17939596a2c1Sopenharmony_ci    if (status != napi_ok) {
17949596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("get select result failed");
17959596a2c1Sopenharmony_ci        return nullptr;
17969596a2c1Sopenharmony_ci    }
17979596a2c1Sopenharmony_ci    return result;
17989596a2c1Sopenharmony_ci}
17999596a2c1Sopenharmony_ci
18009596a2c1Sopenharmony_cinapi_value Init(napi_env env, napi_value exports)
18019596a2c1Sopenharmony_ci{
18029596a2c1Sopenharmony_ci    napi_value val = IntlAddon::InitLocale(env, exports);
18039596a2c1Sopenharmony_ci    val = IntlAddon::InitDateTimeFormat(env, val);
18049596a2c1Sopenharmony_ci    val = IntlAddon::InitNumberFormat(env, val);
18059596a2c1Sopenharmony_ci    val = IntlAddon::InitCollator(env, val);
18069596a2c1Sopenharmony_ci    val = IntlAddon::InitRelativeTimeFormat(env, val);
18079596a2c1Sopenharmony_ci    return IntlAddon::InitPluralRules(env, val);
18089596a2c1Sopenharmony_ci}
18099596a2c1Sopenharmony_ci
18109596a2c1Sopenharmony_cistatic napi_module g_intlModule = {
18119596a2c1Sopenharmony_ci    .nm_version = 1,
18129596a2c1Sopenharmony_ci    .nm_flags = 0,
18139596a2c1Sopenharmony_ci    .nm_filename = nullptr,
18149596a2c1Sopenharmony_ci    .nm_register_func = Init,
18159596a2c1Sopenharmony_ci    .nm_modname = "intl",
18169596a2c1Sopenharmony_ci    .nm_priv = nullptr,
18179596a2c1Sopenharmony_ci    .reserved = { 0 }
18189596a2c1Sopenharmony_ci};
18199596a2c1Sopenharmony_ci
18209596a2c1Sopenharmony_ciextern "C" __attribute__((constructor)) void AbilityRegister()
18219596a2c1Sopenharmony_ci{
18229596a2c1Sopenharmony_ci    napi_module_register(&g_intlModule);
18239596a2c1Sopenharmony_ci}
18249596a2c1Sopenharmony_ci} // namespace I18n
18259596a2c1Sopenharmony_ci} // namespace Global
18269596a2c1Sopenharmony_ci} // namespace OHOS
1827