1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*******************************************************************************
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* Copyright (C) 1996-2005, International Business Machines Corporation and    *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* others. All Rights Reserved.                                                *
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*******************************************************************************
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*******************************************************************************
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10757a7942eed2b0aa457f8517a0259d2ac82c5b18Elliott Hughes#define LOG_TAG "NativeCollation"
11757a7942eed2b0aa457f8517a0259d2ac82c5b18Elliott Hughes
123aac4ddc4d17c07fa8b4908069d23d5401a77993Elliott Hughes#include "IcuUtilities.h"
130808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes#include "JNIHelp.h"
14e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes#include "JniConstants.h"
15bef9ec33e1368f57c731fce63b6a8c61628c64b0Elliott Hughes#include "JniException.h"
16fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes#include "ScopedStringChars.h"
170808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes#include "ScopedUtfChars.h"
180808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes#include "UniquePtr.h"
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "unicode/ucol.h"
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "unicode/ucoleitr.h"
21e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath#include <cutils/log.h>
22e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
23e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath// Manages a UCollationElements instance along with the jchar
24e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath// array it is iterating over. The associated array can be unpinned
25e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath// only after a call to ucol_closeElements. This means we have to
26e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath// keep a reference to the string (so that it isn't collected) and
27e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath// make a call to GetStringChars to ensure the underlying array is
28e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath// pinned.
29e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamathclass CollationElements {
30e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamathpublic:
31e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    CollationElements()
32e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        : mElements(NULL), mString(NULL), mChars(NULL) {
33e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    }
34e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
35e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    UCollationElements* get() const {
36e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        return mElements;
37e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    }
38e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
39e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    // Starts a new iteration sequence over the string |string|. If
40e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    // we have a valid UCollationElements object, we call ucol_setText
41e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    // on it. Otherwise, we create a new object with the specified
42e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    // collator.
43e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    UErrorCode start(JNIEnv* env, jstring string, UCollator* collator) {
44e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        release(env, false /* don't close the collator */);
45e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        mChars = env->GetStringChars(string, NULL);
46e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        if (mChars != NULL) {
47e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            mString = static_cast<jstring>(env->NewGlobalRef(string));
48e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            const size_t size = env->GetStringLength(string);
49e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
50e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            UErrorCode status = U_ZERO_ERROR;
51e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            // If we don't have a UCollationElements object yet, create
52e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            // a new one. If we do, reset it.
53e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            if (mElements == NULL) {
54e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath                mElements = ucol_openElements(collator, mChars, size, &status);
55e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            } else {
56e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath               ucol_setText(mElements, mChars, size, &status);
57e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            }
58e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
59e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            return status;
60e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        }
61e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
62e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        return U_ILLEGAL_ARGUMENT_ERROR;
63e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    }
64e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
65e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    void release(JNIEnv* env, bool closeCollator) {
66e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        if (mElements != NULL && closeCollator) {
67e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            ucol_closeElements(mElements);
68e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        }
69e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
70e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        if (mChars != NULL) {
71e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            env->ReleaseStringChars(mString, mChars);
72e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            env->DeleteGlobalRef(mString);
73e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            mChars = NULL;
74e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath            mString = NULL;
75e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        }
76e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    }
77e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
78e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamathprivate:
79e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    UCollationElements* mElements;
80e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    jstring mString;
81e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    const jchar* mChars;
82e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath};
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
841e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic UCollator* toCollator(jlong address) {
850808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    return reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address));
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamathstatic CollationElements* toCollationElements(jlong address) {
89e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    return reinterpret_cast<CollationElements*>(static_cast<uintptr_t>(address));
900808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes}
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
921e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic void NativeCollation_closeCollator(JNIEnv*, jclass, jlong address) {
930808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    ucol_close(toCollator(address));
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
96e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamathstatic void NativeCollation_closeElements(JNIEnv* env, jclass, jlong address) {
97e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    CollationElements* elements = toCollationElements(address);
98e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    elements->release(env, true /* close collator */);
99e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    delete elements;
1000808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes}
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1021e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jint NativeCollation_compare(JNIEnv* env, jclass, jlong address, jstring javaLhs, jstring javaRhs) {
103fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    ScopedStringChars lhs(env, javaLhs);
104fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    if (lhs.get() == NULL) {
105f08498e4998c3b7197cb31a9fc44910bfd4eeeccDoug Kwan        return 0;
106fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    }
107fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    ScopedStringChars rhs(env, javaRhs);
108fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    if (rhs.get() == NULL) {
109f08498e4998c3b7197cb31a9fc44910bfd4eeeccDoug Kwan        return 0;
110fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    }
111fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    return ucol_strcoll(toCollator(address), lhs.get(), lhs.size(), rhs.get(), rhs.size());
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1141e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jint NativeCollation_getAttribute(JNIEnv* env, jclass, jlong address, jint type) {
115ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes    UErrorCode status = U_ZERO_ERROR;
1160808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status);
1175ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_getAttribute", status);
118ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes    return result;
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1211e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jlong NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jlong address, jstring javaSource) {
122fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    ScopedStringChars source(env, javaSource);
123fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    if (source.get() == NULL) {
124fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes        return -1;
125fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    }
126e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
127e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    UniquePtr<CollationElements> ce(new CollationElements);
128e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    UErrorCode status = ce->start(env, javaSource, toCollator(address));
1295ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_openElements", status);
130e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    if (status == U_ZERO_ERROR) {
131e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath        return static_cast<jlong>(reinterpret_cast<uintptr_t>(ce.release()));
132e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    }
133e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath
134e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    return 0L;
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1371e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jint NativeCollation_getMaxExpansion(JNIEnv*, jclass, jlong address, jint order) {
138e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    return ucol_getMaxExpansion(toCollationElements(address)->get(), order);
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1411e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jint NativeCollation_getOffset(JNIEnv*, jclass, jlong address) {
142e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    return ucol_getOffset(toCollationElements(address)->get());
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1451e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jstring NativeCollation_getRules(JNIEnv* env, jclass, jlong address) {
1460808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    int32_t length = 0;
1470808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    const UChar* rules = ucol_getRules(toCollator(address), &length);
1480808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    return env->NewString(rules, length);
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1511e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jlong address, jstring javaSource) {
152fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    ScopedStringChars source(env, javaSource);
153fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    if (source.get() == NULL) {
154fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes        return NULL;
155fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    }
1560808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    const UCollator* collator  = toCollator(address);
15709adf7b54b3ce9959a588a6bec99e2468cded924ccornelius    // The buffer size prevents reallocation for most strings.
15809adf7b54b3ce9959a588a6bec99e2468cded924ccornelius    uint8_t byteArray[128];
1590808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    UniquePtr<uint8_t[]> largerByteArray;
160acce5ff29455054faa08a10e1486a156b9d1553eElliott Hughes    uint8_t* usedByteArray = byteArray;
161fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    size_t byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, sizeof(byteArray) - 1);
1620808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    if (byteArraySize > sizeof(byteArray) - 1) {
1630808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes        // didn't fit, try again with a larger buffer.
1640808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes        largerByteArray.reset(new uint8_t[byteArraySize + 1]);
1650808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes        usedByteArray = largerByteArray.get();
166fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes        byteArraySize = ucol_getSortKey(collator, source.get(), source.size(), usedByteArray, byteArraySize);
1670808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    }
1680808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    if (byteArraySize == 0) {
1690808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes        return NULL;
1700808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    }
1710808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    jbyteArray result = env->NewByteArray(byteArraySize);
1720808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray));
1730808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    return result;
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1761e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jint NativeCollation_next(JNIEnv* env, jclass, jlong address) {
1779a00adf0909dcee2fad1d21379073fd64129f268Elliott Hughes    UErrorCode status = U_ZERO_ERROR;
178e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    jint result = ucol_next(toCollationElements(address)->get(), &status);
1795ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_next", status);
1809a00adf0909dcee2fad1d21379073fd64129f268Elliott Hughes    return result;
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183a94266074c7b82720fd2cecfb37ab8da85f1b296Elliott Hughesstatic jlong NativeCollation_openCollator(JNIEnv* env, jclass, jstring javaLocaleName) {
184a94266074c7b82720fd2cecfb37ab8da85f1b296Elliott Hughes    ScopedUtfChars localeChars(env, javaLocaleName);
18505960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    if (localeChars.c_str() == NULL) {
18605960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes        return 0;
18705960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    }
188a94266074c7b82720fd2cecfb37ab8da85f1b296Elliott Hughes
1899a00adf0909dcee2fad1d21379073fd64129f268Elliott Hughes    UErrorCode status = U_ZERO_ERROR;
1900808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    UCollator* c = ucol_open(localeChars.c_str(), &status);
1915ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_open", status);
1921e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1951e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jlong NativeCollation_openCollatorFromRules(JNIEnv* env, jclass, jstring javaRules, jint mode, jint strength) {
196fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    ScopedStringChars rules(env, javaRules);
197fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    if (rules.get() == NULL) {
198fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes        return -1;
199fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    }
2009a00adf0909dcee2fad1d21379073fd64129f268Elliott Hughes    UErrorCode status = U_ZERO_ERROR;
201fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    UCollator* c = ucol_openRules(rules.get(), rules.size(),
2020808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes            UColAttributeValue(mode), UCollationStrength(strength), NULL, &status);
2035ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_openRules", status);
2041e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2071e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jint NativeCollation_previous(JNIEnv* env, jclass, jlong address) {
2080808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    UErrorCode status = U_ZERO_ERROR;
209e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    jint result = ucol_previous(toCollationElements(address)->get(), &status);
2105ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_previous", status);
2110808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    return result;
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2141e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic void NativeCollation_reset(JNIEnv*, jclass, jlong address) {
215e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    ucol_reset(toCollationElements(address)->get());
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2181e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic jlong NativeCollation_safeClone(JNIEnv* env, jclass, jlong address) {
2190808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    UErrorCode status = U_ZERO_ERROR;
220bf6f2afa0a56b417ef3e49a5aa3d6df937be6449Elliott Hughes    UCollator* c = ucol_safeClone(toCollator(address), NULL, NULL, &status);
2215ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_safeClone", status);
2221e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    return static_cast<jlong>(reinterpret_cast<uintptr_t>(c));
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2251e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic void NativeCollation_setAttribute(JNIEnv* env, jclass, jlong address, jint type, jint value) {
226ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes    UErrorCode status = U_ZERO_ERROR;
2270808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status);
2285ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_setAttribute", status);
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2311e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic void NativeCollation_setOffset(JNIEnv* env, jclass, jlong address, jint offset) {
2320808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes    UErrorCode status = U_ZERO_ERROR;
233e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    ucol_setOffset(toCollationElements(address)->get(), offset, &status);
2345ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_setOffset", status);
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2371e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughesstatic void NativeCollation_setText(JNIEnv* env, jclass, jlong address, jstring javaSource) {
238fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    ScopedStringChars source(env, javaSource);
239fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    if (source.get() == NULL) {
240fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes        return;
241fe711d61cafbb878d1d6a5e223fcd2201f2e829aElliott Hughes    }
242e43ee5033562120d6d47bd805df769167b62ab51Narayan Kamath    UErrorCode status = toCollationElements(address)->start(env, javaSource, NULL);
2435ec69b20ab9b3e2dcbe225d548168b09afbbbac2Elliott Hughes    maybeThrowIcuException(env, "ucol_setText", status);
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic JNINativeMethod gMethods[] = {
2471e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, closeCollator, "(J)V"),
2481e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, closeElements, "(J)V"),
2491e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, compare, "(JLjava/lang/String;Ljava/lang/String;)I"),
2501e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, getAttribute, "(JI)I"),
251df40b4ad7268a13dff0852f70451a48b59149221Elliott Hughes    NATIVE_METHOD(NativeCollation, getCollationElementIterator, "(JLjava/lang/String;)J"),
2521e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, getMaxExpansion, "(JI)I"),
2531e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, getOffset, "(J)I"),
2541e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, getRules, "(J)Ljava/lang/String;"),
2551e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, getSortKey, "(JLjava/lang/String;)[B"),
2561e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, next, "(J)I"),
2571e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, openCollator, "(Ljava/lang/String;)J"),
2581e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, openCollatorFromRules, "(Ljava/lang/String;II)J"),
2591e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, previous, "(J)I"),
2601e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, reset, "(J)V"),
2611e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, safeClone, "(J)J"),
2621e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, setAttribute, "(JII)V"),
2631e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, setOffset, "(JI)V"),
2641e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes    NATIVE_METHOD(NativeCollation, setText, "(JLjava/lang/String;)V"),
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project};
2667cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughesvoid register_libcore_icu_NativeCollation(JNIEnv* env) {
2677cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes    jniRegisterNativeMethods(env, "libcore/icu/NativeCollation", gMethods, NELEM(gMethods));
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
269