blob: f265bb5fa1e0f2a9e061721307bfd13400cea516 [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
Elliott Hughes3aac4dd2013-02-04 15:37:52 -080012#include "IcuUtilities.h"
Elliott Hughes0808cae2010-04-23 16:15:38 -070013#include "JNIHelp.h"
Elliott Hughese22935d2010-08-12 17:27:27 -070014#include "JniConstants.h"
Elliott Hughesbef9ec32011-04-19 10:26:58 -070015#include "JniException.h"
Elliott Hughesfe711d62011-04-22 15:56:03 -070016#include "ScopedStringChars.h"
Elliott Hughes0808cae2010-04-23 16:15:38 -070017#include "ScopedUtfChars.h"
18#include "UniquePtr.h"
19#include "ucol_imp.h"
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080020#include "unicode/ucol.h"
21#include "unicode/ucoleitr.h"
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080022
Elliott Hughes1e5d7302013-04-22 17:01:52 -070023static UCollator* toCollator(jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070024 return reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address));
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080025}
26
Elliott Hughes1e5d7302013-04-22 17:01:52 -070027static UCollationElements* toCollationElements(jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070028 return reinterpret_cast<UCollationElements*>(static_cast<uintptr_t>(address));
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080029}
30
Elliott Hughes1e5d7302013-04-22 17:01:52 -070031static void NativeCollation_closeCollator(JNIEnv*, jclass, jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070032 ucol_close(toCollator(address));
33}
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080034
Elliott Hughes1e5d7302013-04-22 17:01:52 -070035static void NativeCollation_closeElements(JNIEnv*, jclass, jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070036 ucol_closeElements(toCollationElements(address));
37}
38
Elliott Hughes1e5d7302013-04-22 17:01:52 -070039static jint NativeCollation_compare(JNIEnv* env, jclass, jlong address, jstring javaLhs, jstring javaRhs) {
Elliott Hughesfe711d62011-04-22 15:56:03 -070040 ScopedStringChars lhs(env, javaLhs);
41 if (lhs.get() == NULL) {
Doug Kwanf08498e2011-06-25 00:31:42 -070042 return 0;
Elliott Hughesfe711d62011-04-22 15:56:03 -070043 }
44 ScopedStringChars rhs(env, javaRhs);
45 if (rhs.get() == NULL) {
Doug Kwanf08498e2011-06-25 00:31:42 -070046 return 0;
Elliott Hughesfe711d62011-04-22 15:56:03 -070047 }
48 return ucol_strcoll(toCollator(address), lhs.get(), lhs.size(), rhs.get(), rhs.size());
Elliott Hughes0808cae2010-04-23 16:15:38 -070049}
50
Elliott Hughes1e5d7302013-04-22 17:01:52 -070051static jint NativeCollation_getAttribute(JNIEnv* env, jclass, jlong address, jint type) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070052 UErrorCode status = U_ZERO_ERROR;
53 jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -070054 maybeThrowIcuException(env, "ucol_getAttribute", status);
Elliott Hughes0808cae2010-04-23 16:15:38 -070055 return result;
56}
57
Elliott Hughes1e5d7302013-04-22 17:01:52 -070058static jlong NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jlong address, jstring javaSource) {
Elliott Hughesfe711d62011-04-22 15:56:03 -070059 ScopedStringChars source(env, javaSource);
60 if (source.get() == NULL) {
61 return -1;
62 }
Elliott Hughes0808cae2010-04-23 16:15:38 -070063 UErrorCode status = U_ZERO_ERROR;
Elliott Hughesfe711d62011-04-22 15:56:03 -070064 UCollationElements* result = ucol_openElements(toCollator(address), source.get(), source.size(), &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -070065 maybeThrowIcuException(env, "ucol_openElements", status);
Elliott Hughes1e5d7302013-04-22 17:01:52 -070066 return static_cast<jlong>(reinterpret_cast<uintptr_t>(result));
Elliott Hughes0808cae2010-04-23 16:15:38 -070067}
68
Elliott Hughes1e5d7302013-04-22 17:01:52 -070069static jint NativeCollation_getMaxExpansion(JNIEnv*, jclass, jlong address, jint order) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070070 return ucol_getMaxExpansion(toCollationElements(address), order);
71}
72
Elliott Hughes1e5d7302013-04-22 17:01:52 -070073static jint NativeCollation_getOffset(JNIEnv*, jclass, jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070074 return ucol_getOffset(toCollationElements(address));
75}
76
Elliott Hughes1e5d7302013-04-22 17:01:52 -070077static jstring NativeCollation_getRules(JNIEnv* env, jclass, jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -070078 int32_t length = 0;
79 const UChar* rules = ucol_getRules(toCollator(address), &length);
80 return env->NewString(rules, length);
81}
82
Elliott Hughes1e5d7302013-04-22 17:01:52 -070083static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jlong address, jstring javaSource) {
Elliott Hughesfe711d62011-04-22 15:56:03 -070084 ScopedStringChars source(env, javaSource);
85 if (source.get() == NULL) {
86 return NULL;
87 }
Elliott Hughes0808cae2010-04-23 16:15:38 -070088 const UCollator* collator = toCollator(address);
89 uint8_t byteArray[UCOL_MAX_BUFFER * 2];
90 UniquePtr<uint8_t[]> largerByteArray;
Elliott Hughesacce5ff2010-08-13 16:14:21 -070091 uint8_t* usedByteArray = byteArray;
Elliott Hughesfe711d62011-04-22 15:56:03 -070092 size_t byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, sizeof(byteArray) - 1);
Elliott Hughes0808cae2010-04-23 16:15:38 -070093 if (byteArraySize > sizeof(byteArray) - 1) {
94 // didn't fit, try again with a larger buffer.
95 largerByteArray.reset(new uint8_t[byteArraySize + 1]);
96 usedByteArray = largerByteArray.get();
Elliott Hughesfe711d62011-04-22 15:56:03 -070097 byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, byteArraySize);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080098 }
Elliott Hughes0808cae2010-04-23 16:15:38 -070099 if (byteArraySize == 0) {
100 return NULL;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800101 }
Elliott Hughes0808cae2010-04-23 16:15:38 -0700102 jbyteArray result = env->NewByteArray(byteArraySize);
103 env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray));
104 return result;
105}
106
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700107static jint NativeCollation_next(JNIEnv* env, jclass, jlong address) {
Elliott Hughesebe438a2010-03-26 14:46:11 -0700108 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700109 jint result = ucol_next(toCollationElements(address), &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700110 maybeThrowIcuException(env, "ucol_next", status);
Elliott Hughesebe438a2010-03-26 14:46:11 -0700111 return result;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800112}
113
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700114static jlong NativeCollation_openCollator(JNIEnv* env, jclass, jstring localeName) {
Elliott Hughes0808cae2010-04-23 16:15:38 -0700115 ScopedUtfChars localeChars(env, localeName);
Elliott Hughes05960872010-05-26 17:45:07 -0700116 if (localeChars.c_str() == NULL) {
117 return 0;
118 }
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700119 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700120 UCollator* c = ucol_open(localeChars.c_str(), &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700121 maybeThrowIcuException(env, "ucol_open", status);
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700122 return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
Elliott Hughes0808cae2010-04-23 16:15:38 -0700123}
124
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700125static jlong NativeCollation_openCollatorFromRules(JNIEnv* env, jclass, jstring javaRules, jint mode, jint strength) {
Elliott Hughesfe711d62011-04-22 15:56:03 -0700126 ScopedStringChars rules(env, javaRules);
127 if (rules.get() == NULL) {
128 return -1;
129 }
Elliott Hughes0808cae2010-04-23 16:15:38 -0700130 UErrorCode status = U_ZERO_ERROR;
Elliott Hughesfe711d62011-04-22 15:56:03 -0700131 UCollator* c = ucol_openRules(rules.get(), rules.size(),
Elliott Hughes0808cae2010-04-23 16:15:38 -0700132 UColAttributeValue(mode), UCollationStrength(strength), NULL, &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700133 maybeThrowIcuException(env, "ucol_openRules", status);
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700134 return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
Elliott Hughes0808cae2010-04-23 16:15:38 -0700135}
136
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700137static jint NativeCollation_previous(JNIEnv* env, jclass, jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -0700138 UErrorCode status = U_ZERO_ERROR;
139 jint result = ucol_previous(toCollationElements(address), &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700140 maybeThrowIcuException(env, "ucol_previous", status);
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700141 return result;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800142}
143
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700144static void NativeCollation_reset(JNIEnv*, jclass, jlong address) {
Elliott Hughes0808cae2010-04-23 16:15:38 -0700145 ucol_reset(toCollationElements(address));
146}
147
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700148static jlong NativeCollation_safeClone(JNIEnv* env, jclass, jlong address) {
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800149 UErrorCode status = U_ZERO_ERROR;
Elliott Hughesbf6f2af2013-10-07 11:44:07 -0700150 UCollator* c = ucol_safeClone(toCollator(address), NULL, NULL, &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700151 maybeThrowIcuException(env, "ucol_safeClone", status);
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700152 return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
Elliott Hughes0808cae2010-04-23 16:15:38 -0700153}
154
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700155static void NativeCollation_setAttribute(JNIEnv* env, jclass, jlong address, jint type, jint value) {
Elliott Hughes0808cae2010-04-23 16:15:38 -0700156 UErrorCode status = U_ZERO_ERROR;
157 ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700158 maybeThrowIcuException(env, "ucol_setAttribute", status);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800159}
160
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700161static void NativeCollation_setOffset(JNIEnv* env, jclass, jlong address, jint offset) {
Elliott Hughes9a00adf2009-10-05 16:01:35 -0700162 UErrorCode status = U_ZERO_ERROR;
Elliott Hughes0808cae2010-04-23 16:15:38 -0700163 ucol_setOffset(toCollationElements(address), offset, &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700164 maybeThrowIcuException(env, "ucol_setOffset", status);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800165}
166
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700167static void NativeCollation_setText(JNIEnv* env, jclass, jlong address, jstring javaSource) {
Elliott Hughesfe711d62011-04-22 15:56:03 -0700168 ScopedStringChars source(env, javaSource);
169 if (source.get() == NULL) {
170 return;
171 }
Elliott Hughes0808cae2010-04-23 16:15:38 -0700172 UErrorCode status = U_ZERO_ERROR;
Elliott Hughesfe711d62011-04-22 15:56:03 -0700173 ucol_setText(toCollationElements(address), source.get(), source.size(), &status);
Elliott Hughes5ec69b22012-07-23 16:32:51 -0700174 maybeThrowIcuException(env, "ucol_setText", status);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800175}
176
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800177static JNINativeMethod gMethods[] = {
Elliott Hughes1e5d7302013-04-22 17:01:52 -0700178 NATIVE_METHOD(NativeCollation, closeCollator, "(J)V"),
179 NATIVE_METHOD(NativeCollation, closeElements, "(J)V"),
180 NATIVE_METHOD(NativeCollation, compare, "(JLjava/lang/String;Ljava/lang/String;)I"),
181 NATIVE_METHOD(NativeCollation, getAttribute, "(JI)I"),
182 NATIVE_METHOD(NativeCollation, getCollationElementIterator, "(JLjava/lang/String;)I"),
183 NATIVE_METHOD(NativeCollation, getMaxExpansion, "(JI)I"),
184 NATIVE_METHOD(NativeCollation, getOffset, "(J)I"),
185 NATIVE_METHOD(NativeCollation, getRules, "(J)Ljava/lang/String;"),
186 NATIVE_METHOD(NativeCollation, getSortKey, "(JLjava/lang/String;)[B"),
187 NATIVE_METHOD(NativeCollation, next, "(J)I"),
188 NATIVE_METHOD(NativeCollation, openCollator, "(Ljava/lang/String;)J"),
189 NATIVE_METHOD(NativeCollation, openCollatorFromRules, "(Ljava/lang/String;II)J"),
190 NATIVE_METHOD(NativeCollation, previous, "(J)I"),
191 NATIVE_METHOD(NativeCollation, reset, "(J)V"),
192 NATIVE_METHOD(NativeCollation, safeClone, "(J)J"),
193 NATIVE_METHOD(NativeCollation, setAttribute, "(JII)V"),
194 NATIVE_METHOD(NativeCollation, setOffset, "(JI)V"),
195 NATIVE_METHOD(NativeCollation, setText, "(JLjava/lang/String;)V"),
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800196};
Elliott Hughes7cd67602012-05-03 17:21:04 -0700197void register_libcore_icu_NativeCollation(JNIEnv* env) {
198 jniRegisterNativeMethods(env, "libcore/icu/NativeCollation", gMethods, NELEM(gMethods));
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800199}