• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2 *******************************************************************************
3 * Copyright (C) 1996-2005, International Business Machines Corporation and    *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 *
7 *******************************************************************************
8 */
9 
10 #define LOG_TAG "NativeCollation"
11 
12 #include "JNIHelp.h"
13 #include "JniConstants.h"
14 #include "JniException.h"
15 #include "ScopedStringChars.h"
16 #include "ScopedUtfChars.h"
17 #include "UniquePtr.h"
18 #include "ucol_imp.h"
19 #include "unicode/ucol.h"
20 #include "unicode/ucoleitr.h"
21 
toCollator(jint address)22 static UCollator* toCollator(jint address) {
23     return reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address));
24 }
25 
toCollationElements(jint address)26 static UCollationElements* toCollationElements(jint address) {
27     return reinterpret_cast<UCollationElements*>(static_cast<uintptr_t>(address));
28 }
29 
NativeCollation_closeCollator(JNIEnv *,jclass,jint address)30 static void NativeCollation_closeCollator(JNIEnv*, jclass, jint address) {
31     ucol_close(toCollator(address));
32 }
33 
NativeCollation_closeElements(JNIEnv *,jclass,jint address)34 static void NativeCollation_closeElements(JNIEnv*, jclass, jint address) {
35     ucol_closeElements(toCollationElements(address));
36 }
37 
NativeCollation_compare(JNIEnv * env,jclass,jint address,jstring javaLhs,jstring javaRhs)38 static jint NativeCollation_compare(JNIEnv* env, jclass, jint address, jstring javaLhs, jstring javaRhs) {
39     ScopedStringChars lhs(env, javaLhs);
40     if (lhs.get() == NULL) {
41         return 0;
42     }
43     ScopedStringChars rhs(env, javaRhs);
44     if (rhs.get() == NULL) {
45         return 0;
46     }
47     return ucol_strcoll(toCollator(address), lhs.get(), lhs.size(), rhs.get(), rhs.size());
48 }
49 
NativeCollation_getAttribute(JNIEnv * env,jclass,jint address,jint type)50 static jint NativeCollation_getAttribute(JNIEnv* env, jclass, jint address, jint type) {
51     UErrorCode status = U_ZERO_ERROR;
52     jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status);
53     maybeThrowIcuException(env, status);
54     return result;
55 }
56 
NativeCollation_getCollationElementIterator(JNIEnv * env,jclass,jint address,jstring javaSource)57 static jint NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jint address, jstring javaSource) {
58     ScopedStringChars source(env, javaSource);
59     if (source.get() == NULL) {
60         return -1;
61     }
62     UErrorCode status = U_ZERO_ERROR;
63     UCollationElements* result = ucol_openElements(toCollator(address), source.get(), source.size(), &status);
64     maybeThrowIcuException(env, status);
65     return static_cast<jint>(reinterpret_cast<uintptr_t>(result));
66 }
67 
NativeCollation_getMaxExpansion(JNIEnv *,jclass,jint address,jint order)68 static jint NativeCollation_getMaxExpansion(JNIEnv*, jclass, jint address, jint order) {
69     return ucol_getMaxExpansion(toCollationElements(address), order);
70 }
71 
NativeCollation_getOffset(JNIEnv *,jclass,jint address)72 static jint NativeCollation_getOffset(JNIEnv*, jclass, jint address) {
73     return ucol_getOffset(toCollationElements(address));
74 }
75 
NativeCollation_getRules(JNIEnv * env,jclass,jint address)76 static jstring NativeCollation_getRules(JNIEnv* env, jclass, jint address) {
77     int32_t length = 0;
78     const UChar* rules = ucol_getRules(toCollator(address), &length);
79     return env->NewString(rules, length);
80 }
81 
NativeCollation_getSortKey(JNIEnv * env,jclass,jint address,jstring javaSource)82 static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jint address, jstring javaSource) {
83     ScopedStringChars source(env, javaSource);
84     if (source.get() == NULL) {
85         return NULL;
86     }
87     const UCollator* collator  = toCollator(address);
88     uint8_t byteArray[UCOL_MAX_BUFFER * 2];
89     UniquePtr<uint8_t[]> largerByteArray;
90     uint8_t* usedByteArray = byteArray;
91     size_t byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, sizeof(byteArray) - 1);
92     if (byteArraySize > sizeof(byteArray) - 1) {
93         // didn't fit, try again with a larger buffer.
94         largerByteArray.reset(new uint8_t[byteArraySize + 1]);
95         usedByteArray = largerByteArray.get();
96         byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, byteArraySize);
97     }
98     if (byteArraySize == 0) {
99         return NULL;
100     }
101     jbyteArray result = env->NewByteArray(byteArraySize);
102     env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray));
103     return result;
104 }
105 
NativeCollation_next(JNIEnv * env,jclass,jint address)106 static jint NativeCollation_next(JNIEnv* env, jclass, jint address) {
107     UErrorCode status = U_ZERO_ERROR;
108     jint result = ucol_next(toCollationElements(address), &status);
109     maybeThrowIcuException(env, status);
110     return result;
111 }
112 
NativeCollation_openCollator(JNIEnv * env,jclass,jstring localeName)113 static jint NativeCollation_openCollator(JNIEnv* env, jclass, jstring localeName) {
114     ScopedUtfChars localeChars(env, localeName);
115     if (localeChars.c_str() == NULL) {
116         return 0;
117     }
118     UErrorCode status = U_ZERO_ERROR;
119     UCollator* c = ucol_open(localeChars.c_str(), &status);
120     maybeThrowIcuException(env, status);
121     return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
122 }
123 
NativeCollation_openCollatorFromRules(JNIEnv * env,jclass,jstring javaRules,jint mode,jint strength)124 static jint NativeCollation_openCollatorFromRules(JNIEnv* env, jclass, jstring javaRules, jint mode, jint strength) {
125     ScopedStringChars rules(env, javaRules);
126     if (rules.get() == NULL) {
127         return -1;
128     }
129     UErrorCode status = U_ZERO_ERROR;
130     UCollator* c = ucol_openRules(rules.get(), rules.size(),
131             UColAttributeValue(mode), UCollationStrength(strength), NULL, &status);
132     maybeThrowIcuException(env, status);
133     return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
134 }
135 
NativeCollation_previous(JNIEnv * env,jclass,jint address)136 static jint NativeCollation_previous(JNIEnv* env, jclass, jint address) {
137     UErrorCode status = U_ZERO_ERROR;
138     jint result = ucol_previous(toCollationElements(address), &status);
139     maybeThrowIcuException(env, status);
140     return result;
141 }
142 
NativeCollation_reset(JNIEnv *,jclass,jint address)143 static void NativeCollation_reset(JNIEnv*, jclass, jint address) {
144     ucol_reset(toCollationElements(address));
145 }
146 
NativeCollation_safeClone(JNIEnv * env,jclass,jint address)147 static jint NativeCollation_safeClone(JNIEnv* env, jclass, jint address) {
148     UErrorCode status = U_ZERO_ERROR;
149     jint bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
150     UCollator* c = ucol_safeClone(toCollator(address), NULL, &bufferSize, &status);
151     maybeThrowIcuException(env, status);
152     return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
153 }
154 
NativeCollation_setAttribute(JNIEnv * env,jclass,jint address,jint type,jint value)155 static void NativeCollation_setAttribute(JNIEnv* env, jclass, jint address, jint type, jint value) {
156     UErrorCode status = U_ZERO_ERROR;
157     ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status);
158     maybeThrowIcuException(env, status);
159 }
160 
NativeCollation_setOffset(JNIEnv * env,jclass,jint address,jint offset)161 static void NativeCollation_setOffset(JNIEnv* env, jclass, jint address, jint offset) {
162     UErrorCode status = U_ZERO_ERROR;
163     ucol_setOffset(toCollationElements(address), offset, &status);
164     maybeThrowIcuException(env, status);
165 }
166 
NativeCollation_setText(JNIEnv * env,jclass,jint address,jstring javaSource)167 static void NativeCollation_setText(JNIEnv* env, jclass, jint address, jstring javaSource) {
168     ScopedStringChars source(env, javaSource);
169     if (source.get() == NULL) {
170         return;
171     }
172     UErrorCode status = U_ZERO_ERROR;
173     ucol_setText(toCollationElements(address), source.get(), source.size(), &status);
174     maybeThrowIcuException(env, status);
175 }
176 
177 static JNINativeMethod gMethods[] = {
178     NATIVE_METHOD(NativeCollation, closeCollator, "(I)V"),
179     NATIVE_METHOD(NativeCollation, closeElements, "(I)V"),
180     NATIVE_METHOD(NativeCollation, compare, "(ILjava/lang/String;Ljava/lang/String;)I"),
181     NATIVE_METHOD(NativeCollation, getAttribute, "(II)I"),
182     NATIVE_METHOD(NativeCollation, getCollationElementIterator, "(ILjava/lang/String;)I"),
183     NATIVE_METHOD(NativeCollation, getMaxExpansion, "(II)I"),
184     NATIVE_METHOD(NativeCollation, getOffset, "(I)I"),
185     NATIVE_METHOD(NativeCollation, getRules, "(I)Ljava/lang/String;"),
186     NATIVE_METHOD(NativeCollation, getSortKey, "(ILjava/lang/String;)[B"),
187     NATIVE_METHOD(NativeCollation, next, "(I)I"),
188     NATIVE_METHOD(NativeCollation, openCollator, "(Ljava/lang/String;)I"),
189     NATIVE_METHOD(NativeCollation, openCollatorFromRules, "(Ljava/lang/String;II)I"),
190     NATIVE_METHOD(NativeCollation, previous, "(I)I"),
191     NATIVE_METHOD(NativeCollation, reset, "(I)V"),
192     NATIVE_METHOD(NativeCollation, safeClone, "(I)I"),
193     NATIVE_METHOD(NativeCollation, setAttribute, "(III)V"),
194     NATIVE_METHOD(NativeCollation, setOffset, "(II)V"),
195     NATIVE_METHOD(NativeCollation, setText, "(ILjava/lang/String;)V"),
196 };
register_libcore_icu_NativeCollation(JNIEnv * env)197 void register_libcore_icu_NativeCollation(JNIEnv* env) {
198     jniRegisterNativeMethods(env, "libcore/icu/NativeCollation", gMethods, NELEM(gMethods));
199 }
200