OLD | NEW |
1 /* | 1 /* |
2 ********************************************************************** | 2 ********************************************************************** |
3 * Copyright (C) 1997-2011, International Business Machines | 3 * Copyright (C) 1997-2014, International Business Machines |
4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
5 ********************************************************************** | 5 ********************************************************************** |
6 * | 6 * |
7 * File USCRIPT.C | 7 * File USCRIPT.C |
8 * | 8 * |
9 * Modification History: | 9 * Modification History: |
10 * | 10 * |
11 * Date Name Description | 11 * Date Name Description |
12 * 07/06/2001 Ram Creation. | 12 * 07/06/2001 Ram Creation. |
13 ****************************************************************************** | 13 ****************************************************************************** |
14 */ | 14 */ |
15 | 15 |
| 16 #include "unicode/uchar.h" |
16 #include "unicode/uscript.h" | 17 #include "unicode/uscript.h" |
17 #include "unicode/ures.h" | 18 #include "unicode/uloc.h" |
18 #include "unicode/uchar.h" | |
19 #include "unicode/putil.h" | |
20 #include "uprops.h" | |
21 #include "cmemory.h" | 19 #include "cmemory.h" |
22 #include "cstring.h" | 20 #include "cstring.h" |
23 | 21 |
24 static const char kLocaleScript[] = "LocaleScript"; | 22 static const UScriptCode JAPANESE[3] = { USCRIPT_KATAKANA, USCRIPT_HIRAGANA, USC
RIPT_HAN }; |
| 23 static const UScriptCode KOREAN[2] = { USCRIPT_HANGUL, USCRIPT_HAN }; |
| 24 static const UScriptCode HAN_BOPO[2] = { USCRIPT_HAN, USCRIPT_BOPOMOFO }; |
25 | 25 |
26 /* TODO: this is a bad API should be deprecated */ | 26 static int32_t |
| 27 setCodes(const UScriptCode *src, int32_t length, |
| 28 UScriptCode *dest, int32_t capacity, UErrorCode *err) { |
| 29 int32_t i; |
| 30 if(U_FAILURE(*err)) { return 0; } |
| 31 if(length > capacity) { |
| 32 *err = U_BUFFER_OVERFLOW_ERROR; |
| 33 return length; |
| 34 } |
| 35 for(i = 0; i < length; ++i) { |
| 36 dest[i] = src[i]; |
| 37 } |
| 38 return length; |
| 39 } |
| 40 |
| 41 static int32_t |
| 42 setOneCode(UScriptCode script, UScriptCode *scripts, int32_t capacity, UErrorCod
e *err) { |
| 43 if(U_FAILURE(*err)) { return 0; } |
| 44 if(1 > capacity) { |
| 45 *err = U_BUFFER_OVERFLOW_ERROR; |
| 46 return 1; |
| 47 } |
| 48 scripts[0] = script; |
| 49 return 1; |
| 50 } |
| 51 |
| 52 static int32_t |
| 53 getCodesFromLocale(const char *locale, |
| 54 UScriptCode *scripts, int32_t capacity, UErrorCode *err) { |
| 55 UErrorCode internalErrorCode = U_ZERO_ERROR; |
| 56 char lang[8]; |
| 57 char script[8]; |
| 58 int32_t scriptLength; |
| 59 if(U_FAILURE(*err)) { return 0; } |
| 60 // Multi-script languages, equivalent to the LocaleScript data |
| 61 // that we used to load from locale resource bundles. |
| 62 /*length = */ uloc_getLanguage(locale, lang, UPRV_LENGTHOF(lang), &internalE
rrorCode); |
| 63 if(U_FAILURE(internalErrorCode) || internalErrorCode == U_STRING_NOT_TERMINA
TED_WARNING) { |
| 64 return 0; |
| 65 } |
| 66 if(0 == uprv_strcmp(lang, "ja")) { |
| 67 return setCodes(JAPANESE, UPRV_LENGTHOF(JAPANESE), scripts, capacity, er
r); |
| 68 } |
| 69 if(0 == uprv_strcmp(lang, "ko")) { |
| 70 return setCodes(KOREAN, UPRV_LENGTHOF(KOREAN), scripts, capacity, err); |
| 71 } |
| 72 scriptLength = uloc_getScript(locale, script, UPRV_LENGTHOF(script), &intern
alErrorCode); |
| 73 if(U_FAILURE(internalErrorCode) || internalErrorCode == U_STRING_NOT_TERMINA
TED_WARNING) { |
| 74 return 0; |
| 75 } |
| 76 if(0 == uprv_strcmp(lang, "zh") && 0 == uprv_strcmp(script, "Hant")) { |
| 77 return setCodes(HAN_BOPO, UPRV_LENGTHOF(HAN_BOPO), scripts, capacity, er
r); |
| 78 } |
| 79 // Explicit script code. |
| 80 if(scriptLength != 0) { |
| 81 UScriptCode scriptCode = (UScriptCode)u_getPropertyValueEnum(UCHAR_SCRIP
T, script); |
| 82 if(scriptCode != USCRIPT_INVALID_CODE) { |
| 83 if(scriptCode == USCRIPT_SIMPLIFIED_HAN || scriptCode == USCRIPT_TRA
DITIONAL_HAN) { |
| 84 scriptCode = USCRIPT_HAN; |
| 85 } |
| 86 return setOneCode(scriptCode, scripts, capacity, err); |
| 87 } |
| 88 } |
| 89 return 0; |
| 90 } |
| 91 |
| 92 /* TODO: this is a bad API and should be deprecated, ticket #11141 */ |
27 U_CAPI int32_t U_EXPORT2 | 93 U_CAPI int32_t U_EXPORT2 |
28 uscript_getCode(const char* nameOrAbbrOrLocale, | 94 uscript_getCode(const char* nameOrAbbrOrLocale, |
29 UScriptCode* fillIn, | 95 UScriptCode* fillIn, |
30 int32_t capacity, | 96 int32_t capacity, |
31 UErrorCode* err){ | 97 UErrorCode* err){ |
| 98 UBool triedCode; |
| 99 char likely[ULOC_FULLNAME_CAPACITY]; |
| 100 UErrorCode internalErrorCode; |
| 101 int32_t length; |
32 | 102 |
33 UScriptCode code = USCRIPT_INVALID_CODE; | 103 if(U_FAILURE(*err)) { |
34 int32_t numFilled=0; | 104 return 0; |
35 int32_t len=0; | |
36 /* check arguments */ | |
37 if(err==NULL ||U_FAILURE(*err)){ | |
38 return numFilled; | |
39 } | 105 } |
40 if(nameOrAbbrOrLocale==NULL || fillIn == NULL || capacity<0){ | 106 if(nameOrAbbrOrLocale==NULL || |
| 107 (fillIn == NULL ? capacity != 0 : capacity < 0)) { |
41 *err = U_ILLEGAL_ARGUMENT_ERROR; | 108 *err = U_ILLEGAL_ARGUMENT_ERROR; |
42 return numFilled; | 109 return 0; |
43 } | 110 } |
44 | 111 |
| 112 triedCode = FALSE; |
45 if(uprv_strchr(nameOrAbbrOrLocale, '-')==NULL && uprv_strchr(nameOrAbbrOrLoc
ale, '_')==NULL ){ | 113 if(uprv_strchr(nameOrAbbrOrLocale, '-')==NULL && uprv_strchr(nameOrAbbrOrLoc
ale, '_')==NULL ){ |
46 /* try long and abbreviated script names first */ | 114 /* try long and abbreviated script names first */ |
47 code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT, nameOrAbbrOrLo
cale); | 115 UScriptCode code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT, na
meOrAbbrOrLocale); |
48 | 116 if(code!=USCRIPT_INVALID_CODE) { |
| 117 return setOneCode(code, fillIn, capacity, err); |
| 118 } |
| 119 triedCode = TRUE; |
49 } | 120 } |
50 if(code==(UScriptCode)UCHAR_INVALID_CODE){ | 121 internalErrorCode = U_ZERO_ERROR; |
51 /* Do not propagate error codes from just not finding a locale bundle. */ | 122 length = getCodesFromLocale(nameOrAbbrOrLocale, fillIn, capacity, err); |
52 UErrorCode localErrorCode = U_ZERO_ERROR; | 123 if(U_FAILURE(*err) || length != 0) { |
53 UResourceBundle* resB = ures_open(NULL,nameOrAbbrOrLocale,&localErrorCod
e); | 124 return length; |
54 if(U_SUCCESS(localErrorCode)&& localErrorCode != U_USING_DEFAULT_WARNING
){ | |
55 UResourceBundle* resD = ures_getByKey(resB,kLocaleScript,NULL,&local
ErrorCode); | |
56 if(U_SUCCESS(localErrorCode) ){ | |
57 len =0; | |
58 while(ures_hasNext(resD)){ | |
59 const UChar* name = ures_getNextString(resD,&len,NULL,&local
ErrorCode); | |
60 if(U_SUCCESS(localErrorCode)){ | |
61 char cName[50] = {'\0'}; | |
62 u_UCharsToChars(name,cName,len); | |
63 code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT
, cName); | |
64 /* got the script code now fill in the buffer */ | |
65 if(numFilled<capacity){ | |
66 *(fillIn)++=code; | |
67 numFilled++; | |
68 }else{ | |
69 ures_close(resD); | |
70 ures_close(resB); | |
71 *err=U_BUFFER_OVERFLOW_ERROR; | |
72 return len; | |
73 } | |
74 } | |
75 } | |
76 } | |
77 ures_close(resD); | |
78 } | |
79 ures_close(resB); | |
80 code = USCRIPT_INVALID_CODE; | |
81 } | 125 } |
82 if(code==(UScriptCode)UCHAR_INVALID_CODE){ | 126 (void)uloc_addLikelySubtags(nameOrAbbrOrLocale, |
83 /* still not found .. try long and abbreviated script names again */ | 127 likely, UPRV_LENGTHOF(likely), &internalErrorCod
e); |
84 code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT, nameOrAbbrOrLo
cale); | 128 if(U_SUCCESS(internalErrorCode) && internalErrorCode != U_STRING_NOT_TERMINA
TED_WARNING) { |
85 } | 129 length = getCodesFromLocale(likely, fillIn, capacity, err); |
86 if(code!=(UScriptCode)UCHAR_INVALID_CODE){ | 130 if(U_FAILURE(*err) || length != 0) { |
87 /* we found it */ | 131 return length; |
88 if(numFilled<capacity){ | |
89 *(fillIn)++=code; | |
90 numFilled++; | |
91 }else{ | |
92 *err=U_BUFFER_OVERFLOW_ERROR; | |
93 return len; | |
94 } | 132 } |
95 } | 133 } |
96 return numFilled; | 134 if(!triedCode) { |
| 135 /* still not found .. try long and abbreviated script names again */ |
| 136 UScriptCode code = (UScriptCode) u_getPropertyValueEnum(UCHAR_SCRIPT, na
meOrAbbrOrLocale); |
| 137 if(code!=USCRIPT_INVALID_CODE) { |
| 138 return setOneCode(code, fillIn, capacity, err); |
| 139 } |
| 140 } |
| 141 return 0; |
97 } | 142 } |
OLD | NEW |