diff options
-rw-r--r-- | icu/src/main/java/com/ibm/icu4jni/text/Collator.java | 80 | ||||
-rw-r--r-- | icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java | 17 | ||||
-rw-r--r-- | icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java | 83 | ||||
-rw-r--r-- | icu/src/main/native/ICU.cpp | 4 | ||||
-rw-r--r-- | icu/src/main/native/NativeBreakIterator.cpp | 4 | ||||
-rw-r--r-- | icu/src/main/native/NativeCollation.cpp | 532 | ||||
-rw-r--r-- | icu/src/main/native/NativeConverter.cpp | 8 | ||||
-rw-r--r-- | icu/src/main/native/UCharacter.cpp | 4 | ||||
-rw-r--r-- | include/ScopedUtfChars.h | 2 | ||||
-rw-r--r-- | text/src/main/java/java/text/Collator.java | 5 |
10 files changed, 124 insertions, 615 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/Collator.java b/icu/src/main/java/com/ibm/icu4jni/text/Collator.java index 7883d30..9eb85ea 100644 --- a/icu/src/main/java/com/ibm/icu4jni/text/Collator.java +++ b/icu/src/main/java/com/ibm/icu4jni/text/Collator.java @@ -13,64 +13,6 @@ package com.ibm.icu4jni.text; import com.ibm.icu4jni.text.RuleBasedCollator; import java.util.Locale; -/** -* Abstract class handling locale specific collation via JNI and ICU. -* Subclasses implement specific collation strategies. One subclass, -* com.ibm.icu4jni.text.RuleBasedCollator, is currently provided and is -* applicable to a wide set of languages. Other subclasses may be created to -* handle more specialized needs. -* You can use the static factory method, getInstance(), to obtain the -* appropriate Collator object for a given locale. -* -* <pre> -* // Compare two strings in the default locale -* Collator myCollator = Collator.getInstance(); -* if (myCollator.compare("abc", "ABC") < 0) { -* System.out.println("abc is less than ABC"); -* } -* else { -* System.out.println("abc is greater than or equal to ABC"); -* } -* </pre> -* -* You can set a Collator's strength property to determine the level of -* difference considered significant in comparisons. -* Five strengths in CollationAttribute are provided: VALUE_PRIMARY, -* VALUE_SECONDARY, VALUE_TERTIARY, VALUE_QUATERNARY and VALUE_IDENTICAL. -* The exact assignment of strengths to language features is locale-dependent. -* For example, in Czech, "e" and "f" are considered primary differences, while -* "e" and "?" latin small letter e with circumflex are secondary differences, -* "e" and "E" are tertiary differences and "e" and "e" are identical. -* -* <p> -* The following shows how both case and accents could be ignored for US -* English. -* <pre> -* //Get the Collator for US English and set its strength to PRIMARY -* Collator usCollator = Collator.getInstance(Locale.US); -* usCollator.setStrength(Collator.PRIMARY); -* if (usCollator.compare("abc", "ABC") == 0) { -* System.out.println("Strings are equivalent"); -* } -* </pre> -* For comparing Strings exactly once, the compare method provides the best -* performance. -* When sorting a list of Strings however, it is generally necessary to compare -* each String multiple times. -* In this case, com.ibm.icu4jni.text.CollationKey provide better performance. -* The CollationKey class converts a String to a series of bits that can be -* compared bitwise against other CollationKeys. -* A CollationKey is created by a Collator object for a given String. -* Note: CollationKeys from different Collators can not be compared. -* </p> -* -* Considerations : -* 1) ErrorCode not returned to user throw exceptions instead -* 2) Similar API to java.text.Collator -* @author syn wee quek -* @stable ICU 2.4 -*/ - public abstract class Collator implements Cloneable { /** * Strongest collator strength value. Typically used to denote differences @@ -164,28 +106,8 @@ public abstract class Collator implements Cloneable { */ public final static int CANONICAL_DECOMPOSITION = CollationAttribute.VALUE_ON; - public static Collator getInstance() { - return getInstance(null); - } - - /** - * Factory method to create an appropriate Collator which uses the given - * locale's collation rules.<br> - * Current implementation createInstance() returns a RuleBasedCollator(Locale) - * instance. The RuleBasedCollator will be created in the following order, - * <ul> - * <li> Data from argument locale resource bundle if found, otherwise - * <li> Data from parent locale resource bundle of given locale if found, otherwise - * <li> Data from built-in default collation rules if found, other - * <li> null is returned - * </ul> - * @param locale to be used for collation - * @return an instance of Collator - * @stable ICU 2.4 - */ public static Collator getInstance(Locale locale) { - RuleBasedCollator result = new RuleBasedCollator(locale); - return result; + return new RuleBasedCollator(locale); } public boolean equals(String source, String target) { diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java index fbdcf93..d481790 100644 --- a/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java +++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java @@ -23,14 +23,7 @@ final class NativeCollation public NativeCollation() { } - - /** - * Method to create a new C Collator using the default locale rules. - * @return new c collator - * @internal ICU 2.4 - */ - static native int openCollator(); - + /** * Method to create a new C Collator using the argument locale rules. * @param locale locale name @@ -160,14 +153,6 @@ final class NativeCollation */ static native int getCollationElementIterator(int collatoraddress, String source); - - /** - * Returns a hash of this collation object - * @param collatoraddress address of C collator - * @return hash of this collation object - * @internal ICU 2.4 - */ - static native int hashCode(int collatoraddress); // collationelementiterator methods ------------------------------------- diff --git a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java index 3135daa..8e048dd 100644 --- a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java +++ b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java @@ -454,20 +454,6 @@ public final class RuleBasedCollator extends Collator { return NativeCollation.getAttribute(m_collator_, type); } - /** - * Get the sort key as an CollationKey object from the argument string. - * To retrieve sort key in terms of byte arrays, use the method as below<br> - * <br> - * <code> - * Collator collator = Collator.getInstance(); - * byte[] array = collator.getSortKey(source); - * </code><br> - * Byte array result are zero-terminated and can be compared using - * java.util.Arrays.equals(); - * @param source string to be processed. - * @return the sort key - * @stable ICU 2.4 - */ public CollationKey getCollationKey(String source) { if (source == null) { return null; @@ -480,17 +466,6 @@ public final class RuleBasedCollator extends Collator { } /** - * Get a sort key for the argument string - * Sort keys may be compared using java.util.Arrays.equals - * @param source string for key to be generated - * @return sort key - * @stable ICU 2.4 - */ - public byte[] getSortKey(String source) { - return NativeCollation.getSortKey(m_collator_, source); - } - - /** * Get the collation rules of this Collation object * The rules will follow the rule syntax. * @return collation rules. @@ -529,21 +504,9 @@ public final class RuleBasedCollator extends Collator { return result.toString(); } - /** - * Returns a hash of this collation object - * Note this method is not complete, it only returns 0 at the moment. - * @return hash of this collation object - * @stable ICU 2.4 - */ + @Override public int hashCode() { - // since rules do not change once it is created, we can cache the hash - if (m_hashcode_ == 0) { - m_hashcode_ = NativeCollation.hashCode(m_collator_); - if (m_hashcode_ == 0) { - m_hashcode_ = 1; - } - } - return m_hashcode_; + return 42; // No-one uses RuleBasedCollator as a hash key. } /** @@ -565,50 +528,16 @@ public final class RuleBasedCollator extends Collator { getDecomposition() == rhs.getDecomposition(); } - /** - * RuleBasedCollator default constructor. This constructor takes the default - * locale. The only caller of this class should be Collator.getInstance(). - * Current implementation createInstance() returns a RuleBasedCollator(Locale) - * instance. The RuleBasedCollator will be created in the following order, - * <ul> - * <li> Data from argument locale resource bundle if found, otherwise - * <li> Data from parent locale resource bundle of arguemtn locale if found, - * otherwise - * <li> Data from built-in default collation rules if found, other - * <li> null is returned - * </ul> - */ - RuleBasedCollator() { - m_collator_ = NativeCollation.openCollator(); - } - - /** - * RuleBasedCollator constructor. This constructor takes a locale. The - * only caller of this class should be Collator.createInstance(). - * Current implementation createInstance() returns a RuleBasedCollator(Locale) - * instance. The RuleBasedCollator will be created in the following order, - * <ul> - * <li> Data from argument locale resource bundle if found, otherwise - * <li> Data from parent locale resource bundle of arguemtn locale if found, - * otherwise - * <li> Data from built-in default collation rules if found, other - * <li> null is returned - * </ul> - * @param locale locale used - */ RuleBasedCollator(Locale locale) { - if (locale == null) { - m_collator_ = NativeCollation.openCollator(); - } else { - m_collator_ = NativeCollation.openCollator(locale.toString()); - } + m_collator_ = NativeCollation.openCollator(locale.toString()); } + @Override protected void finalize() { NativeCollation.closeCollator(m_collator_); } - private RuleBasedCollator(int collatoraddress) { - m_collator_ = collatoraddress; + private RuleBasedCollator(int addr) { + m_collator_ = addr; } } diff --git a/icu/src/main/native/ICU.cpp b/icu/src/main/native/ICU.cpp index 1517932..4f08513 100644 --- a/icu/src/main/native/ICU.cpp +++ b/icu/src/main/native/ICU.cpp @@ -70,7 +70,7 @@ private: }; static Locale getLocale(JNIEnv* env, jstring localeName) { - return Locale::createFromName(ScopedUtfChars(env, localeName).data()); + return Locale::createFromName(ScopedUtfChars(env, localeName).c_str()); } static jint getCurrencyFractionDigitsNative(JNIEnv* env, jclass, jstring currencyCode) { @@ -528,7 +528,7 @@ static jstring getIntCurrencyCode(JNIEnv* env, jstring locale) { ScopedUtfChars localeChars(env, locale); // Extract the 2-character country name. - if (strlen(localeChars.data()) < 5) { + if (strlen(localeChars.c_str()) < 5) { return NULL; } if (localeChars[3] < 'A' || localeChars[3] > 'Z' || localeChars[4] < 'A' || localeChars[4] > 'Z') { diff --git a/icu/src/main/native/NativeBreakIterator.cpp b/icu/src/main/native/NativeBreakIterator.cpp index 85ada2d..0be7630 100644 --- a/icu/src/main/native/NativeBreakIterator.cpp +++ b/icu/src/main/native/NativeBreakIterator.cpp @@ -26,10 +26,10 @@ static jint getIterator(JNIEnv* env, jstring locale, UBreakIteratorType type) { UErrorCode status = U_ZERO_ERROR; ScopedUtfChars localeChars(env, locale); - if (!localeChars.data()) { + if (!localeChars.c_str()) { return 0; } - UBreakIterator* it = ubrk_open(type, localeChars.data(), NULL, 0, &status); + UBreakIterator* it = ubrk_open(type, localeChars.c_str(), NULL, 0, &status); icu4jni_error(env, status); return reinterpret_cast<uintptr_t>(it); } diff --git a/icu/src/main/native/NativeCollation.cpp b/icu/src/main/native/NativeCollation.cpp index 263a525..9a092e8 100644 --- a/icu/src/main/native/NativeCollation.cpp +++ b/icu/src/main/native/NativeCollation.cpp @@ -9,497 +9,170 @@ #define LOG_TAG "NativeCollation" -#include "JNIHelp.h" #include "ErrorCode.h" +#include "JNIHelp.h" +#include "ScopedJavaUnicodeString.h" +#include "ScopedUtfChars.h" +#include "UniquePtr.h" +#include "ucol_imp.h" #include "unicode/ucol.h" #include "unicode/ucoleitr.h" -#include "ucol_imp.h" - -/** -* Closing a C UCollator with the argument locale rules. -* Note determining if a collator currently exist for the caller is to be handled -* by the caller. Hence if the caller has a existing collator, it is his -* responsibility to delete first before calling this method. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of the C UCollator -*/ -static void closeCollator(JNIEnv *env, jclass obj, - jint address) { - - UCollator *collator = (UCollator *)(int)address; - ucol_close(collator); +static UCollator* toCollator(jint address) { + return reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address)); } +static UCollationElements* toCollationElements(jint address) { + return reinterpret_cast<UCollationElements*>(static_cast<uintptr_t>(address)); +} -/** -* Close a C collation element iterator. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of C collation element iterator to close. -*/ -static void closeElements(JNIEnv *env, jclass obj, - jint address) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - ucol_closeElements(iterator); +static void closeCollator(JNIEnv* env, jclass, jint address) { + ucol_close(toCollator(address)); } -/** -* Compare two strings. -* The strings will be compared using the normalization mode and options -* specified in openCollator or openCollatorFromRules -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address address of the c collator -* @param source The source string. -* @param target The target string. -* @return result of the comparison, UCOL_EQUAL, UCOL_GREATER or UCOL_LESS -*/ -static jint compare(JNIEnv *env, jclass obj, jint address, - jstring source, jstring target) { +static void closeElements(JNIEnv* env, jclass, jint address) { + ucol_closeElements(toCollationElements(address)); +} - const UCollator *collator = (const UCollator *)(int)address; - jint result = -2; - if(collator){ - jsize srcLength = env->GetStringLength(source); - const UChar *chars = (const UChar *) env->GetStringCritical(source,0); - if(chars){ - jsize tgtlength = env->GetStringLength(target); - const UChar *tgtstr = (const UChar *) env->GetStringCritical(target,0); - if(tgtstr){ - result = ucol_strcoll(collator, chars, srcLength, tgtstr, tgtlength); - env->ReleaseStringCritical(source, chars); - env->ReleaseStringCritical(target, tgtstr); - return result; - }else{ - icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR); - } - }else{ - icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR); - } - }else{ - icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR); - } - return result; +static jint compare(JNIEnv* env, jclass, jint address, jstring lhs0, jstring rhs0) { + ScopedJavaUnicodeString lhs(env, lhs0); + ScopedJavaUnicodeString rhs(env, rhs0); + return ucol_strcoll(toCollator(address), + lhs.unicodeString().getBuffer(), lhs.unicodeString().length(), + rhs.unicodeString().getBuffer(), rhs.unicodeString().length()); } -static jint getAttribute(JNIEnv *env, jclass, jint address, jint type) { - const UCollator *collator = (const UCollator *)(int)address; - if (!collator) { - icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR); - return 0; - } +static jint getAttribute(JNIEnv* env, jclass, jint address, jint type) { UErrorCode status = U_ZERO_ERROR; - jint result = (jint)ucol_getAttribute(collator, (UColAttribute)type, &status); + jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status); icu4jni_error(env, status); return result; } -/** -* Create a CollationElementIterator object that will iterator over the elements -* in a string, using the collation rules defined in this RuleBasedCollatorJNI -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address address of C collator -* @param source string to iterate over -* @return address of C collationelement -*/ -static jint getCollationElementIterator(JNIEnv *env, - jclass obj, jint address, jstring source) { - - UErrorCode status = U_ZERO_ERROR; - UCollator *collator = (UCollator *)(int)address; - jint result=0; - if(collator){ - jsize srcLength = env->GetStringLength(source); - const UChar *chars = (const UChar *) env->GetStringCritical(source,0); - if(chars){ - result = (jint)(ucol_openElements(collator, chars, srcLength, &status)); - - env->ReleaseStringCritical(source, chars); - icu4jni_error(env, status); - }else{ - icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR); - } - }else{ - icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR); - } - return result; +static jint getCollationElementIterator(JNIEnv* env, jclass, jint address, jstring source0) { + ScopedJavaUnicodeString source(env, source0); + UErrorCode status = U_ZERO_ERROR; + UCollationElements* result = ucol_openElements(toCollator(address), + source.unicodeString().getBuffer(), source.unicodeString().length(), &status); + icu4jni_error(env, status); + return static_cast<jint>(reinterpret_cast<uintptr_t>(result)); } -/** -* Get the maximum length of any expansion sequences that end with the specified -* comparison order. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of the C collation element iterator containing the text. -* @param order collation order returned by previous or next. -* @return maximum length of any expansion sequences ending with the specified -* order or 1 if collation order does not occur at the end of any -* expansion sequence. -*/ -static jint getMaxExpansion(JNIEnv *env, jclass obj, - jint address, jint order) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - return ucol_getMaxExpansion(iterator, order); +static jint getMaxExpansion(JNIEnv* env, jclass, jint address, jint order) { + return ucol_getMaxExpansion(toCollationElements(address), order); } -/** -* Get the normalization mode for this object. -* The normalization mode influences how strings are compared. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of C collator -* @return normalization mode; one of the values from NormalizerEnum -*/ -static jint getNormalization(JNIEnv *env, jclass obj, - jint address) { - - const UCollator* collator = (const UCollator*) address; +static jint getNormalization(JNIEnv* env, jclass, jint address) { UErrorCode status = U_ZERO_ERROR; - jint result = ucol_getAttribute(collator, UCOL_NORMALIZATION_MODE, &status); + jint result = ucol_getAttribute(toCollator(address), UCOL_NORMALIZATION_MODE, &status); icu4jni_error(env, status); return result; } -/** -* Set the normalization mode for this object. -* The normalization mode influences how strings are compared. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of C collator -* @param mode the normalization mode -*/ -static void setNormalization(JNIEnv *env, jclass, jint address, jint mode) { - UCollator* collator = reinterpret_cast<UCollator*>(static_cast<uintptr_t>(address)); +static void setNormalization(JNIEnv* env, jclass, jint address, jint mode) { UErrorCode status = U_ZERO_ERROR; - ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UColAttributeValue(mode), &status); + ucol_setAttribute(toCollator(address), UCOL_NORMALIZATION_MODE, UColAttributeValue(mode), &status); icu4jni_error(env, status); } - -/** -* Get the offset of the current source character. -* This is an offset into the text of the character containing the current -* collation elements. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param addresss of the C collation elements iterator to query. -* @return offset of the current source character. -*/ -static jint getOffset(JNIEnv *env, jclass obj, jint address) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - return ucol_getOffset(iterator); -} - -/** -* Get the collation rules from a UCollator. -* The rules will follow the rule syntax. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address the address of the C collator -* @return collation rules. -*/ -static jstring getRules(JNIEnv *env, jclass obj, - jint address) { - - const UCollator *collator = (const UCollator *)(int)address; - int32_t length=0; - const UChar *rules = ucol_getRules(collator, &length); - return env->NewString(rules, length); +static jint getOffset(JNIEnv* env, jclass, jint address) { + return ucol_getOffset(toCollationElements(address)); } -/** -* Get a sort key for the argument string -* Sort keys may be compared using java.util.Arrays.equals -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address address of the C collator -* @param source string for key to be generated -* @return sort key -*/ -static jbyteArray getSortKey(JNIEnv *env, jclass obj, - jint address, jstring source) { - - const UCollator *collator = (const UCollator *)(int)address; - jbyteArray result = NULL; - if(collator && source){ - // BEGIN android-added - if(!source) { - return NULL; - } - // END android-added - jsize srcLength = env->GetStringLength(source); - const UChar *chars = (const UChar *) env->GetStringCritical(source, 0); - if (chars){ -// BEGIN android-changed - uint8_t byteArray[UCOL_MAX_BUFFER * 2]; - uint8_t *largerByteArray = NULL; - uint8_t *usedByteArray = byteArray; - - size_t byteArraySize = ucol_getSortKey(collator, chars, srcLength, byteArray, - sizeof(byteArray) - 1); - - if (byteArraySize > sizeof(byteArray) - 1) { - // didn't fit, try again with a larger buffer. - largerByteArray = new uint8_t[byteArraySize + 1]; - usedByteArray = largerByteArray; - byteArraySize = ucol_getSortKey(collator, chars, srcLength, largerByteArray, - byteArraySize); - } - - env->ReleaseStringCritical(source, chars); - - if (byteArraySize == 0) { - delete[] largerByteArray; - return NULL; - } - - /* no problem converting uint8_t to int8_t, gives back the correct value - * tried and tested - */ - result = env->NewByteArray(byteArraySize); - env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray)); - delete[] largerByteArray; -// END android-changed - }else{ - icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR); - } - }else{ - icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR); - } - return result; +static jstring getRules(JNIEnv* env, jclass, jint address) { + int32_t length = 0; + const UChar* rules = ucol_getRules(toCollator(address), &length); + return env->NewString(rules, length); } -/** -* Returns a hash of this collation object -* Note this method is not complete, it only returns 0 at the moment. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address address of C collator -* @return hash of this collation object -*/ -static jint hashCode(JNIEnv *env, jclass obj, jint address) { - - UCollator *collator = (UCollator *)(int)address; - int32_t length=0; - const UChar *rules = ucol_getRules(collator, &length); - /* temporary commented out - * return uhash_hashUCharsN(rules, length); - */ - return 0; +static jbyteArray getSortKey(JNIEnv* env, jclass, jint address, jstring source0) { + ScopedJavaUnicodeString source(env, source0); + const UCollator* collator = toCollator(address); + uint8_t byteArray[UCOL_MAX_BUFFER * 2]; + UniquePtr<uint8_t[]> largerByteArray; + uint8_t *usedByteArray = byteArray; + const UChar* chars = source.unicodeString().getBuffer(); + size_t charCount = source.unicodeString().length(); + size_t byteArraySize = ucol_getSortKey(collator, chars, charCount, usedByteArray, sizeof(byteArray) - 1); + if (byteArraySize > sizeof(byteArray) - 1) { + // didn't fit, try again with a larger buffer. + largerByteArray.reset(new uint8_t[byteArraySize + 1]); + usedByteArray = largerByteArray.get(); + byteArraySize = ucol_getSortKey(collator, chars, charCount, usedByteArray, byteArraySize); + } + if (byteArraySize == 0) { + return NULL; + } + jbyteArray result = env->NewByteArray(byteArraySize); + env->SetByteArrayRegion(result, 0, byteArraySize, reinterpret_cast<jbyte*>(usedByteArray)); + return result; } -/** -* Get the ordering priority of the next collation element in the text. -* A single character may contain more than one collation element. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address if C collation elements containing the text. -* @return next collation elements ordering, otherwise returns NULLORDER if an -* error has occured or if the end of string has been reached -*/ -static jint next(JNIEnv *env, jclass obj, jint address) { - UCollationElements *iterator = (UCollationElements *) address; +static jint next(JNIEnv* env, jclass, jint address) { UErrorCode status = U_ZERO_ERROR; - jint result = ucol_next(iterator, &status); + jint result = ucol_next(toCollationElements(address), &status); icu4jni_error(env, status); return result; } -/** -* Opening a new C UCollator with the default locale. -* Note determining if a collator currently exist for the caller is to be handled -* by the caller. Hence if the caller has a existing collator, it is his -* responsibility to delete first before calling this method. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @return address of the new C UCollator -* @exception thrown if creation of the UCollator fails -*/ -static jint openCollator__(JNIEnv *env, jclass obj) { +static jint openCollator(JNIEnv* env, jclass, jstring localeName) { + ScopedUtfChars localeChars(env, localeName); UErrorCode status = U_ZERO_ERROR; - UCollator* result = ucol_open(NULL, &status); + UCollator* c = ucol_open(localeChars.c_str(), &status); icu4jni_error(env, status); - return reinterpret_cast<uintptr_t>(result); + return static_cast<jint>(reinterpret_cast<uintptr_t>(c)); } - -/** -* Opening a new C UCollator with the argument locale rules. -* Note determining if a collator currently exist for the caller is to be handled -* by the caller. Hence if the caller has a existing collator, it is his -* responsibility to delete first before calling this method. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param locale name -* @return address of the new C UCollator -* @exception thrown if creation of the UCollator fails -*/ -static jint openCollator__Ljava_lang_String_2(JNIEnv *env, - jclass obj, jstring locale) { - - /* this will be null terminated */ - const char* localeStr = env->GetStringUTFChars(locale, NULL); - if (localeStr == NULL) { - icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR); - return 0; - } - +static jint openCollatorFromRules(JNIEnv* env, jclass, jstring rules0, jint mode, jint strength) { + ScopedJavaUnicodeString rules(env, rules0); UErrorCode status = U_ZERO_ERROR; - UCollator* result = ucol_open(localeStr, &status); - env->ReleaseStringUTFChars(locale, localeStr); + UCollator* c = ucol_openRules(rules.unicodeString().getBuffer(), rules.unicodeString().length(), + UColAttributeValue(mode), UCollationStrength(strength), NULL, &status); icu4jni_error(env, status); - return reinterpret_cast<uintptr_t>(result); + return static_cast<jint>(reinterpret_cast<uintptr_t>(c)); } -/** -* Opening a new C UCollator with the argument locale rules. -* Note determining if a collator currently exist for the caller is to be -* handled by the caller. Hence if the caller has a existing collator, it is his -* responsibility to delete first before calling this method. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param rules set of collation rules -* @param normalizationmode normalization mode -* @param strength collation strength -* @return address of the new C UCollator -* @exception thrown if creation of the UCollator fails -*/ -static jint openCollatorFromRules(JNIEnv *env, jclass obj, - jstring rules, jint normalizationmode, jint strength) { - - jsize ruleslength = env->GetStringLength(rules); - const UChar *rulestr = (const UChar *) env->GetStringCritical(rules, 0); - UErrorCode status = U_ZERO_ERROR; - jint result = 0; - if(rulestr){ - result = (jint)ucol_openRules(rulestr, ruleslength, - (UColAttributeValue)normalizationmode, - (UCollationStrength)strength, NULL, &status); - - env->ReleaseStringCritical(rules, rulestr); - icu4jni_error(env, status); - }else{ - icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR); - } - - return result; -} - -/** -* Get the ordering priority of the previous collation element in the text. -* A single character may contain more than one collation element. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of the C collation element iterator containing the text. -* @return previous collation element ordering, otherwise returns NULLORDER if -* an error has occured or if the start of string has been reached -* @exception thrown when retrieval of previous collation element fails. -*/ -static jint previous(JNIEnv *env, jclass obj, jint address) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - UErrorCode status = U_ZERO_ERROR; - jint result = ucol_previous(iterator, &status); - - icu4jni_error(env, status); - return result; +static jint previous(JNIEnv* env, jclass, jint address) { + UErrorCode status = U_ZERO_ERROR; + jint result = ucol_previous(toCollationElements(address), &status); + icu4jni_error(env, status); + return result; } - -/** -* Reset the collation elements to their initial state. -* This will move the 'cursor' to the beginning of the text. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of C collation element iterator to reset. -*/ -static void reset(JNIEnv *env, jclass obj, jint address) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - ucol_reset(iterator); +static void reset(JNIEnv* env, jclass, jint address) { + ucol_reset(toCollationElements(address)); } -/** -* Thread safe cloning operation -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address address of C collator to be cloned -* @return address of the new clone -* @exception thrown when error occurs while cloning -*/ -static jint safeClone(JNIEnv *env, jclass obj, jint address) { - - const UCollator *collator = (const UCollator *)(int)address; - UErrorCode status = U_ZERO_ERROR; - jint result; - jint buffersize = U_COL_SAFECLONE_BUFFERSIZE; - - result = (jint)ucol_safeClone(collator, NULL, &buffersize, &status); - - if ( icu4jni_error(env, status) != FALSE) { - return 0; - } - - return result; +static jint safeClone(JNIEnv* env, jclass, jint address) { + UErrorCode status = U_ZERO_ERROR; + jint bufferSize = U_COL_SAFECLONE_BUFFERSIZE; + UCollator* c = ucol_safeClone(toCollator(address), NULL, &bufferSize, &status); + icu4jni_error(env, status); + return static_cast<jint>(reinterpret_cast<uintptr_t>(c)); } -static void setAttribute(JNIEnv *env, jclass, jint address, jint type, jint value) { - UCollator *collator = (UCollator *)(int)address; +static void setAttribute(JNIEnv* env, jclass, jint address, jint type, jint value) { UErrorCode status = U_ZERO_ERROR; - ucol_setAttribute(collator, (UColAttribute)type, (UColAttributeValue)value, &status); + ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status); icu4jni_error(env, status); } -/** -* Set the offset of the current source character. -* This is an offset into the text of the character to be processed. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of the C collation element iterator to set. -* @param offset The desired character offset. -* @exception thrown when offset setting fails -*/ -static void setOffset(JNIEnv *env, jclass obj, jint address, - jint offset) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - UErrorCode status = U_ZERO_ERROR; - - ucol_setOffset(iterator, offset, &status); - icu4jni_error(env, status); +static void setOffset(JNIEnv* env, jclass, jint address, jint offset) { + UErrorCode status = U_ZERO_ERROR; + ucol_setOffset(toCollationElements(address), offset, &status); + icu4jni_error(env, status); } -/** -* Set the text containing the collation elements. -* @param env JNI environment -* @param obj RuleBasedCollatorJNI object -* @param address of the C collation element iterator to be set -* @param source text containing the collation elements. -* @exception thrown when error occurs while setting offset -*/ -static void setText(JNIEnv *env, jclass obj, jint address, - jstring source) { - - UCollationElements *iterator = (UCollationElements *)(int)address; - UErrorCode status = U_ZERO_ERROR; - int strlength = env->GetStringLength(source); - const UChar *str = (const UChar *) env->GetStringCritical(source, 0); - - ucol_setText(iterator, str, strlength, &status); - env->ReleaseStringCritical(source, str); - - icu4jni_error(env, status); +static void setText(JNIEnv* env, jclass, jint address, jstring source0) { + ScopedJavaUnicodeString source(env, source0); + UErrorCode status = U_ZERO_ERROR; + ucol_setText(toCollationElements(address), + source.unicodeString().getBuffer(), source.unicodeString().length(), &status); + icu4jni_error(env, status); } static JNINativeMethod gMethods[] = { - { "openCollator", "()I", (void*) openCollator__ }, - { "openCollator", "(Ljava/lang/String;)I", (void*) openCollator__Ljava_lang_String_2 }, + { "openCollator", "(Ljava/lang/String;)I", (void*) openCollator }, { "openCollatorFromRules", "(Ljava/lang/String;II)I", (void*) openCollatorFromRules }, { "closeCollator", "(I)V", (void*) closeCollator }, { "compare", "(ILjava/lang/String;Ljava/lang/String;)I", (void*) compare }, @@ -511,7 +184,6 @@ static JNINativeMethod gMethods[] = { { "getAttribute", "(II)I", (void*) getAttribute }, { "safeClone", "(I)I", (void*) safeClone }, { "getCollationElementIterator", "(ILjava/lang/String;)I", (void*) getCollationElementIterator }, - { "hashCode", "(I)I", (void*) hashCode }, { "closeElements", "(I)V", (void*) closeElements }, { "reset", "(I)V", (void*) reset }, { "next", "(I)I", (void*) next }, @@ -521,7 +193,7 @@ static JNINativeMethod gMethods[] = { { "getOffset", "(I)I", (void*) getOffset }, { "setOffset", "(II)V", (void*) setOffset } }; -int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv *_env) { - return jniRegisterNativeMethods(_env, "com/ibm/icu4jni/text/NativeCollation", +int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv* env) { + return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeCollation", gMethods, NELEM(gMethods)); } diff --git a/icu/src/main/native/NativeConverter.cpp b/icu/src/main/native/NativeConverter.cpp index 3f5a186..8b3952e 100644 --- a/icu/src/main/native/NativeConverter.cpp +++ b/icu/src/main/native/NativeConverter.cpp @@ -39,11 +39,11 @@ static void JNI_TO_U_CALLBACK_SUBSTITUTE static jlong openConverter(JNIEnv* env, jclass, jstring converterName) { ScopedUtfChars converterNameChars(env, converterName); - if (!converterNameChars.data()) { + if (!converterNameChars.c_str()) { return 0; } UErrorCode errorCode = U_ZERO_ERROR; - UConverter* conv = ucnv_open(converterNameChars.data(), &errorCode); + UConverter* conv = ucnv_open(converterNameChars.c_str(), &errorCode); icu4jni_error(env, errorCode); return (jlong) conv; } @@ -945,11 +945,11 @@ static jboolean contains(JNIEnv* env, jclass, jlong handle1, jlong handle2) { static jobject charsetForName(JNIEnv* env, jclass, jstring charsetName) { ScopedUtfChars charsetNameChars(env, charsetName); - if (!charsetNameChars.data()) { + if (!charsetNameChars.c_str()) { return NULL; } // Get ICU's canonical name for this charset. - const char* icuCanonicalName = getICUCanonicalName(charsetNameChars.data()); + const char* icuCanonicalName = getICUCanonicalName(charsetNameChars.c_str()); if (icuCanonicalName == NULL) { return NULL; } diff --git a/icu/src/main/native/UCharacter.cpp b/icu/src/main/native/UCharacter.cpp index 1c5af48..abad16a 100644 --- a/icu/src/main/native/UCharacter.cpp +++ b/icu/src/main/native/UCharacter.cpp @@ -136,7 +136,7 @@ static jstring toLowerCaseStringImpl(JNIEnv* env, jclass, jstring javaString, js ScopedJavaUnicodeString scopedString(env, javaString); UnicodeString& s(scopedString.unicodeString()); UnicodeString original(s); - s.toLower(Locale::createFromName(ScopedUtfChars(env, localeName).data())); + s.toLower(Locale::createFromName(ScopedUtfChars(env, localeName).c_str())); return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); } @@ -144,7 +144,7 @@ static jstring toUpperCaseStringImpl(JNIEnv* env, jclass, jstring javaString, js ScopedJavaUnicodeString scopedString(env, javaString); UnicodeString& s(scopedString.unicodeString()); UnicodeString original(s); - s.toUpper(Locale::createFromName(ScopedUtfChars(env, localeName).data())); + s.toUpper(Locale::createFromName(ScopedUtfChars(env, localeName).c_str())); return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); } diff --git a/include/ScopedUtfChars.h b/include/ScopedUtfChars.h index 8bc3e66..bfe9bb9 100644 --- a/include/ScopedUtfChars.h +++ b/include/ScopedUtfChars.h @@ -34,7 +34,7 @@ public: } } - const char* data() const { + const char* c_str() const { return mUtfChars; } diff --git a/text/src/main/java/java/text/Collator.java b/text/src/main/java/java/text/Collator.java index dba931c..3495d2d 100644 --- a/text/src/main/java/java/text/Collator.java +++ b/text/src/main/java/java/text/Collator.java @@ -291,9 +291,10 @@ public abstract class Collator implements Comparator<Object>, Cloneable { * Returns a {@code Collator} instance which is appropriate for {@code locale}. */ public static Collator getInstance(Locale locale) { - // BEGIN android-changed: removed non-functional cache. + if (locale == null) { + throw new NullPointerException(); + } return new RuleBasedCollator(com.ibm.icu4jni.text.Collator.getInstance(locale)); - // END android-changed } /** |