2 * Copyright (c) 2009 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
31 #include <unicode/ucol.h>
32 #include <unicode/ustring.h>
34 #include "lockscreen-options-debug.h"
35 #include "lockscreen-options-ucol.h"
46 HAPI int ucol_init(void)
49 UErrorCode status = U_ZERO_ERROR;
53 if (!strcasecmp(env, "en_US.utf-8")) {
54 s_info.lang = LANG_ENGLISH;
55 } else if (!strcasecmp(env, "ja_JP.utf-8")) {
56 s_info.lang = LANG_JAPANESS;
57 } else if (!strcasecmp(env, "ko_KR.utf-8")) {
58 s_info.lang = LANG_KOREAN;
62 s_info.coll = ucol_open(NULL, &status);
63 if (!U_SUCCESS(status)) {
64 LOCKOPTIONS_DBG("Failed to open ucol (%d)\n", status);
65 ucol_close(s_info.coll);
69 ucol_setAttribute(s_info.coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
70 if (!U_SUCCESS(status)) {
71 LOCKOPTIONS_DBG("Failed to open ucol (%d)\n", status);
72 ucol_close(s_info.coll);
76 ucol_setStrength(s_info.coll, UCOL_PRIMARY);
80 static inline UChar *to_UTF16(const char *src, int *out_len)
83 UErrorCode status = U_ZERO_ERROR;
88 res = calloc(len + 1, sizeof(*res));
90 LOCKOPTIONS_DBG("Heap: %s\n", strerror(errno));
94 u_strFromUTF8(res, len, &len, src, -1, &status);
95 if (!U_SUCCESS(status)) {
96 LOCKOPTIONS_DBG("Unable to convert(%s) to UTF16(%s)\n", src, u_errorName(status));
105 static inline int hangul_to_jamo(const char *index)
108 Eina_Unicode tmp = 0;
112 static int table[] = {
113 0x00003131, 0x00003131,
115 0x00003137, 0x00003137,
118 0x00003142, 0x00003142,
119 0x00003145, 0x00003145,
121 0x00003148, 0x00003148,
128 0xb184e3, 0xb284e3, 0xb484e3, 0xb784e3, 0xb884e3, 0xb984e3,
129 0x8185e3, 0x8285e3, 0x8385e3, 0x8585e3, 0x8685e3, 0x8785e3,
130 0x8885e3, 0x8985e3, 0x8a85e3, 0x8b85e3, 0x8c85e3, 0x8d85e3,
135 ret = eina_unicode_utf8_to_unicode(index, &a);
141 if (tmp < base || tmp > last) {
150 #define __isalpha(a) (((a) >= 'a' && (a) <= 'z') || ((a) >= 'A' && (a) <= 'Z'))
151 #define __tolower(a) (((a) >= 'A' && (a) <= 'Z') ? (a) + 32 : (a))
153 HAPI int ucol_compare_first_letters(const char *name, const char *letters)
155 if (s_info.lang == LANG_KOREAN) {
157 int jamo_letters = 0;
160 jamo_name = hangul_to_jamo(name);
162 ucs = eina_unicode_utf8_to_unicode(letters, &jamo_letters);
164 jamo_letters = (int)*ucs;
168 if (__isalpha(jamo_letters)) {
169 if (!__isalpha(jamo_name)) {
170 //DbgPrint("%d - %d (%s, %s)\n", jamo_name, jamo_letters, name, letters);
174 return __tolower(jamo_name) - __tolower(jamo_letters);
177 return jamo_name - jamo_letters;
180 return ucol_ncompare(name, letters, strlen(letters));
183 HAPI int ucol_is_alpha(const char *name)
189 ucs = eina_unicode_utf8_to_unicode(name, &len);
195 return __isalpha(letter);
198 HAPI int ucol_detect_lang(int ch)
206 u_strToUpper((UChar *)&ch, 1, (UChar *)&result, -1, NULL, &status);
207 if (U_FAILURE(status)) {
208 ErrPrint("u_strToLower: %s\n", u_errorName(status));
212 size = unorm_normalize((UChar *)&result, 1, UNORM_NFD, 0, (UChar *)&result, 1, &status);
213 if (U_FAILURE(status)) {
214 ErrPrint("unorm_normalize: %s\n", u_errorName(status));
219 lang = ublock_getCode(ch);
221 case UBLOCK_HIRAGANA:
222 case UBLOCK_KATAKANA:
223 case UBLOCK_KATAKANA_PHONETIC_EXTENSIONS:
224 case UBLOCK_JAVANESE:
225 case UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS:
226 lang = LANG_JAPANESS;
228 case UBLOCK_HANGUL_JAMO:
229 case UBLOCK_HANGUL_COMPATIBILITY_JAMO:
230 case UBLOCK_HANGUL_SYLLABLES:
231 case UBLOCK_HANGUL_JAMO_EXTENDED_A:
232 case UBLOCK_HANGUL_JAMO_EXTENDED_B:
235 case UBLOCK_BASIC_LATIN: // = 1, /*[0000]*/
236 case UBLOCK_LATIN_1_SUPPLEMENT: // =2, /*[0080]*/
237 case UBLOCK_LATIN_EXTENDED_A: // =3, /*[0100]*/
238 case UBLOCK_LATIN_EXTENDED_B: // =4, /*[0180]*/
239 case UBLOCK_LATIN_EXTENDED_ADDITIONAL: // =38, /*[1E00]*/
242 case UBLOCK_CJK_RADICALS_SUPPLEMENT: //=58, /*[2E80]*/
243 case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION: //=61, /*[3000]*/
244 case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS: //=68, /*[3200]*/
245 case UBLOCK_CJK_STROKES: // =130, /*[31C0]*/
246 case UBLOCK_CJK_COMPATIBILITY: // =69, /*[3300]*/
247 case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A: //=70, /*[3400]*/
248 case UBLOCK_CJK_UNIFIED_IDEOGRAPHS: //=71, /*[4E00]*/
249 case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS: //=79, /*[F900]*/
250 case UBLOCK_CJK_COMPATIBILITY_FORMS: //=83, /*[FE30]*/
251 case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B : // =94, /*[20000]*/
252 case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT: // =95, /*[2F800]*/
253 case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C: // =197, /*[2A700]*/
254 case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D: // =209, /*[2B740]*/
258 LOCKOPTIONS_DBG("Detected unknown: %d\n", lang);
266 HAPI int ucol_ncompare(const char *src, const char *dest, int len)
270 UCollationResult res;
276 return strncmp(src, dest, len);
279 tmp = malloc(len + 1);
281 LOCKOPTIONS_DBG("Heap: %s\n", strerror(errno));
282 return strncmp(src, dest, len);
284 strncpy(tmp, dest, len);
287 /* To get the ucs16 len */
288 src_uni = to_UTF16(tmp, &len);
291 LOCKOPTIONS_DBG("Failed get utf16\n");
292 return strncmp(src, dest, len);
296 src_uni = to_UTF16(src, &src_len);
298 LOCKOPTIONS_DBG("SRC: Failed to convert to UTF16\n");
299 return strncmp(src, dest, len);
302 dest_uni = to_UTF16(dest, &dest_len);
304 LOCKOPTIONS_DBG("DEST: Failed to convert to UTF16\n");
306 return strncmp(src, dest, len);
309 switch (s_info.lang) {
311 if (__isalpha(*src_uni) && !__isalpha(*dest_uni)) {
313 } else if (!__isalpha(*src_uni) && __isalpha(*dest_uni)) {
319 src_lang = ucol_detect_lang(*src_uni);
320 dest_lang = ucol_detect_lang(*dest_uni);
322 if (src_lang == LANG_JAPANESS && dest_lang != LANG_JAPANESS) {
324 } else if (src_lang != LANG_JAPANESS && dest_lang == LANG_JAPANESS) {
327 res = ucol_strcoll(s_info.coll, (UChar *)src_uni, len, (UChar *)dest_uni, len);
332 if (__isalpha(*src_uni) && !__isalpha(*dest_uni)) {
334 } else if (!__isalpha(*src_uni) && __isalpha(*dest_uni)) {
340 src_lang = ucol_detect_lang(*src_uni);
341 dest_lang = ucol_detect_lang(*dest_uni);
343 if (src_lang == LANG_KOREAN && dest_lang != LANG_KOREAN) {
345 } else if (src_lang != LANG_KOREAN && dest_lang == LANG_KOREAN) {
348 res = ucol_strcoll(s_info.coll, (UChar *)src_uni, len, (UChar *)dest_uni, len);
355 if (__isalpha(*src_uni) && !__isalpha(*dest_uni)) {
357 } else if (!__isalpha(*src_uni) && __isalpha(*dest_uni)) {
361 res = ucol_strcoll(s_info.coll, (UChar *)src_uni, len, (UChar *)dest_uni, len);
381 LOCKOPTIONS_DBG("%s ? %s\n", src, dest);
386 HAPI int ucol_compare(const char *src, const char *dest)
390 UCollationResult res;
396 return strcmp(src, dest);
399 src_uni = to_UTF16(src, &src_len);
401 LOCKOPTIONS_DBG("SRC: Failed to convert to UTF16\n");
402 return strcmp(src, dest);
405 dest_uni = to_UTF16(dest, &dest_len);
407 LOCKOPTIONS_DBG("DEST: Failed to convert to UTF16\n");
409 return strcmp(src, dest);
412 len = src_len > dest_len ? dest_len : src_len;
414 switch (s_info.lang) {
416 if (__isalpha(*src_uni) && !__isalpha(*dest_uni)) {
418 } else if (!__isalpha(*src_uni) && __isalpha(*dest_uni)) {
424 src_lang = ucol_detect_lang(*src_uni);
425 dest_lang = ucol_detect_lang(*dest_uni);
427 if (src_lang == LANG_JAPANESS && dest_lang != LANG_JAPANESS) {
429 } else if (src_lang != LANG_JAPANESS && dest_lang == LANG_JAPANESS) {
432 res = ucol_strcoll(s_info.coll, (UChar *)src_uni, len, (UChar *)dest_uni, len);
437 if (__isalpha(*src_uni) && !__isalpha(*dest_uni)) {
439 } else if (!__isalpha(*src_uni) && __isalpha(*dest_uni)) {
445 src_lang = ucol_detect_lang(*src_uni);
446 dest_lang = ucol_detect_lang(*dest_uni);
448 if (src_lang == LANG_KOREAN && dest_lang != LANG_KOREAN) {
450 } else if (src_lang != LANG_KOREAN && dest_lang == LANG_KOREAN) {
453 res = ucol_strcoll(s_info.coll, (UChar *)src_uni, len, (UChar *)dest_uni, len);
459 if (__isalpha(*src_uni) && !__isalpha(*dest_uni)) {
461 } else if (!__isalpha(*src_uni) && __isalpha(*dest_uni)) {
464 res = ucol_strcoll(s_info.coll, (UChar *)src_uni, len, (UChar *)dest_uni, len);
476 if (src_len > dest_len) {
478 } else if (src_len == dest_len) {
488 LOCKOPTIONS_DBG("%s ? %s\n", src, dest);
493 HAPI int ucol_fini(void)
496 ucol_close(s_info.coll);
502 HAPI const int ucol_current_lang(void)