blob: ce76786589f37257d76500decfebf700d3370370 [file] [log] [blame]
The Android Open Source Projectadc854b2009-03-03 19:28:47 -08001/**
2*******************************************************************************
3* Copyright (C) 1996-2005, International Business Machines Corporation and *
4* others. All Rights Reserved. *
5*******************************************************************************
6*
7*******************************************************************************
8*/
9
Elliott Hughes757a7942010-04-16 14:14:28 -070010#define LOG_TAG "NativeCollation"
11
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080012#include "ErrorCode.h"
Elliott Hughes0808cae2010-04-23 16:15:38 -070013#include "JNIHelp.h"
14#include "ScopedJavaUnicodeString.h"
15#include "ScopedUtfChars.h"
16#include "UniquePtr.h"
17#include "ucol_imp.h"
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080018#include "unicode/ucol.h"
19#include "unicode/ucoleitr.h"
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080020
Elliott Hughes0808cae2010-04-23 16:15:38 -070021static UCollator* toCollator(jint address) {
22 return reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address));
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080023}
24
Elliott Hughes0808cae2010-04-23 16:15:38 -070025static UCollationElements* toCollationElements(jint address) {
26 return reinterpret_cast<UCollationElements*>(static_cast<uintptr_t>(address));
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080027}
28
Brian Carlstrom44e0e562010-05-06 23:44:16 -070029static void closeCollator(JNIEnv*, jclass, jint address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070030 ucol_close(toCollator(address));
31}
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080032
Brian Carlstrom44e0e562010-05-06 23:44:16 -070033static void closeElements(JNIEnv*, jclass, jint address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070034 ucol_closeElements(toCollationElements(address));
35}
36
37static jint compare(JNIEnv* env, jclass, jint address, jstring lhs0, jstring rhs0) {
38 ScopedJavaUnicodeString lhs(env, lhs0);
39 ScopedJavaUnicodeString rhs(env, rhs0);
40 return ucol_strcoll(toCollator(address),
41 lhs.unicodeString().getBuffer(), lhs.unicodeString().length(),
42 rhs.unicodeString().getBuffer(), rhs.unicodeString().length());
43}
44
45static jint getAttribute(JNIEnv* env, jclass, jint address, jint type) {
46 UErrorCode status = U_ZERO_ERROR;
47 jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status);
48 icu4jni_error(env, status);
49 return result;
50}
51
52static jint getCollationElementIterator(JNIEnv* env, jclass, jint address, jstring source0) {
53 ScopedJavaUnicodeString source(env, source0);
54 UErrorCode status = U_ZERO_ERROR;
55 UCollationElements* result = ucol_openElements(toCollator(address),
56 source.unicodeString().getBuffer(), source.unicodeString().length(), &status);
57 icu4jni_error(env, status);
58 return static_cast<jint>(reinterpret_cast<uintptr_t>(result));
59}
60
Brian Carlstrom44e0e562010-05-06 23:44:16 -070061static jint getMaxExpansion(JNIEnv*, jclass, jint address, jint order) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070062 return ucol_getMaxExpansion(toCollationElements(address), order);
63}
64
65static jint getNormalization(JNIEnv* env, jclass, jint address) {
66 UErrorCode status = U_ZERO_ERROR;
67 jint result = ucol_getAttribute(toCollator(address), UCOL_NORMALIZATION_MODE, &status);
68 icu4jni_error(env, status);
69 return result;
70}
71
72static void setNormalization(JNIEnv* env, jclass, jint address, jint mode) {
73 UErrorCode status = U_ZERO_ERROR;
74 ucol_setAttribute(toCollator(address), UCOL_NORMALIZATION_MODE, UColAttributeValue(mode), &status);
75 icu4jni_error(env, status);
76}
77
Brian Carlstrom44e0e562010-05-06 23:44:16 -070078static jint getOffset(JNIEnv*, jclass, jint address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070079 return ucol_getOffset(toCollationElements(address));
80}
81
82static jstring getRules(JNIEnv* env, jclass, jint address) {
83 int32_t length = 0;
84 const UChar* rules = ucol_getRules(toCollator(address), &length);
85 return env->NewString(rules, length);
86}
87
88static jbyteArray getSortKey(JNIEnv* env, jclass, jint address, jstring source0) {
89 ScopedJavaUnicodeString source(env, source0);
90 const UCollator* collator = toCollator(address);
91 uint8_t byteArray[UCOL_MAX_BUFFER * 2];
92 UniquePtr<uint8_t[]> largerByteArray;
93 uint8_t *usedByteArray = byteArray;
94 const UChar* chars = source.unicodeString().getBuffer();
95 size_t charCount = source.unicodeString().length();
96 size_t byteArraySize = ucol_getSortKey(collator, chars, charCount, usedByteArray, sizeof(byteArray) - 1);
97 if (byteArraySize > sizeof(byteArray) - 1) {
98 // didn't fit, try again with a larger buffer.
99 largerByteArray.reset(new uint8_t[byteArraySize + 1]);
100 usedByteArray = largerByteArray.get();
101 byteArraySize = ucol_getSortKey(collator, chars, charCount, usedByteArray, byteArraySize);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800102 }
Elliott Hughes0808cae2010-04-23 16:15:38 -0700103 if (byteArraySize == 0) {
104 return NULL;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800105 }
Elliott Hughes0808cae2010-04-23 16:15:38 -0700106 jbyteArray result = env->NewByteArray(byteArraySize);
107 env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray));
108 return result;
109}
110
111static jint next(JNIEnv* env, jclass, jint address) {
Elliott Hughesebe438a2010-03-26 14:46:11 -0700112 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700113 jint result = ucol_next(toCollationElements(address), &status);
Elliott Hughesebe438a2010-03-26 14:46:11 -0700114 icu4jni_error(env, status);
115 return result;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800116}
117
Elliott Hughes0808cae2010-04-23 16:15:38 -0700118static jint openCollator(JNIEnv* env, jclass, jstring localeName) {
119 ScopedUtfChars localeChars(env, localeName);
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700120 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700121 UCollator* c = ucol_open(localeChars.c_str(), &status);
122 icu4jni_error(env, status);
123 return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
124}
125
126static jint openCollatorFromRules(JNIEnv* env, jclass, jstring rules0, jint mode, jint strength) {
127 ScopedJavaUnicodeString rules(env, rules0);
128 UErrorCode status = U_ZERO_ERROR;
129 UCollator* c = ucol_openRules(rules.unicodeString().getBuffer(), rules.unicodeString().length(),
130 UColAttributeValue(mode), UCollationStrength(strength), NULL, &status);
131 icu4jni_error(env, status);
132 return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
133}
134
135static jint previous(JNIEnv* env, jclass, jint address) {
136 UErrorCode status = U_ZERO_ERROR;
137 jint result = ucol_previous(toCollationElements(address), &status);
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700138 icu4jni_error(env, status);
139 return result;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800140}
141
Brian Carlstrom44e0e562010-05-06 23:44:16 -0700142static void reset(JNIEnv*, jclass, jint address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -0700143 ucol_reset(toCollationElements(address));
144}
145
146static jint safeClone(JNIEnv* env, jclass, jint address) {
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800147 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700148 jint bufferSize = U_COL_SAFECLONE_BUFFERSIZE;
149 UCollator* c = ucol_safeClone(toCollator(address), NULL, &bufferSize, &status);
150 icu4jni_error(env, status);
151 return static_cast<jint>(reinterpret_cast<uintptr_t>(c));
152}
153
154static void setAttribute(JNIEnv* env, jclass, jint address, jint type, jint value) {
155 UErrorCode status = U_ZERO_ERROR;
156 ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status);
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700157 icu4jni_error(env, status);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800158}
159
Elliott Hughes0808cae2010-04-23 16:15:38 -0700160static void setOffset(JNIEnv* env, jclass, jint address, jint offset) {
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700161 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700162 ucol_setOffset(toCollationElements(address), offset, &status);
Elliott Hughesebe438a2010-03-26 14:46:11 -0700163 icu4jni_error(env, status);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800164}
165
Elliott Hughes0808cae2010-04-23 16:15:38 -0700166static void setText(JNIEnv* env, jclass, jint address, jstring source0) {
167 ScopedJavaUnicodeString source(env, source0);
168 UErrorCode status = U_ZERO_ERROR;
169 ucol_setText(toCollationElements(address),
170 source.unicodeString().getBuffer(), source.unicodeString().length(), &status);
171 icu4jni_error(env, status);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800172}
173
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800174static JNINativeMethod gMethods[] = {
Elliott Hughes0808cae2010-04-23 16:15:38 -0700175 { "openCollator", "(Ljava/lang/String;)I", (void*) openCollator },
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800176 { "openCollatorFromRules", "(Ljava/lang/String;II)I", (void*) openCollatorFromRules },
177 { "closeCollator", "(I)V", (void*) closeCollator },
178 { "compare", "(ILjava/lang/String;Ljava/lang/String;)I", (void*) compare },
179 { "getNormalization", "(I)I", (void*) getNormalization },
180 { "setNormalization", "(II)V", (void*) setNormalization },
181 { "getRules", "(I)Ljava/lang/String;", (void*) getRules },
182 { "getSortKey", "(ILjava/lang/String;)[B", (void*) getSortKey },
183 { "setAttribute", "(III)V", (void*) setAttribute },
184 { "getAttribute", "(II)I", (void*) getAttribute },
185 { "safeClone", "(I)I", (void*) safeClone },
186 { "getCollationElementIterator", "(ILjava/lang/String;)I", (void*) getCollationElementIterator },
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800187 { "closeElements", "(I)V", (void*) closeElements },
188 { "reset", "(I)V", (void*) reset },
189 { "next", "(I)I", (void*) next },
190 { "previous", "(I)I", (void*) previous },
191 { "getMaxExpansion", "(II)I", (void*) getMaxExpansion },
192 { "setText", "(ILjava/lang/String;)V", (void*) setText },
193 { "getOffset", "(I)I", (void*) getOffset },
194 { "setOffset", "(II)V", (void*) setOffset }
195};
Elliott Hughes0808cae2010-04-23 16:15:38 -0700196int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv* env) {
197 return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeCollation",
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800198 gMethods, NELEM(gMethods));
199}