• 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 "ErrorCode.h"
13 #include "JNIHelp.h"
14 #include "JniConstants.h"
15 #include "ScopedJavaUnicodeString.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 lhs0,jstring rhs0)38 static jint NativeCollation_compare(JNIEnv* env, jclass, jint address, jstring lhs0, jstring rhs0) {
39     ScopedJavaUnicodeString lhs(env, lhs0);
40     ScopedJavaUnicodeString rhs(env, rhs0);
41     return ucol_strcoll(toCollator(address),
42             lhs.unicodeString().getBuffer(), lhs.unicodeString().length(),
43             rhs.unicodeString().getBuffer(), rhs.unicodeString().length());
44 }
45 
NativeCollation_getAttribute(JNIEnv * env,jclass,jint address,jint type)46 static jint NativeCollation_getAttribute(JNIEnv* env, jclass, jint address, jint type) {
47     UErrorCode status = U_ZERO_ERROR;
48     jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status);
49     icu4jni_error(env, status);
50     return result;
51 }
52 
NativeCollation_getCollationElementIterator(JNIEnv * env,jclass,jint address,jstring source0)53 static jint NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jint address, jstring source0) {
54     ScopedJavaUnicodeString source(env, source0);
55     UErrorCode status = U_ZERO_ERROR;
56     UCollationElements* result = ucol_openElements(toCollator(address),
57             source.unicodeString().getBuffer(), source.unicodeString().length(), &status);
58     icu4jni_error(env, status);
59     return static_cast<jint>(reinterpret_cast<uintptr_t>(result));
60 }
61 
NativeCollation_getMaxExpansion(JNIEnv *,jclass,jint address,jint order)62 static jint NativeCollation_getMaxExpansion(JNIEnv*, jclass, jint address, jint order) {
63     return ucol_getMaxExpansion(toCollationElements(address), order);
64 }
65 
NativeCollation_getNormalization(JNIEnv * env,jclass,jint address)66 static jint NativeCollation_getNormalization(JNIEnv* env, jclass, jint address) {
67     UErrorCode status = U_ZERO_ERROR;
68     jint result = ucol_getAttribute(toCollator(address), UCOL_NORMALIZATION_MODE, &status);
69     icu4jni_error(env, status);
70     return result;
71 }
72 
NativeCollation_setNormalization(JNIEnv * env,jclass,jint address,jint mode)73 static void NativeCollation_setNormalization(JNIEnv* env, jclass, jint address, jint mode) {
74     UErrorCode status = U_ZERO_ERROR;
75     ucol_setAttribute(toCollator(address), UCOL_NORMALIZATION_MODE, UColAttributeValue(mode), &status);
76     icu4jni_error(env, status);
77 }
78 
NativeCollation_getOffset(JNIEnv *,jclass,jint address)79 static jint NativeCollation_getOffset(JNIEnv*, jclass, jint address) {
80     return ucol_getOffset(toCollationElements(address));
81 }
82 
NativeCollation_getRules(JNIEnv * env,jclass,jint address)83 static jstring NativeCollation_getRules(JNIEnv* env, jclass, jint address) {
84     int32_t length = 0;
85     const UChar* rules = ucol_getRules(toCollator(address), &length);
86     return env->NewString(rules, length);
87 }
88 
NativeCollation_getSortKey(JNIEnv * env,jclass,jint address,jstring source0)89 static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jint address, jstring source0) {
90     ScopedJavaUnicodeString source(env, source0);
91     const UCollator* collator  = toCollator(address);
92     uint8_t byteArray[UCOL_MAX_BUFFER * 2];
93     UniquePtr<uint8_t[]> largerByteArray;
94     uint8_t* usedByteArray = byteArray;
95     const UChar* chars = source.unicodeString().getBuffer();
96     size_t charCount = source.unicodeString().length();
97     size_t byteArraySize = ucol_getSortKey(collator, chars, charCount, usedByteArray, sizeof(byteArray) - 1);
98     if (byteArraySize > sizeof(byteArray) - 1) {
99         // didn't fit, try again with a larger buffer.
100         largerByteArray.reset(new uint8_t[byteArraySize + 1]);
101         usedByteArray = largerByteArray.get();
102         byteArraySize = ucol_getSortKey(collator, chars, charCount, usedByteArray, byteArraySize);
103     }
104     if (byteArraySize == 0) {
105         return NULL;
106     }
107     jbyteArray result = env->NewByteArray(byteArraySize);
108     env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray));
109     return result;
110 }
111 
NativeCollation_next(JNIEnv * env,jclass,jint address)112 static jint NativeCollation_next(JNIEnv* env, jclass, jint address) {
113     UErrorCode status = U_ZERO_ERROR;
114     jint result = ucol_next(toCollationElements(address), &status);
115     icu4jni_error(env, status);
116     return result;
117 }
118 
NativeCollation_openCollator(JNIEnv * env,jclass,jstring localeName)119 static jint NativeCollation_openCollator(JNIEnv* env, jclass, jstring localeName) {
120     ScopedUtfChars localeChars(env, localeName);
121     if (localeChars.c_str() == NULL) {
122         return 0;
123     }
124     UErrorCode status = U_ZERO_ERROR;
125     UCollator* c = ucol_open(localeChars.c_str(), &status);
126     icu4jni_error(env, status);
127     return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
128 }
129 
NativeCollation_openCollatorFromRules(JNIEnv * env,jclass,jstring rules0,jint mode,jint strength)130 static jint NativeCollation_openCollatorFromRules(JNIEnv* env, jclass, jstring rules0, jint mode, jint strength) {
131     ScopedJavaUnicodeString rules(env, rules0);
132     UErrorCode status = U_ZERO_ERROR;
133     UCollator* c = ucol_openRules(rules.unicodeString().getBuffer(), rules.unicodeString().length(),
134             UColAttributeValue(mode), UCollationStrength(strength), NULL, &status);
135     icu4jni_error(env, status);
136     return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
137 }
138 
NativeCollation_previous(JNIEnv * env,jclass,jint address)139 static jint NativeCollation_previous(JNIEnv* env, jclass, jint address) {
140     UErrorCode status = U_ZERO_ERROR;
141     jint result = ucol_previous(toCollationElements(address), &status);
142     icu4jni_error(env, status);
143     return result;
144 }
145 
NativeCollation_reset(JNIEnv *,jclass,jint address)146 static void NativeCollation_reset(JNIEnv*, jclass, jint address) {
147     ucol_reset(toCollationElements(address));
148 }
149 
NativeCollation_safeClone(JNIEnv * env,jclass,jint address)150 static jint NativeCollation_safeClone(JNIEnv* env, jclass, jint address) {
151     UErrorCode status = U_ZERO_ERROR;
152     jint bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
153     UCollator* c = ucol_safeClone(toCollator(address), NULL, &bufferSize, &status);
154     icu4jni_error(env, status);
155     return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
156 }
157 
NativeCollation_setAttribute(JNIEnv * env,jclass,jint address,jint type,jint value)158 static void NativeCollation_setAttribute(JNIEnv* env, jclass, jint address, jint type, jint value) {
159     UErrorCode status = U_ZERO_ERROR;
160     ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status);
161     icu4jni_error(env, status);
162 }
163 
NativeCollation_setOffset(JNIEnv * env,jclass,jint address,jint offset)164 static void NativeCollation_setOffset(JNIEnv* env, jclass, jint address, jint offset) {
165     UErrorCode status = U_ZERO_ERROR;
166     ucol_setOffset(toCollationElements(address), offset, &status);
167     icu4jni_error(env, status);
168 }
169 
NativeCollation_setText(JNIEnv * env,jclass,jint address,jstring source0)170 static void NativeCollation_setText(JNIEnv* env, jclass, jint address, jstring source0) {
171     ScopedJavaUnicodeString source(env, source0);
172     UErrorCode status = U_ZERO_ERROR;
173     ucol_setText(toCollationElements(address),
174             source.unicodeString().getBuffer(), source.unicodeString().length(), &status);
175     icu4jni_error(env, status);
176 }
177 
178 static JNINativeMethod gMethods[] = {
179     NATIVE_METHOD(NativeCollation, closeCollator, "(I)V"),
180     NATIVE_METHOD(NativeCollation, closeElements, "(I)V"),
181     NATIVE_METHOD(NativeCollation, compare, "(ILjava/lang/String;Ljava/lang/String;)I"),
182     NATIVE_METHOD(NativeCollation, getAttribute, "(II)I"),
183     NATIVE_METHOD(NativeCollation, getCollationElementIterator, "(ILjava/lang/String;)I"),
184     NATIVE_METHOD(NativeCollation, getMaxExpansion, "(II)I"),
185     NATIVE_METHOD(NativeCollation, getNormalization, "(I)I"),
186     NATIVE_METHOD(NativeCollation, getOffset, "(I)I"),
187     NATIVE_METHOD(NativeCollation, getRules, "(I)Ljava/lang/String;"),
188     NATIVE_METHOD(NativeCollation, getSortKey, "(ILjava/lang/String;)[B"),
189     NATIVE_METHOD(NativeCollation, next, "(I)I"),
190     NATIVE_METHOD(NativeCollation, openCollator, "(Ljava/lang/String;)I"),
191     NATIVE_METHOD(NativeCollation, openCollatorFromRules, "(Ljava/lang/String;II)I"),
192     NATIVE_METHOD(NativeCollation, previous, "(I)I"),
193     NATIVE_METHOD(NativeCollation, reset, "(I)V"),
194     NATIVE_METHOD(NativeCollation, safeClone, "(I)I"),
195     NATIVE_METHOD(NativeCollation, setAttribute, "(III)V"),
196     NATIVE_METHOD(NativeCollation, setNormalization, "(II)V"),
197     NATIVE_METHOD(NativeCollation, setOffset, "(II)V"),
198     NATIVE_METHOD(NativeCollation, setText, "(ILjava/lang/String;)V"),
199 };
register_com_ibm_icu4jni_text_NativeCollator(JNIEnv * env)200 int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv* env) {
201     return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeCollation",
202                 gMethods, NELEM(gMethods));
203 }
204