mirror of
https://gitee.com/openharmony/global_i18n
synced 2024-11-27 09:11:40 +00:00
add phone number format to i18n
Signed-off-by: sunyaozu <sunyaozu@huawei.com>
This commit is contained in:
parent
c535838f89
commit
6abad5a4e6
@ -19,6 +19,8 @@ config("intl_config") {
|
||||
"//third_party/icu/icu4c/source/common",
|
||||
"//third_party/icu/icu4c/source/i18n",
|
||||
"//base/global/i18n_standard/frameworks/intl/include",
|
||||
"//third_party/libphonenumber/cpp/src",
|
||||
"//third_party/protobuf/src",
|
||||
]
|
||||
}
|
||||
ohos_shared_library("intl_util") {
|
||||
@ -39,12 +41,16 @@ ohos_shared_library("intl_util") {
|
||||
"//base/telephony/core_service/interfaces/kits/include",
|
||||
"//utils/native/base/include",
|
||||
"//third_party/libxml2/include",
|
||||
"//third_party/libphonenumber/cpp/src",
|
||||
"//third_party/libphonenumber",
|
||||
"//third_party/protobuf/src",
|
||||
]
|
||||
sources = [
|
||||
"src/date_time_format.cpp",
|
||||
"src/locale_config.cpp",
|
||||
"src/locale_info.cpp",
|
||||
"src/number_format.cpp",
|
||||
"src/phone_number_format.cpp",
|
||||
]
|
||||
cflags_cc = [
|
||||
"-Wall",
|
||||
@ -58,6 +64,7 @@ ohos_shared_library("intl_util") {
|
||||
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
|
||||
"//third_party/icu/icu4c:shared_icui18n",
|
||||
"//third_party/icu/icu4c:shared_icuuc",
|
||||
"//third_party/libphonenumber/cpp:phonenumber_standard",
|
||||
"//third_party/libxml2:xml2",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
44
frameworks/intl/include/phone_number_format.h
Normal file
44
frameworks/intl/include/phone_number_format.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_GLOBAL_I18N_PHONE_NUMBER_FORMAT_H
|
||||
#define OHOS_GLOBAL_I18N_PHONE_NUMBER_FORMAT_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "cpp/src/phonenumbers/phonenumberutil.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
using i18n::phonenumbers::PhoneNumberUtil;
|
||||
|
||||
class PhoneNumberFormat {
|
||||
public:
|
||||
PhoneNumberFormat(const std::string &countryTag, const std::map<std::string, std::string> &options);
|
||||
virtual ~PhoneNumberFormat();
|
||||
bool isValidPhoneNumber(const std::string &number) const;
|
||||
std::string format(const std::string &number) const;
|
||||
|
||||
private:
|
||||
PhoneNumberUtil *util;
|
||||
std::string country;
|
||||
PhoneNumberUtil::PhoneNumberFormat phoneNumberFormat;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OHOS_GLOBAL_I18N_PHONE_NUMBER_FORMAT_H
|
77
frameworks/intl/src/phone_number_format.cpp
Normal file
77
frameworks/intl/src/phone_number_format.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "phone_number_format.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
using i18n::phonenumbers::PhoneNumberUtil;
|
||||
|
||||
PhoneNumberFormat::PhoneNumberFormat(const std::string &countryTag,
|
||||
const std::map<std::string, std::string> &options)
|
||||
{
|
||||
util = PhoneNumberUtil::GetInstance();
|
||||
country = countryTag;
|
||||
|
||||
std::string type = "";
|
||||
auto search = options.find("type");
|
||||
if (search != options.end()) {
|
||||
type = search->second;
|
||||
}
|
||||
|
||||
std::map<std::string, PhoneNumberUtil::PhoneNumberFormat> type2PhoneNumberFormat = {
|
||||
{"E164", PhoneNumberUtil::PhoneNumberFormat::E164},
|
||||
{"RFC3966", PhoneNumberUtil::PhoneNumberFormat::RFC3966},
|
||||
{"INTERNATIONAL", PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL},
|
||||
{"NATIONAL", PhoneNumberUtil::PhoneNumberFormat::NATIONAL}
|
||||
};
|
||||
|
||||
std::set<std::string> validType = {"E164", "RFC3966", "INTERNATIONAL", "NATIONAL"};
|
||||
if (validType.find(type) != validType.end()) {
|
||||
phoneNumberFormat = type2PhoneNumberFormat[type];
|
||||
} else {
|
||||
phoneNumberFormat = PhoneNumberUtil::PhoneNumberFormat::NATIONAL;
|
||||
}
|
||||
}
|
||||
|
||||
PhoneNumberFormat::~PhoneNumberFormat()
|
||||
{
|
||||
}
|
||||
|
||||
bool PhoneNumberFormat::isValidPhoneNumber(const std::string &number) const
|
||||
{
|
||||
i18n::phonenumbers::PhoneNumber phoneNumber;
|
||||
PhoneNumberUtil::ErrorType type = util->Parse(number, country, &phoneNumber);
|
||||
if (type != PhoneNumberUtil::ErrorType::NO_PARSING_ERROR) {
|
||||
return false;
|
||||
}
|
||||
return util->IsValidNumber(phoneNumber);
|
||||
}
|
||||
|
||||
std::string PhoneNumberFormat::format(const std::string &number) const
|
||||
{
|
||||
i18n::phonenumbers::PhoneNumber phoneNumber;
|
||||
PhoneNumberUtil::ErrorType type = util->Parse(number, country, &phoneNumber);
|
||||
if (type != PhoneNumberUtil::ErrorType::NO_PARSING_ERROR) {
|
||||
return "";
|
||||
}
|
||||
std::string formatted_number;
|
||||
util->Format(phoneNumber, phoneNumberFormat, &formatted_number);
|
||||
return formatted_number;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,9 @@ ohos_shared_library("intl") {
|
||||
"//third_party/icu/icu4c/source",
|
||||
"//third_party/icu/icu4c/source/common",
|
||||
"//third_party/icu/icu4c/source/i18n",
|
||||
"//third_party/libphonenumber/cpp/src",
|
||||
"//third_party/libphonenumber",
|
||||
"//third_party/protobuf/src",
|
||||
]
|
||||
|
||||
sources = [ "src/intl_addon.cpp" ]
|
||||
@ -33,6 +36,7 @@ ohos_shared_library("intl") {
|
||||
"//foundation/ace/napi:ace_napi",
|
||||
"//third_party/icu/icu4c:shared_icui18n",
|
||||
"//third_party/icu/icu4c:shared_icuuc",
|
||||
"//third_party/libphonenumber/cpp:phonenumber_standard",
|
||||
]
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
relative_install_dir = "module"
|
||||
@ -51,6 +55,9 @@ ohos_shared_library("i18n") {
|
||||
"//third_party/icu/icu4c/source",
|
||||
"//third_party/icu/icu4c/source/common",
|
||||
"//third_party/icu/icu4c/source/i18n",
|
||||
"//third_party/libphonenumber/cpp/src",
|
||||
"//third_party/libphonenumber",
|
||||
"//third_party/protobuf/src",
|
||||
]
|
||||
|
||||
sources = [ "src/i18n_addon.cpp" ]
|
||||
@ -60,10 +67,10 @@ ohos_shared_library("i18n") {
|
||||
"//foundation/ace/napi:ace_napi",
|
||||
"//third_party/icu/icu4c:shared_icui18n",
|
||||
"//third_party/icu/icu4c:shared_icuuc",
|
||||
"//third_party/libphonenumber/cpp:phonenumber_standard",
|
||||
]
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
relative_install_dir = "module"
|
||||
subsystem_name = "global"
|
||||
part_name = "i18n_standard"
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "locale_config.h"
|
||||
#include "phone_number_format.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
@ -40,6 +41,18 @@ public:
|
||||
static napi_value SetSystemLanguage(napi_env env, napi_callback_info info);
|
||||
static napi_value SetSystemRegion(napi_env env, napi_callback_info info);
|
||||
static napi_value SetSystemLocale(napi_env env, napi_callback_info info);
|
||||
static napi_value InitPhoneNumberFormat(napi_env env, napi_value exports);
|
||||
|
||||
private:
|
||||
static napi_value PhoneNumberFormatConstructor(napi_env env, napi_callback_info info);
|
||||
static napi_value IsValidPhoneNumber(napi_env env, napi_callback_info info);
|
||||
static napi_value FormatPhoneNumber(napi_env env, napi_callback_info info);
|
||||
bool InitPhoneNumberFormatContext(napi_env env, napi_callback_info info, const std::string &country,
|
||||
const std::map<std::string, std::string> &options);
|
||||
|
||||
napi_env env_;
|
||||
napi_ref wrapper_;
|
||||
std::unique_ptr<PhoneNumberFormat> phonenumberfmt_;
|
||||
};
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
|
@ -23,10 +23,11 @@ namespace I18n {
|
||||
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "I18nJs" };
|
||||
using namespace OHOS::HiviewDFX;
|
||||
|
||||
I18nAddon::I18nAddon() {}
|
||||
I18nAddon::I18nAddon() : env_(nullptr), wrapper_(nullptr) {}
|
||||
|
||||
I18nAddon::~I18nAddon()
|
||||
{
|
||||
napi_delete_reference(env_, wrapper_);
|
||||
}
|
||||
|
||||
void I18nAddon::Destructor(napi_env env, void *nativeObject, void *hint)
|
||||
@ -55,7 +56,8 @@ napi_value I18nAddon::Init(napi_env env, napi_value exports)
|
||||
};
|
||||
|
||||
status = napi_define_properties(env, exports,
|
||||
sizeof(properties) / sizeof(napi_property_descriptor), properties);
|
||||
sizeof(properties) / sizeof(napi_property_descriptor),
|
||||
properties);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to set properties at init");
|
||||
return nullptr;
|
||||
@ -354,9 +356,219 @@ napi_value I18nAddon::SetSystemLocale(napi_env env, napi_callback_info info)
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value I18nAddon::InitPhoneNumberFormat(napi_env env, napi_value exports)
|
||||
{
|
||||
napi_status status;
|
||||
napi_property_descriptor properties[] = {
|
||||
DECLARE_NAPI_FUNCTION("isValidNumber", IsValidPhoneNumber),
|
||||
DECLARE_NAPI_FUNCTION("format", FormatPhoneNumber)
|
||||
};
|
||||
|
||||
napi_value constructor;
|
||||
status = napi_define_class(env, "PhoneNumberFormat", NAPI_AUTO_LENGTH, PhoneNumberFormatConstructor, nullptr,
|
||||
sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Define class failed when InitPhoneNumberFormat");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_set_named_property(env, exports, "PhoneNumberFormat", constructor);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Set property failed when InitPhoneNumberFormat");
|
||||
return nullptr;
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
|
||||
void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
std::map<std::string, std::string> &map)
|
||||
{
|
||||
napi_value optionValue = nullptr;
|
||||
napi_valuetype type = napi_undefined;
|
||||
napi_status status = napi_typeof(env, options, &type);
|
||||
if (status != napi_ok && type != napi_object) {
|
||||
HiLog::Error(LABEL, "Get option failed, option is not an object");
|
||||
return;
|
||||
}
|
||||
bool hasProperty = false;
|
||||
napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
|
||||
if (propStatus == napi_ok && hasProperty) {
|
||||
status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
|
||||
if (status == napi_ok) {
|
||||
size_t len;
|
||||
napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
|
||||
std::vector<char> optionBuf(len + 1);
|
||||
status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
|
||||
map.insert(make_pair(optionName, optionBuf.data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
napi_value I18nAddon::PhoneNumberFormatConstructor(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 2;
|
||||
napi_value argv[2] = {0};
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
|
||||
|
||||
napi_valuetype valueType = napi_valuetype::napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_valuetype::napi_string) {
|
||||
napi_throw_type_error(env, nullptr, "Parameter type does not match");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get country tag length failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<char> country (len + 1);
|
||||
status = napi_get_value_string_utf8(env, argv[0], country.data(), len + 1, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get country tag failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> options;
|
||||
GetOptionValue(env, argv[1], "type", options);
|
||||
|
||||
std::unique_ptr<I18nAddon> obj = std::make_unique<I18nAddon>();
|
||||
if (obj == nullptr) {
|
||||
HiLog::Error(LABEL, "Create IntlAddon failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
|
||||
I18nAddon::Destructor, nullptr, &obj->wrapper_);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Wrap IntlAddon failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!obj->InitPhoneNumberFormatContext(env, info, country.data(), options)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
obj.release();
|
||||
|
||||
return thisVar;
|
||||
}
|
||||
|
||||
bool I18nAddon::InitPhoneNumberFormatContext(napi_env env, napi_callback_info info, const std::string &country,
|
||||
const std::map<std::string, std::string> &options)
|
||||
{
|
||||
napi_value global;
|
||||
napi_status status = napi_get_global(env, &global);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get global failed");
|
||||
return false;
|
||||
}
|
||||
env_ = env;
|
||||
phonenumberfmt_ = std::make_unique<PhoneNumberFormat>(country, options);
|
||||
|
||||
return phonenumberfmt_ != nullptr;
|
||||
}
|
||||
|
||||
napi_value I18nAddon::IsValidPhoneNumber(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = num;
|
||||
napi_value argv[num];
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
|
||||
napi_valuetype valueType = napi_valuetype::napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_valuetype::napi_string) {
|
||||
napi_throw_type_error(env, nullptr, "Parameter type does not match");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get phone number length failed");
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<char> buf(len + 1);
|
||||
status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get phone number failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
I18nAddon *obj = nullptr;
|
||||
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
|
||||
if (status != napi_ok || obj == nullptr || obj->phonenumberfmt_ == nullptr) {
|
||||
HiLog::Error(LABEL, "GetPhoneNumberFormat object failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isValid = obj->phonenumberfmt_->isValidPhoneNumber(buf.data());
|
||||
|
||||
napi_value result;
|
||||
status = napi_get_boolean(env, isValid, &result);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Create boolean failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value I18nAddon::FormatPhoneNumber(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = num;
|
||||
napi_value argv[num];
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
|
||||
napi_valuetype valueType = napi_valuetype::napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_valuetype::napi_string) {
|
||||
napi_throw_type_error(env, nullptr, "Parameter type does not match");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t len;
|
||||
napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get phone number length failed");
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<char> buf(len + 1);
|
||||
status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Get phone number failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
I18nAddon *obj = nullptr;
|
||||
status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
|
||||
if (status != napi_ok || obj == nullptr || obj->phonenumberfmt_ == nullptr) {
|
||||
HiLog::Error(LABEL, "Get PhoneNumberFormat object failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string formattedPhoneNumber = obj->phonenumberfmt_->format(buf.data());
|
||||
|
||||
napi_value result;
|
||||
status = napi_create_string_utf8(env, formattedPhoneNumber.c_str(), NAPI_AUTO_LENGTH, &result);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Create format phone number failed");
|
||||
return nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
napi_value Init(napi_env env, napi_value exports)
|
||||
{
|
||||
return I18nAddon::Init(env, exports);
|
||||
napi_value val = I18nAddon::Init(env, exports);
|
||||
return I18nAddon::InitPhoneNumberFormat(env, val);
|
||||
}
|
||||
|
||||
static napi_module g_i18nModule = {
|
||||
|
Loading…
Reference in New Issue
Block a user