14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_JS_COLLATOR_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_JS_COLLATOR_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/js_locale.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#include "unicode/udata.h" 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_cinamespace panda::ecmascript { 244514f5e3Sopenharmony_cienum class UsageOption : uint8_t { SORT = 0x01, SEARCH, EXCEPTION }; 254514f5e3Sopenharmony_cienum class CaseFirstOption : uint8_t { UPPER = 0x01, LOWER, FALSE_OPTION, UNDEFINED, EXCEPTION }; 264514f5e3Sopenharmony_cienum class SensitivityOption : uint8_t { BASE = 0x01, ACCENT, CASE, VARIANT, UNDEFINED, EXCEPTION }; 274514f5e3Sopenharmony_cienum class CompareStringsOption : uint8_t { NONE = 0x01, TRY_FAST_PATH }; 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_ciclass JSCollator : public JSObject { 304514f5e3Sopenharmony_cipublic: 314514f5e3Sopenharmony_ci // NOLINTNEXTLINE (readability-identifier-naming, fuchsia-statically-constructed-objects) 324514f5e3Sopenharmony_ci static const CString uIcuDataColl; 334514f5e3Sopenharmony_ci 344514f5e3Sopenharmony_ci static const std::map<std::string, CaseFirstOption> caseFirstMap; 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_ci static const std::map<CaseFirstOption, UColAttributeValue> uColAttributeValueMap; 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_ci static const std::vector<LocaleMatcherOption> LOCALE_MATCHER_OPTION; 394514f5e3Sopenharmony_ci static const std::vector<std::string> LOCALE_MATCHER_OPTION_NAME; 404514f5e3Sopenharmony_ci 414514f5e3Sopenharmony_ci static const std::vector<CaseFirstOption> CASE_FIRST_OPTION; 424514f5e3Sopenharmony_ci static const std::vector<std::string> CASE_FIRST_OPTION_NAME; 434514f5e3Sopenharmony_ci 444514f5e3Sopenharmony_ci static const std::set<std::string> RELEVANT_EXTENSION_KEYS; 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ci static const std::vector<SensitivityOption> SENSITIVITY_OPTION; 474514f5e3Sopenharmony_ci static const std::vector<std::string> SENSITIVITY_OPTION_NAME; 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_ci static const std::vector<UsageOption> USAGE_OPTION; 504514f5e3Sopenharmony_ci static const std::vector<std::string> USAGE_OPTION_NAME; 514514f5e3Sopenharmony_ci 524514f5e3Sopenharmony_ci // All the available locales that are statically known to fulfill fast path conditions. 534514f5e3Sopenharmony_ci static const char *const FAST_LOCALE[]; 544514f5e3Sopenharmony_ci 554514f5e3Sopenharmony_ci CAST_CHECK(JSCollator, IsJSCollator); 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ci static constexpr size_t ICU_FIELD_OFFSET = JSObject::SIZE; 584514f5e3Sopenharmony_ci // icu field. 594514f5e3Sopenharmony_ci ACCESSORS(IcuField, ICU_FIELD_OFFSET, LOCALE_OFFSET) 604514f5e3Sopenharmony_ci ACCESSORS(Locale, LOCALE_OFFSET, COLLATION_OFFSET) 614514f5e3Sopenharmony_ci ACCESSORS(Collation, COLLATION_OFFSET, BOUND_COMPARE_OFFSET) 624514f5e3Sopenharmony_ci ACCESSORS(BoundCompare, BOUND_COMPARE_OFFSET, BIT_FIELD_OFFSET) 634514f5e3Sopenharmony_ci ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET) 644514f5e3Sopenharmony_ci DEFINE_ALIGN_SIZE(LAST_OFFSET); 654514f5e3Sopenharmony_ci 664514f5e3Sopenharmony_ci // define BitField 674514f5e3Sopenharmony_ci static constexpr size_t USAGE_BITS = 2; 684514f5e3Sopenharmony_ci static constexpr size_t CASE_FIRST_BITS = 3; 694514f5e3Sopenharmony_ci static constexpr size_t SENSITIVITY_BITS = 3; 704514f5e3Sopenharmony_ci static constexpr size_t IGNORE_PUNCTUATION_BITS = 1; 714514f5e3Sopenharmony_ci static constexpr size_t NUMERIC_BITS = 1; 724514f5e3Sopenharmony_ci FIRST_BIT_FIELD(BitField, Usage, UsageOption, USAGE_BITS) 734514f5e3Sopenharmony_ci NEXT_BIT_FIELD(BitField, CaseFirst, CaseFirstOption, CASE_FIRST_BITS, Usage) 744514f5e3Sopenharmony_ci NEXT_BIT_FIELD(BitField, Sensitivity, SensitivityOption, SENSITIVITY_BITS, CaseFirst) 754514f5e3Sopenharmony_ci NEXT_BIT_FIELD(BitField, IgnorePunctuation, bool, IGNORE_PUNCTUATION_BITS, Sensitivity) 764514f5e3Sopenharmony_ci NEXT_BIT_FIELD(BitField, Numeric, bool, NUMERIC_BITS, IgnorePunctuation) 774514f5e3Sopenharmony_ci 784514f5e3Sopenharmony_ci DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, BIT_FIELD_OFFSET) 794514f5e3Sopenharmony_ci DECL_DUMP() 804514f5e3Sopenharmony_ci 814514f5e3Sopenharmony_ci icu::Collator *GetIcuCollator() const 824514f5e3Sopenharmony_ci { 834514f5e3Sopenharmony_ci ASSERT(GetIcuField().IsJSNativePointer()); 844514f5e3Sopenharmony_ci JSNativePointer *nativePointer = JSNativePointer::Cast(GetIcuField().GetTaggedObject()); 854514f5e3Sopenharmony_ci auto result = nativePointer->GetExternalPointer(); 864514f5e3Sopenharmony_ci return reinterpret_cast<icu::Collator *>(result); 874514f5e3Sopenharmony_ci } 884514f5e3Sopenharmony_ci 894514f5e3Sopenharmony_ci static void FreeIcuCollator([[maybe_unused]] void *env, void *pointer, [[maybe_unused]] void *hint = nullptr) 904514f5e3Sopenharmony_ci { 914514f5e3Sopenharmony_ci if (pointer == nullptr) { 924514f5e3Sopenharmony_ci return; 934514f5e3Sopenharmony_ci } 944514f5e3Sopenharmony_ci auto icuCollator = reinterpret_cast<icu::Collator *>(pointer); 954514f5e3Sopenharmony_ci delete icuCollator; 964514f5e3Sopenharmony_ci } 974514f5e3Sopenharmony_ci 984514f5e3Sopenharmony_ci static void SetIcuCollator(JSThread *thread, const JSHandle<JSCollator> &collator, 994514f5e3Sopenharmony_ci icu::Collator *icuCollator, const NativePointerCallback &callback); 1004514f5e3Sopenharmony_ci 1014514f5e3Sopenharmony_ci // 11.1.1 InitializeCollator ( collator, locales, options ) 1024514f5e3Sopenharmony_ci static JSHandle<JSCollator> InitializeCollator(JSThread *thread, const JSHandle<JSCollator> &collator, 1034514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &locales, 1044514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &options, 1054514f5e3Sopenharmony_ci bool forIcuCache = false, 1064514f5e3Sopenharmony_ci bool enableLocaleCache = false); 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci static icu::Collator *GetCachedIcuCollator(JSThread *thread, const JSHandle<JSTaggedValue> &locales); 1094514f5e3Sopenharmony_ci static icu::Collator *GetCachedIcuCollator(JSThread *thread, const JSTaggedValue &locales); 1104514f5e3Sopenharmony_ci 1114514f5e3Sopenharmony_ci // 11.3.4 Intl.Collator.prototype.resolvedOptions () 1124514f5e3Sopenharmony_ci static JSHandle<JSObject> ResolvedOptions(JSThread *thread, const JSHandle<JSCollator> &collator); 1134514f5e3Sopenharmony_ci 1144514f5e3Sopenharmony_ci static JSHandle<TaggedArray> GetAvailableLocales(JSThread *thread, bool enableLocaleCache = false); 1154514f5e3Sopenharmony_ci 1164514f5e3Sopenharmony_ci static CompareStringsOption CompareStringsOptionFor(JSThread *thread, JSHandle<JSTaggedValue> locales); 1174514f5e3Sopenharmony_ci 1184514f5e3Sopenharmony_ci static CompareStringsOption CompareStringsOptionFor(JSThread *thread, JSHandle<JSTaggedValue> locales, 1194514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> options); 1204514f5e3Sopenharmony_ci 1214514f5e3Sopenharmony_ci static JSTaggedValue CompareStrings(JSThread *thread, const icu::Collator *icuCollator, 1224514f5e3Sopenharmony_ci const JSHandle<EcmaString> &string1, const JSHandle<EcmaString> &string2, 1234514f5e3Sopenharmony_ci CompareStringsOption csOption = CompareStringsOption::NONE); 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ciprivate: 1264514f5e3Sopenharmony_ci static CaseFirstOption StringToCaseFirstOption(const std::string &str); 1274514f5e3Sopenharmony_ci 1284514f5e3Sopenharmony_ci static UColAttributeValue OptionToUColAttribute(CaseFirstOption caseFirstOption); 1294514f5e3Sopenharmony_ci 1304514f5e3Sopenharmony_ci static std::set<std::string> BuildLocaleSet(const std::vector<std::string> &availableLocales, const char *path, 1314514f5e3Sopenharmony_ci const char *key); 1324514f5e3Sopenharmony_ci 1334514f5e3Sopenharmony_ci static void SetNumericOption(icu::Collator *icuCollator, bool numeric); 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ci static void SetCaseFirstOption(icu::Collator *icuCollator, CaseFirstOption caseFirstOption); 1364514f5e3Sopenharmony_ci}; 1374514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1384514f5e3Sopenharmony_ci#endif // ECMASCRIPT_JS_COLLATOR_H 139