mirror of
https://gitee.com/openharmony/global_i18n
synced 2024-11-23 15:10:32 +00:00
add measure format
Signed-off-by: meaty-bag-and-wangwang-meat <zouzhexi@huawei.com>
This commit is contained in:
parent
e833453903
commit
e63a531ce7
@ -52,9 +52,11 @@ ohos_shared_library("intl_util") {
|
||||
"src/i18n_calendar.cpp",
|
||||
"src/locale_config.cpp",
|
||||
"src/locale_info.cpp",
|
||||
"src/measure_data.cpp",
|
||||
"src/number_format.cpp",
|
||||
"src/phone_number_format.cpp",
|
||||
"src/plural_rules.cpp",
|
||||
"src/str_util.cpp",
|
||||
]
|
||||
cflags_cc = [
|
||||
"-Wall",
|
||||
|
38
frameworks/intl/include/measure_data.h
Normal file
38
frameworks/intl/include/measure_data.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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_MEASURE_DATA_H
|
||||
#define OHOS_GLOBAL_I18N_MEASURE_DATA_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
uint32_t GetMask(const std::string ®ion);
|
||||
void GetDefaultPreferredUnit(const std::string ®ion, const std::string &type, std::vector<std::string> &units);
|
||||
void GetFallbackPreferredUnit(const std::string ®ion, const std::string &usage, std::vector<std::string> &units);
|
||||
void GetRestPreferredUnit(const std::string ®ion, const std::string &usage, std::vector<std::string> &units);
|
||||
void GetPreferredUnit(const std::string ®ion, const std::string &usage, std::vector<std::string> &units);
|
||||
void ComputeFactorValue(const std::string &unit, const std::string &measSys, std::vector<double> &factors);
|
||||
double ComputeSIPrefixValue(const std::string &unit);
|
||||
void ComputePowerValue(const std::string &unit, const std::string &measSys, std::vector<double> &factors);
|
||||
int ComputeValue(const std::string &unit, const std::string &measSys, std::vector<double> &factors);
|
||||
int Convert(double &value, const std::string &fromUnit, const std::string &fromMeasSys, const std::string &toUnit,
|
||||
const std::string &toMeasSys);
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
} // namespace OHOS
|
||||
#endif
|
@ -15,6 +15,10 @@
|
||||
#ifndef OHOS_GLOBAL_I18N_NUMBER_FORMAT_H
|
||||
#define OHOS_GLOBAL_I18N_NUMBER_FORMAT_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "unicode/numberformatter.h"
|
||||
#include "unicode/locid.h"
|
||||
#include "unicode/numfmt.h"
|
||||
@ -27,12 +31,12 @@
|
||||
#include "unicode/measure.h"
|
||||
#include "unicode/currunit.h"
|
||||
#include "unicode/fmtable.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "unicode/ulocdata.h"
|
||||
#include "number_utils.h"
|
||||
#include "number_utypes.h"
|
||||
#include "locale_info.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "measure_data.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
@ -75,6 +79,9 @@ private:
|
||||
std::string maximumSignificantDigits;
|
||||
std::string localeBaseName;
|
||||
std::string localeMatcher;
|
||||
std::string unitUsage;
|
||||
std::string unitType;
|
||||
std::string unitMeasSys;
|
||||
LocaleInfo *localeInfo = nullptr;
|
||||
icu::number::LocalizedNumberFormatter numberFormat;
|
||||
icu::number::Notation notation = icu::number::Notation::simple();
|
||||
@ -82,13 +89,15 @@ private:
|
||||
UNumberUnitWidth currencyDisplay = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT;
|
||||
UNumberSignDisplay signDisplay = UNumberSignDisplay::UNUM_SIGN_AUTO;
|
||||
static const int MAX_UNIT_NUM = 500;
|
||||
static const int DEFAULT_FRACTION_DIGITS = 3;
|
||||
icu::MeasureUnit unitArray[MAX_UNIT_NUM];
|
||||
static bool icuInitialized;
|
||||
static bool Init();
|
||||
static std::map<std::string, UNumberUnitWidth> unitStyle;
|
||||
static std::map<std::string, UNumberUnitWidth> currencyStyle;
|
||||
static std::map<std::string, UNumberSignDisplay> signAutoStyle;
|
||||
static std::map<std::string, UNumberSignDisplay> signAccountingStyle;
|
||||
static std::unordered_map<std::string, UNumberUnitWidth> unitStyle;
|
||||
static std::unordered_map<std::string, UNumberUnitWidth> currencyStyle;
|
||||
static std::unordered_map<std::string, UNumberSignDisplay> signAutoStyle;
|
||||
static std::unordered_map<std::string, UNumberSignDisplay> signAccountingStyle;
|
||||
static std::unordered_map<UMeasurementSystem, std::string> measurementSystem;
|
||||
static std::set<std::string> allValidLocales;
|
||||
static std::set<std::string> GetValidLocales();
|
||||
void ParseConfigs(std::map<std::string, std::string> &configs);
|
||||
|
28
frameworks/intl/include/str_util.h
Normal file
28
frameworks/intl/include/str_util.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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_STR_UTIL_H
|
||||
#define OHOS_GLOBAL_I18N_STR_UTIL_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
void Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest);
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
} // namespace OHOS
|
||||
#endif
|
570
frameworks/intl/src/measure_data.cpp
Normal file
570
frameworks/intl/src/measure_data.cpp
Normal file
@ -0,0 +1,570 @@
|
||||
/*
|
||||
* 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 "measure_data.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <cmath>
|
||||
#include "str_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
using namespace std;
|
||||
const double FT_TO_M = 0.3048;
|
||||
const double FT2_TO_M2 = FT_TO_M * FT_TO_M;
|
||||
const double FT3_TO_M3 = FT_TO_M * FT2_TO_M2;
|
||||
const double IN3_TO_M3 = FT3_TO_M3 / (12 * 12 * 12);
|
||||
const double GAL_IMP_TO_M3 = 0.00454609;
|
||||
const double GAL_TO_M3 = 231 * IN3_TO_M3;
|
||||
const int REGION_OFFSET = 7;
|
||||
const int BASE_VALUE_SIZE = 2;
|
||||
const int FACTOR_SIZE = 2;
|
||||
const int CHAR_OFFSET = 48;
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_001 {
|
||||
{ "area-land-agricult", { "hectare" } },
|
||||
{ "area-land-commercl", { "hectare" } },
|
||||
{ "area-land-residntl", { "hectare" } },
|
||||
{ "length-person", { "centimeter" } },
|
||||
{ "length-person-small", { "centimeter" } },
|
||||
{ "length-rainfall", { "millimeter" } },
|
||||
{ "length-road", { "kilometer" } },
|
||||
{ "length-road-small", { "meter" } },
|
||||
{ "length-snowfall", { "centimeter" } },
|
||||
{ "length-vehicle", { "meter" } },
|
||||
{ "length-visiblty", { "kilometer" } },
|
||||
{ "length-visiblty-small", { "meter" } },
|
||||
{ "speed-road-travel", { "kilometer-per-hour" } },
|
||||
{ "speed-wind", { "kilometer-per-hour" } },
|
||||
{ "temperature-person", { "celsius" } },
|
||||
{ "temperature-weather", { "celsius" } },
|
||||
{ "volume-vehicle-fuel", { "liter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_DEFAULT_001 {
|
||||
{ "length", { "kilometer", "meter", "centimeter" } },
|
||||
{ "area", { "square-kilometer", "hectare", "square-meter", "square-centimeter" } },
|
||||
{ "speed", { "kilometer-per-hour" } },
|
||||
{ "temperature", { "celsius" } },
|
||||
{ "volume", { "cubic-meter", "cubic-centimeter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_AT {
|
||||
{ "length-person", { "meter", "centimeter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_BR {
|
||||
{ "length-person-informal", { "meter", "centimeter" } },
|
||||
{ "length-rainfall", { "centimeter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_BS {
|
||||
{ "temperature-weather", { "fahrenheit" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_CA {
|
||||
{ "length-person-informal", { "foot", "inch" } },
|
||||
{ "length-person-small-informal", { "inch" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_CN {
|
||||
{ "length-person-informal", { "meter", "centimeter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_DE {
|
||||
{ "length-person-informal", { "meter", "centimeter" } },
|
||||
{ "length-visiblty", { "meter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_GB {
|
||||
{ "area-land-agricult", { "acre" } },
|
||||
{ "area-land-commercl", { "acre" } },
|
||||
{ "area-land-residntl", { "acre" } },
|
||||
{ "length-person-informal", { "foot", "inch" } },
|
||||
{ "length-person-small-informal", { "inch" } },
|
||||
{ "length-road", { "mile" } },
|
||||
{ "length-road-small", { "yard" } },
|
||||
{ "length-vehicle", { "foot", "inch" } },
|
||||
{ "length-visiblty", { "mile" } },
|
||||
{ "length-visiblty-small", { "foot" } },
|
||||
{ "speed-road-travel", { "mile-per-hour" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_DEFAULT_GB {
|
||||
{ "length", { "mile", "foot", "inch" } },
|
||||
{ "area", { "square-mile", "acre", "square-foot", "square-inch" } },
|
||||
{ "speed", { "mile-per-hour" } },
|
||||
{ "volume", { "cubic-foot", "cubic-inch" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_KR {
|
||||
{ "speed-wind", { "meter-per-second" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_MX {
|
||||
{ "length-person-informal", { "meter", "centimeter" } },
|
||||
{ "length-vehicle", { "meter", "centimeter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_NL {
|
||||
{ "length-person-informal", { "meter", "centimeter" } },
|
||||
{ "length-visiblty", { "meter", "centimeter" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_NO {
|
||||
{ "length-person-informal", { "meter", "centimeter" } },
|
||||
{ "speed-wind", { "meter-per-second" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_SE {
|
||||
{ "length-person", { "meter", "centimeter" } },
|
||||
{ "length-road-informal", { "mile-scandinavian" } },
|
||||
{ "speed-wind", { "meter-per-second" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_US {
|
||||
{ "area-land-agricult", { "acre" } },
|
||||
{ "area-land-commercl", { "acre" } },
|
||||
{ "area-land-residntl", { "acre" } },
|
||||
{ "length-person", { "inch" } },
|
||||
{ "length-person-informal", { "foot", "inch" } },
|
||||
{ "length-person-small", { "inch" } },
|
||||
{ "length-rainfall", { "inch" } },
|
||||
{ "length-road", { "mile" } },
|
||||
{ "length-road-small", { "foot" } },
|
||||
{ "length-snowfall", { "inch" } },
|
||||
{ "length-vehicle", { "foot", "inch" } },
|
||||
{ "length-visiblty", { "mile" } },
|
||||
{ "length-visiblty-small", { "foot" } },
|
||||
{ "speed-road-travel", { "mile-per-hour" } },
|
||||
{ "speed-wind", { "mile-per-hour" } },
|
||||
{ "temperature-person", { "fahrenheit" } },
|
||||
{ "temperature-weather", { "fahrenheit" } },
|
||||
{ "volume-vehicle-fuel", { "gallon" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<std::string>> USAGE_DEFAULT_US {
|
||||
{ "length", { "mile", "foot", "inch" } },
|
||||
{ "area", { "square-mile", "acre", "square-foot", "square-inch" } },
|
||||
{ "speed", { "mile-per-hour" } },
|
||||
{ "temperature", { "fahrenheit" } },
|
||||
{ "volume", { "cubic-foot", "cubic-inch" } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::vector<double>> CONVERT_FACTORS {
|
||||
{ "acre", { FT2_TO_M2 * 43560, 0 } },
|
||||
{ "hectare", { 10000, 0 } },
|
||||
{ "dunam", { 1000, 0 } },
|
||||
{ "fathom", { FT_TO_M * 6, 0 } },
|
||||
{ "foot", { FT_TO_M, 0 } },
|
||||
{ "furlong", { FT_TO_M * 660, 0 } },
|
||||
{ "inch", { FT_TO_M / 12, 0 } },
|
||||
{ "meter", { 1, 0 } },
|
||||
{ "mile", { FT_TO_M * 5280, 0 } },
|
||||
{ "mile-scandinavian", { 10000, 0 } },
|
||||
{ "nautical-mile", { 1852, 0 } },
|
||||
{ "point", { FT_TO_M / 864, 0 } },
|
||||
{ "yard", { FT_TO_M * 3, 0 } },
|
||||
{ "knot", { 1852 / 3600.0, 0 } },
|
||||
{ "kilometer-per-hour", { 1000 / 3600.0, 0 } },
|
||||
{ "celsius", { 1, 273.15 }},
|
||||
{ "fahrenheit", {5.0 / 9, 2298.35 / 9 }},
|
||||
{ "kelvin", { 1, 0 } },
|
||||
{ "acre-foot", { 43560 * FT3_TO_M3, 0 } },
|
||||
{ "bushel", { GAL_IMP_TO_M3 * 8, 0 } },
|
||||
{ "bushel-UK", { GAL_IMP_TO_M3 * 8, 0 } },
|
||||
{ "bushel-US", { IN3_TO_M3 * 2150.42, 0 } },
|
||||
{ "cup", { GAL_IMP_TO_M3 / 16, 0 } },
|
||||
{ "cup-UK", { GAL_IMP_TO_M3 / 16, 0 } },
|
||||
{ "cup-US", { GAL_TO_M3 / 16, 0 } },
|
||||
{ "cup-metric", {0.00025, 0 } },
|
||||
{ "fluid-ounce", { GAL_IMP_TO_M3 / 128, 0 } },
|
||||
{ "fluid-ounce-imperial", { GAL_IMP_TO_M3 / 160, 0 } },
|
||||
{ "gallon", { GAL_TO_M3, 0 } },
|
||||
{ "gallon-imperial", { GAL_IMP_TO_M3, 0 } },
|
||||
{ "liter", {0.001, 0 } },
|
||||
{ "pint-metric", { 0.0005, 0 } },
|
||||
{ "pint", { GAL_IMP_TO_M3 / 8, 0 } },
|
||||
{ "pint-UK", { GAL_IMP_TO_M3 / 8, 0 } },
|
||||
{ "pint-US", { GAL_TO_M3 / 8, 0 } },
|
||||
{ "quart", { GAL_IMP_TO_M3 / 4, 0 } },
|
||||
{ "quart-UK", { GAL_IMP_TO_M3 / 4, 0 } },
|
||||
{ "quart-US", { GAL_TO_M3 / 4, 0 } },
|
||||
{ "tablespoon", { GAL_IMP_TO_M3 / 256, 0 } },
|
||||
{ "tablespoon-UK", { GAL_IMP_TO_M3 / 256, 0 } },
|
||||
{ "tablespoon-US", { GAL_TO_M3 / 256, 0 } },
|
||||
{ "teaspoon", { GAL_IMP_TO_M3 / (16 * 48), 0 } },
|
||||
{ "teaspoon-UK", { GAL_IMP_TO_M3 / (16 * 48), 0 } },
|
||||
{ "teaspoon-US", { GAL_TO_M3 / (16 * 48), 0 } },
|
||||
{ "barrel", { GAL_IMP_TO_M3 * 36, 0 } },
|
||||
{ "barrel-UK", { GAL_IMP_TO_M3 * 36, 0 } },
|
||||
{ "barrel-US", { GAL_TO_M3 * 42, 0 } },
|
||||
{ "hour", { 3600, 0 } },
|
||||
{ "second", { 1, 0 } },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, std::string> CONVERT_TO_UNIT {
|
||||
{ "acre", "sqaure-meter" },
|
||||
{ "hectare", "sqaure-meter" },
|
||||
{ "dunam", "sqaure-meter" },
|
||||
{ "fathom", "meter" },
|
||||
{ "foot", "meter" },
|
||||
{ "furlong", "meter" },
|
||||
{ "inch", "meter" },
|
||||
{ "meter", "meter" },
|
||||
{ "mile", "meter" },
|
||||
{ "mile-scandinavian", "meter" },
|
||||
{ "nautical-mile", "meter" },
|
||||
{ "point", "meter" },
|
||||
{ "yard", "meter" },
|
||||
{ "knot", "meter-per-second" },
|
||||
{ "kilometer-per-hour", "meter-per-second" },
|
||||
{ "celsius", "kelvin" },
|
||||
{ "fahrenheit", "kelvin" },
|
||||
{ "kelvin", "kelvin" },
|
||||
{ "acre-foot", "cubic-meter" },
|
||||
{ "bushel", "cubic-meter" },
|
||||
{ "bushel-UK", "cubic-meter" },
|
||||
{ "bushel-US", "cubic-meter" },
|
||||
{ "cup", "cubic-meter" },
|
||||
{ "cup-UK", "cubic-meter" },
|
||||
{ "cup-US", "cubic-meter" },
|
||||
{ "cup-metric", "cubic-meter" },
|
||||
{ "fluid-ounce", "cubic-meter" },
|
||||
{ "fluid-ounce-imperial", "cubic-meter" },
|
||||
{ "gallon", "cubic-meter" },
|
||||
{ "gallon-imperial", "cubic-meter" },
|
||||
{ "liter", "cubic-meter" },
|
||||
{ "pint-metric", "cubic-meter" },
|
||||
{ "pint", "cubic-meter" },
|
||||
{ "pint-UK", "cubic-meter" },
|
||||
{ "pint-US", "cubic-meter" },
|
||||
{ "quart", "cubic-meter" },
|
||||
{ "quart-UK", "cubic-meter" },
|
||||
{ "quart-US", "cubic-meter" },
|
||||
{ "tablespoon", "cubic-meter" },
|
||||
{ "tablespoon-UK", "cubic-meter" },
|
||||
{ "tablespoon-US", "cubic-meter" },
|
||||
{ "teaspoon", "cubic-meter" },
|
||||
{ "teaspoon-UK", "cubic-meter" },
|
||||
{ "teaspoon-US", "cubic-meter" },
|
||||
{ "barrel", "cubic-meter" },
|
||||
{ "barrel-US", "cubic-meter" },
|
||||
{ "barrel-UK", "cubic-meter" },
|
||||
{ "hour", "second" },
|
||||
{ "second", "second" },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, double> PREFIX_VALUE {
|
||||
{ "deci", pow(10, -1) },
|
||||
{ "centi", pow(10, -2) },
|
||||
{ "milli", pow(10, -3) },
|
||||
{ "micro", pow(10, -6) },
|
||||
{ "nano", pow(10, -9) },
|
||||
{ "pico", pow(10, -12) },
|
||||
{ "kilo", pow(10, 3) },
|
||||
{ "hecto", pow(10, 2) },
|
||||
{ "mega", pow(10, 6) },
|
||||
};
|
||||
|
||||
const std::unordered_map<std::string, double> POWER_VALUE {
|
||||
{ "square-", 2 },
|
||||
{ "cubic-", 3 },
|
||||
};
|
||||
|
||||
uint32_t GetMask(const string ®ion)
|
||||
{
|
||||
uint32_t firstChar = (region.c_str()[0] - CHAR_OFFSET);
|
||||
uint32_t secondChar = (region.c_str()[1] - CHAR_OFFSET);
|
||||
return (firstChar << REGION_OFFSET) | secondChar;
|
||||
}
|
||||
|
||||
void GetDefaultPreferredUnit(const string ®ion, const string &type, vector<string> &units)
|
||||
{
|
||||
switch (GetMask(region)) {
|
||||
case 0x00000B92: {
|
||||
if (USAGE_DEFAULT_GB.count(type) > 0) {
|
||||
units.assign(USAGE_DEFAULT_GB.at(type).begin(), USAGE_DEFAULT_GB.at(type).end());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x000012A3: {
|
||||
if (USAGE_DEFAULT_US.count(type) > 0) {
|
||||
units.assign(USAGE_DEFAULT_US.at(type).begin(), USAGE_DEFAULT_US.at(type).end());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (USAGE_DEFAULT_001.count(type) > 0) {
|
||||
units.assign(USAGE_DEFAULT_001.at(type).begin(), USAGE_DEFAULT_001.at(type).end());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetFallbackPreferredUnit(const string ®ion, const string &usage, vector<string> &units)
|
||||
{
|
||||
switch (GetMask(region)) {
|
||||
case 0x00000EA8: {
|
||||
if (USAGE_MX.count(usage) > 0) {
|
||||
units.assign(USAGE_MX.at(usage).begin(), USAGE_MX.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000F1C: {
|
||||
if (USAGE_NL.count(usage) > 0) {
|
||||
units.assign(USAGE_NL.at(usage).begin(), USAGE_NL.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000F1F:
|
||||
case 0x0000101C:
|
||||
case 0x00001125: {
|
||||
if (USAGE_NO.count(usage) > 0) {
|
||||
units.assign(USAGE_NO.at(usage).begin(), USAGE_NO.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00001195: {
|
||||
if (USAGE_SE.count(usage) > 0) {
|
||||
units.assign(USAGE_SE.at(usage).begin(), USAGE_SE.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x000012A3: {
|
||||
if (USAGE_US.count(usage) > 0) {
|
||||
units.assign(USAGE_US.at(usage).begin(), USAGE_US.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (USAGE_001.count(usage) > 0) {
|
||||
units.assign(USAGE_001.at(usage).begin(), USAGE_001.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetRestPreferredUnit(const string ®ion, const string &usage, vector<string> &units)
|
||||
{
|
||||
switch (GetMask(region)) {
|
||||
case 0x00000991:
|
||||
case 0x00000C9E: {
|
||||
if (USAGE_CA.count(usage) > 0) {
|
||||
units.assign(USAGE_CA.at(usage).begin(), USAGE_CA.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x0000099E:
|
||||
case 0x00000A1B:
|
||||
case 0x00001024: {
|
||||
if (USAGE_CN.count(usage) > 0) {
|
||||
units.assign(USAGE_CN.at(usage).begin(), USAGE_CN.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000A15: {
|
||||
if (USAGE_DE.count(usage) > 0) {
|
||||
units.assign(USAGE_DE.at(usage).begin(), USAGE_DE.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000B92: {
|
||||
if (USAGE_GB.count(usage) > 0) {
|
||||
units.assign(USAGE_GB.at(usage).begin(), USAGE_GB.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000DA2: {
|
||||
if (USAGE_KR.count(usage) > 0) {
|
||||
units.assign(USAGE_KR.at(usage).begin(), USAGE_KR.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
GetFallbackPreferredUnit(region, usage, units);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (units.size() == 0) {
|
||||
GetFallbackPreferredUnit(region, usage, units);
|
||||
}
|
||||
}
|
||||
|
||||
void GetPreferredUnit(const string ®ion, const string &usage, vector<string> &units)
|
||||
{
|
||||
switch (GetMask(region)) {
|
||||
case 0x000008A4:
|
||||
case 0x00000915:
|
||||
case 0x00000A2A:
|
||||
case 0x00000A97:
|
||||
case 0x00000AA3:
|
||||
case 0x00000B22:
|
||||
case 0x00000C1B:
|
||||
case 0x00000C94:
|
||||
case 0x00000C9C:
|
||||
case 0x00000CA4:
|
||||
case 0x00000D1F:
|
||||
case 0x00000EA9:
|
||||
case 0x00001191:
|
||||
case 0x00001222:
|
||||
case 0x0000131E: {
|
||||
if (USAGE_AT.count(usage) > 0) {
|
||||
units.assign(USAGE_AT.at(usage).begin(), USAGE_AT.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000922: {
|
||||
if (USAGE_BR.count(usage) > 0) {
|
||||
units.assign(USAGE_BR.at(usage).begin(), USAGE_BR.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x00000923:
|
||||
case 0x0000092A:
|
||||
case 0x00001022:
|
||||
case 0x00001027: {
|
||||
if (USAGE_BS.count(usage) > 0) {
|
||||
units.assign(USAGE_BS.at(usage).begin(), USAGE_BS.at(usage).end());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
GetRestPreferredUnit(region, usage, units);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (units.size() == 0) {
|
||||
GetRestPreferredUnit(region, usage, units);
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeFactorValue(const string &unit, const string &measSys, vector<double> &factors)
|
||||
{
|
||||
string unitKey = unit + "-" + measSys;
|
||||
if (CONVERT_FACTORS.count(unitKey) > 0) {
|
||||
factors[0] = CONVERT_FACTORS.at(unitKey)[0];
|
||||
factors[1] = CONVERT_FACTORS.at(unitKey)[1];
|
||||
return;
|
||||
}
|
||||
if (CONVERT_FACTORS.count(unit) > 0) {
|
||||
factors[0] = CONVERT_FACTORS.at(unit)[0];
|
||||
factors[1] = CONVERT_FACTORS.at(unit)[1];
|
||||
}
|
||||
}
|
||||
|
||||
double ComputeSIPrefixValue(const string &unit)
|
||||
{
|
||||
for (auto& prefixValue : PREFIX_VALUE) {
|
||||
if (unit.rfind(prefixValue.first, 0) == 0) {
|
||||
return prefixValue.second;
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void ComputePowerValue(const string &unit, const string &measSys, vector<double> &factors)
|
||||
{
|
||||
for (auto& powerValue : POWER_VALUE) {
|
||||
if (unit.rfind(powerValue.first, 0) == 0) {
|
||||
string baseUnit = unit.substr(powerValue.first.length());
|
||||
double value = ComputeSIPrefixValue(baseUnit);
|
||||
double compare = 0.0;
|
||||
if (fabs(value - compare) < 1e-6) {
|
||||
ComputeFactorValue(baseUnit, measSys, factors);
|
||||
}
|
||||
factors[0] = pow(factors[0], powerValue.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ComputeValue(const string &unit, const string &measSys, vector<double> &factors)
|
||||
{
|
||||
if (unit.find("-per-") != string::npos) {
|
||||
vector<string> baseValues;
|
||||
Split(unit, "-per-", baseValues);
|
||||
if (baseValues.size() == BASE_VALUE_SIZE) {
|
||||
vector<double> numerator = { 1.0, 0.0 };
|
||||
int status = ComputeValue(baseValues[0], measSys, numerator);
|
||||
if (status == 0) {
|
||||
return 0;
|
||||
}
|
||||
vector<double> denominator = { 1.0, 0.0 };
|
||||
status = ComputeValue(baseValues[1], measSys, denominator);
|
||||
if (status == 0) {
|
||||
return 0;
|
||||
}
|
||||
factors[0] = numerator[0] / denominator[0];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
double compare = 0.0;
|
||||
factors[0] = ComputeSIPrefixValue(unit);
|
||||
if (fabs(factors[0] - compare) < 1e-6) {
|
||||
ComputePowerValue(unit, measSys, factors);
|
||||
}
|
||||
if (fabs(factors[0] - compare) < 1e-6) {
|
||||
ComputeFactorValue(unit, measSys, factors);
|
||||
}
|
||||
if (fabs(factors[0] - compare) < 1e-6) {
|
||||
factors[0] = 1.0;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Convert(double &value, const string &fromUnit, const string &fromMeasSys, const string &toUnit,
|
||||
const string &toMeasSys)
|
||||
{
|
||||
double baseResult = 0.0;
|
||||
double result = 0.0;
|
||||
vector<double> fromFactors = {0.0, 0.0};
|
||||
int status = ComputeValue(fromUnit, fromMeasSys, fromFactors);
|
||||
if (status == 0) {
|
||||
return 0;
|
||||
}
|
||||
vector<double> toFactors = {0.0, 0.0};
|
||||
status = ComputeValue(toUnit, toMeasSys, toFactors);
|
||||
if (status == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (fromFactors.size() == FACTOR_SIZE) {
|
||||
baseResult = fromFactors[0] * value + fromFactors[1];
|
||||
}
|
||||
if (toFactors.size() == FACTOR_SIZE) {
|
||||
result = (baseResult - toFactors[1]) / toFactors[0];
|
||||
}
|
||||
value = result;
|
||||
return 1;
|
||||
}
|
||||
} // I18n
|
||||
} // Global
|
||||
} // OHOS
|
@ -36,33 +36,39 @@ std::set<std::string> NumberFormat::GetValidLocales()
|
||||
return allValidLocales;
|
||||
}
|
||||
|
||||
std::map<std::string, UNumberUnitWidth> NumberFormat::unitStyle = {
|
||||
std::unordered_map<std::string, UNumberUnitWidth> NumberFormat::unitStyle = {
|
||||
{ "long", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME },
|
||||
{ "short", UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT },
|
||||
{ "narrow", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }
|
||||
};
|
||||
|
||||
std::map<std::string, UNumberUnitWidth> NumberFormat::currencyStyle = {
|
||||
std::unordered_map<std::string, UNumberUnitWidth> NumberFormat::currencyStyle = {
|
||||
{ "symbol", UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT },
|
||||
{ "code", UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE },
|
||||
{ "name", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME },
|
||||
{ "narrowSymbol", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }
|
||||
};
|
||||
|
||||
std::map<std::string, UNumberSignDisplay> NumberFormat::signAutoStyle = {
|
||||
std::unordered_map<std::string, UNumberSignDisplay> NumberFormat::signAutoStyle = {
|
||||
{ "auto", UNumberSignDisplay::UNUM_SIGN_AUTO },
|
||||
{ "never", UNumberSignDisplay::UNUM_SIGN_NEVER },
|
||||
{ "always", UNumberSignDisplay::UNUM_SIGN_ALWAYS },
|
||||
{ "exceptZero", UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO }
|
||||
};
|
||||
|
||||
std::map<std::string, UNumberSignDisplay> NumberFormat::signAccountingStyle = {
|
||||
std::unordered_map<std::string, UNumberSignDisplay> NumberFormat::signAccountingStyle = {
|
||||
{ "auto", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING },
|
||||
{ "never", UNumberSignDisplay::UNUM_SIGN_NEVER },
|
||||
{ "always", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS },
|
||||
{ "exceptZero", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO }
|
||||
};
|
||||
|
||||
std::unordered_map<UMeasurementSystem, std::string> NumberFormat::measurementSystem = {
|
||||
{ UMeasurementSystem::UMS_SI, "SI" },
|
||||
{ UMeasurementSystem::UMS_US, "US" },
|
||||
{ UMeasurementSystem::UMS_UK, "UK" },
|
||||
};
|
||||
|
||||
NumberFormat::NumberFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
@ -115,9 +121,14 @@ void NumberFormat::InitProperties()
|
||||
for (icu::MeasureUnit curUnit : unitArray) {
|
||||
if (strcmp(curUnit.getSubtype(), unit.c_str()) == 0) {
|
||||
numberFormat = numberFormat.unit(curUnit);
|
||||
unitType = curUnit.getType();
|
||||
}
|
||||
}
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UMeasurementSystem measSys = ulocdata_getMeasurementSystem(localeBaseName.c_str(), &status);
|
||||
unitMeasSys = measurementSystem[measSys];
|
||||
numberFormat = numberFormat.unitWidth(unitDisplay);
|
||||
numberFormat = numberFormat.precision(icu::number::Precision::maxFraction(DEFAULT_FRACTION_DIGITS));
|
||||
}
|
||||
if (!useGrouping.empty()) {
|
||||
numberFormat.grouping((useGrouping == "true") ?
|
||||
@ -176,6 +187,9 @@ void NumberFormat::ParseConfigs(std::map<std::string, std::string> &configs)
|
||||
unitDisplayString = configs["unitDisplay"];
|
||||
unitDisplay = unitStyle[unitDisplayString];
|
||||
}
|
||||
if (configs.count("unitUsage") > 0) {
|
||||
unitUsage = configs["unitUsage"];
|
||||
}
|
||||
}
|
||||
if (styleString == "currency" && configs.count("currency") > 0) {
|
||||
currency = configs["currency"];
|
||||
@ -239,9 +253,47 @@ void NumberFormat::ParseDigitsConfigs(std::map<std::string, std::string> &config
|
||||
|
||||
std::string NumberFormat::Format(double number)
|
||||
{
|
||||
double finalNumber = number;
|
||||
if (!unitUsage.empty()) {
|
||||
std::vector<std::string> preferredUnits;
|
||||
if (unitUsage == "default") {
|
||||
GetDefaultPreferredUnit(localeInfo->GetRegion(), unitType, preferredUnits);
|
||||
} else {
|
||||
GetPreferredUnit(localeInfo->GetRegion(), unitUsage, preferredUnits);
|
||||
}
|
||||
std::map<double, std::string> preferredValuesOverOne;
|
||||
std::map<double, std::string> preferredValuesUnderOne;
|
||||
double num = number;
|
||||
for (size_t i = 0; i < preferredUnits.size(); i++) {
|
||||
int status = Convert(num, unit, unitMeasSys, preferredUnits[i], unitMeasSys);
|
||||
if (status == 0) {
|
||||
continue;
|
||||
}
|
||||
if (num >= 1) {
|
||||
preferredValuesOverOne.insert(std::make_pair(num, preferredUnits[i]));
|
||||
} else {
|
||||
preferredValuesUnderOne.insert(std::make_pair(num, preferredUnits[i]));
|
||||
}
|
||||
}
|
||||
std::string preferredUnit;
|
||||
if (preferredValuesOverOne.size() > 0) {
|
||||
finalNumber = preferredValuesOverOne.begin()->first;
|
||||
preferredUnit = preferredValuesOverOne.begin()->second;
|
||||
} else if (preferredValuesUnderOne.size() > 0) {
|
||||
finalNumber = preferredValuesUnderOne.rbegin()->first;
|
||||
preferredUnit = preferredValuesUnderOne.rbegin()->second;
|
||||
}
|
||||
if (!preferredUnit.empty()) {
|
||||
for (icu::MeasureUnit curUnit : unitArray) {
|
||||
if (strcmp(curUnit.getSubtype(), preferredUnit.c_str()) == 0) {
|
||||
numberFormat = numberFormat.unit(curUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string result;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
numberFormat.formatDouble(number, status).toString(status).toUTF8String(result);
|
||||
numberFormat.formatDouble(finalNumber, status).toString(status).toUTF8String(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -269,6 +321,9 @@ void NumberFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
|
||||
if (!unitDisplayString.empty()) {
|
||||
map.insert(std::make_pair("unitDisplay", unitDisplayString));
|
||||
}
|
||||
if (!unitUsage.empty()) {
|
||||
map.insert(std::make_pair("unitUsage", unitUsage));
|
||||
}
|
||||
if (!unit.empty()) {
|
||||
map.insert(std::make_pair("unit", unit));
|
||||
}
|
||||
|
40
frameworks/intl/src/str_util.cpp
Normal file
40
frameworks/intl/src/str_util.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 "str_util.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
using namespace std;
|
||||
|
||||
void Split(const string &src, const string &sep, vector<string> &dest)
|
||||
{
|
||||
if (src == "") {
|
||||
return;
|
||||
}
|
||||
string::size_type begin = 0;
|
||||
string::size_type end = src.find(sep);
|
||||
while (end != string::npos) {
|
||||
dest.push_back(src.substr(begin, end - begin));
|
||||
begin = end + sep.size();
|
||||
end = src.find(sep, begin);
|
||||
}
|
||||
if (begin != src.size()) {
|
||||
dest.push_back(src.substr(begin));
|
||||
}
|
||||
}
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
} // namespace OHOS
|
@ -21,11 +21,17 @@
|
||||
#include "i18n_calendar.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "locale_config.h"
|
||||
#include "measure_data.h"
|
||||
#include "number_format.h"
|
||||
#include "phone_number_format.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
void GetOptionMap(napi_env env, napi_value argv, std::map<std::string, std::string> &map);
|
||||
void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
std::string &value);
|
||||
|
||||
class I18nAddon {
|
||||
public:
|
||||
static napi_value Init(napi_env env, napi_value exports);
|
||||
@ -46,6 +52,7 @@ public:
|
||||
static napi_value IsRTL(napi_env env, napi_callback_info info);
|
||||
static napi_value InitPhoneNumberFormat(napi_env env, napi_value exports);
|
||||
static napi_value InitI18nCalendar(napi_env env, napi_value exports);
|
||||
static napi_value UnitConvert(napi_env env, napi_callback_info info);
|
||||
|
||||
private:
|
||||
static napi_value PhoneNumberFormatConstructor(napi_env env, napi_callback_info info);
|
||||
|
@ -29,22 +29,22 @@
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
static void GetLocaleTags(napi_env env, napi_value rawLocaleTag, std::vector<std::string> &localeTags);
|
||||
static void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
void GetLocaleTags(napi_env env, napi_value rawLocaleTag, std::vector<std::string> &localeTags);
|
||||
void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
std::map<std::string, std::string> &map);
|
||||
static void GetBoolOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
void GetBoolOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
std::map<std::string, std::string> &map);
|
||||
static void GetIntegerOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
void GetIntegerOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
std::map<std::string, std::string> &map);
|
||||
static void GetDateOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
static void GetNumberOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
static void GetCollatorOptionValue(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
static void GetPluralRulesOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
static void SetOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
|
||||
void GetDateOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
void GetNumberOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
void GetCollatorOptionValue(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
void GetPluralRulesOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map);
|
||||
void SetOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
|
||||
const std::string &option);
|
||||
static void SetIntegerOptionProperties(napi_env env, napi_value &result,
|
||||
void SetIntegerOptionProperties(napi_env env, napi_value &result,
|
||||
std::map<std::string, std::string> &options, const std::string &option);
|
||||
static void SetBooleanOptionProperties(napi_env env, napi_value &result,
|
||||
void SetBooleanOptionProperties(napi_env env, napi_value &result,
|
||||
std::map<std::string, std::string> &options, const std::string &option);
|
||||
|
||||
class IntlAddon {
|
||||
|
@ -83,6 +83,22 @@ void I18nAddon::Destructor(napi_env env, void *nativeObject, void *hint)
|
||||
napi_value I18nAddon::Init(napi_env env, napi_value exports)
|
||||
{
|
||||
napi_status status = napi_ok;
|
||||
napi_value util;
|
||||
status = napi_create_object(env, &util);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to create util object at init");
|
||||
return nullptr;
|
||||
}
|
||||
napi_property_descriptor utilProperties[] = {
|
||||
DECLARE_NAPI_FUNCTION("unitConvert", UnitConvert),
|
||||
};
|
||||
status = napi_define_properties(env, util,
|
||||
sizeof(utilProperties) / sizeof(napi_property_descriptor),
|
||||
utilProperties);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to set properties of util at init");
|
||||
return nullptr;
|
||||
}
|
||||
napi_property_descriptor properties[] = {
|
||||
DECLARE_NAPI_FUNCTION("getSystemLanguages", GetSystemLanguages),
|
||||
DECLARE_NAPI_FUNCTION("getSystemCountries", GetSystemCountries),
|
||||
@ -97,6 +113,7 @@ napi_value I18nAddon::Init(napi_env env, napi_value exports)
|
||||
DECLARE_NAPI_FUNCTION("setSystemLocale", SetSystemLocale),
|
||||
DECLARE_NAPI_FUNCTION("getCalendar", GetCalendar),
|
||||
DECLARE_NAPI_FUNCTION("isRTL", IsRTL),
|
||||
DECLARE_NAPI_PROPERTY("Util", util),
|
||||
};
|
||||
|
||||
status = napi_define_properties(env, exports,
|
||||
@ -109,6 +126,99 @@ napi_value I18nAddon::Init(napi_env env, napi_value exports)
|
||||
return exports;
|
||||
}
|
||||
|
||||
void GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
|
||||
std::string &value)
|
||||
{
|
||||
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);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to get string item");
|
||||
return;
|
||||
}
|
||||
value = optionBuf.data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetOptionMap(napi_env env, napi_value option, std::map<std::string, std::string> &map)
|
||||
{
|
||||
if (option != nullptr) {
|
||||
size_t len;
|
||||
napi_get_value_string_utf8(env, option, nullptr, 0, &len);
|
||||
std::vector<char> styleBuf(len + 1);
|
||||
napi_status status = napi_get_value_string_utf8(env, option, styleBuf.data(), len + 1, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to get string item");
|
||||
return;
|
||||
}
|
||||
map.insert(std::make_pair("unitDisplay", styleBuf.data()));
|
||||
}
|
||||
}
|
||||
|
||||
napi_value I18nAddon::UnitConvert(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 5;
|
||||
napi_value argv[5] = { 0 };
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
|
||||
std::string fromUnit;
|
||||
GetOptionValue(env, argv[0], "unit", fromUnit);
|
||||
std::string fromMeasSys;
|
||||
GetOptionValue(env, argv[0], "measureSystem", fromMeasSys);
|
||||
std::string toUnit;
|
||||
GetOptionValue(env, argv[1], "unit", toUnit);
|
||||
std::string toMeasSys;
|
||||
GetOptionValue(env, argv[1], "measureSystem", toMeasSys);
|
||||
double number;
|
||||
napi_get_value_double(env, argv[2], &number); // 2 is the index of value
|
||||
int convertStatus = Convert(number, fromUnit, fromMeasSys, toUnit, toMeasSys);
|
||||
size_t len;
|
||||
napi_get_value_string_utf8(env, argv[3], nullptr, 0, &len); // 3 is the index of value
|
||||
std::vector<char> localeBuf(len + 1);
|
||||
// 3 is the index of value
|
||||
status = napi_get_value_string_utf8(env, argv[3], localeBuf.data(), len + 1, &len);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to get string item");
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<std::string> localeTags;
|
||||
localeTags.push_back(localeBuf.data());
|
||||
std::map<std::string, std::string> map = {};
|
||||
map.insert(std::make_pair("style", "unit"));
|
||||
if (convertStatus == 0) {
|
||||
HiLog::Error(LABEL, "Do not support the conversion");
|
||||
map.insert(std::make_pair("unit", fromUnit));
|
||||
} else {
|
||||
map.insert(std::make_pair("unit", toUnit));
|
||||
}
|
||||
// 4 is the index of value
|
||||
GetOptionMap(env, argv[4], map);
|
||||
auto numberFmt = std::make_unique<NumberFormat>(localeTags, map);
|
||||
std::string value = numberFmt->Format(number);
|
||||
napi_value result;
|
||||
status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
|
||||
if (status != napi_ok) {
|
||||
HiLog::Error(LABEL, "Failed to create string item");
|
||||
return nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value I18nAddon::GetSystemLanguages(napi_env env, napi_callback_info info)
|
||||
{
|
||||
std::vector<std::string> systemLanguages;
|
||||
|
@ -487,6 +487,7 @@ void GetNumberOptionValues(napi_env env, napi_value options, std::map<std::strin
|
||||
GetOptionValue(env, options, "style", map);
|
||||
GetOptionValue(env, options, "numberingSystem", map);
|
||||
GetOptionValue(env, options, "notation", map);
|
||||
GetOptionValue(env, options, "unitUsage", map);
|
||||
GetBoolOptionValue(env, options, "useGrouping", map);
|
||||
GetIntegerOptionValue(env, options, "minimumIntegerDigits", map);
|
||||
GetIntegerOptionValue(env, options, "minimumFractionDigits", map);
|
||||
@ -1169,6 +1170,7 @@ napi_value IntlAddon::GetNumberResolvedOptions(napi_env env, napi_callback_info
|
||||
SetOptionProperties(env, result, options, "notation");
|
||||
SetOptionProperties(env, result, options, "style");
|
||||
SetOptionProperties(env, result, options, "numberingSystem");
|
||||
SetOptionProperties(env, result, options, "unitUsage");
|
||||
SetBooleanOptionProperties(env, result, options, "useGrouping");
|
||||
SetIntegerOptionProperties(env, result, options, "minimumIntegerDigits");
|
||||
SetIntegerOptionProperties(env, result, options, "minimumFractionDigits");
|
||||
|
Loading…
Reference in New Issue
Block a user