• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define LOG_TAG "ICUCollect"
16 #include "icu_collect.h"
17 
18 #include <sqlite3sym.h>
19 #include <unicode/ucol.h>
20 #include <unicode/uclean.h>
21 
22 #include "ohos/init_data.h"
23 #include "logger.h"
24 #include "rdb_errno.h"
25 #include "rdb_visibility.h"
26 #include "sqlite3.h"
27 #include "sqlite_errno.h"
28 
29 API_EXPORT int32_t ConfigICULocale(sqlite3 *, const std::string &str) asm("ConfigICULocale");
30 API_EXPORT int32_t CleanUp() asm("CleanUp");
ConfigICULocale(sqlite3 * handle,const std::string & str)31 int32_t ConfigICULocale(sqlite3 *handle, const std::string &str)
32 {
33     return OHOS::NativeRdb::ICUCollect::Locale(handle, str);
34 }
35 
CleanUp()36 int32_t CleanUp()
37 {
38     u_cleanup();
39     return OHOS::NativeRdb::E_OK;
40 }
41 
42 namespace OHOS::NativeRdb {
43 using namespace OHOS::Rdb;
44 
Collate8Compare(void * p,int n1,const void * v1,int n2,const void * v2)45 int ICUCollect::Collate8Compare(void *p, int n1, const void *v1, int n2, const void *v2)
46 {
47     UCollator *coll = reinterpret_cast<UCollator *>(p);
48     UCharIterator i1;
49     UCharIterator i2;
50     UErrorCode status = U_ZERO_ERROR;
51 
52     uiter_setUTF8(&i1, (const char *)v1, n1);
53     uiter_setUTF8(&i2, (const char *)v2, n2);
54 
55     UCollationResult result = ucol_strcollIter(coll, &i1, &i2, &status);
56 
57     if (U_FAILURE(status)) {
58         LOG_ERROR("Ucol strcoll error.");
59     }
60 
61     if (result == UCOL_LESS) {
62         return -1;
63     } else if (result == UCOL_GREATER) {
64         return 1;
65     }
66     return 0;
67 }
68 
LocalizedCollatorDestroy(void * collator)69 void ICUCollect::LocalizedCollatorDestroy(void *collator)
70 {
71     ucol_close(reinterpret_cast<UCollator *>(collator));
72 }
73 
Locale(sqlite3 * dbHandle,const std::string & str)74 int32_t ICUCollect::Locale(sqlite3 *dbHandle, const std::string &str)
75 {
76     UErrorCode status = U_ZERO_ERROR;
77     SetHwIcuDirectory();
78 
79     UCollator *collator = ucol_open(str.c_str(), &status);
80     if (status == U_USING_DEFAULT_WARNING || status == U_ILLEGAL_ARGUMENT_ERROR) {
81         LOG_ERROR("A resource bundle lookup returned a result from the root locale, locale:%{public}s.", str.c_str());
82         ucol_close(collator);
83         return E_INVALID_ARGS_NEW;
84     }
85     if (U_FAILURE(status)) {
86         LOG_ERROR("Can not open collator, status:%{public}d.", status);
87         ucol_close(collator);
88         return E_ERROR;
89     }
90     ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status);
91     if (U_FAILURE(status)) {
92         LOG_ERROR("Set attribute of collator failed, status:%{public}d.", status);
93         ucol_close(collator);
94         return E_ERROR;
95     }
96     int err = sqlite3_create_collation_v2(dbHandle, "LOCALES", SQLITE_UTF8, collator, ICUCollect::Collate8Compare,
97         (void (*)(void *))ICUCollect::LocalizedCollatorDestroy);
98     if (err != SQLITE_OK) {
99         LOG_ERROR("SCreate collator in sqlite3 failed err:%{public}d.", err);
100         ucol_close(collator);
101         return SQLiteError::ErrNo(err);
102     }
103     return E_OK;
104 }
105 
106 } // namespace OHOS::NativeRdb
107