diff options
Diffstat (limited to 'icu/src/main/native/CharacterInterface.c')
-rw-r--r-- | icu/src/main/native/CharacterInterface.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/icu/src/main/native/CharacterInterface.c b/icu/src/main/native/CharacterInterface.c new file mode 100644 index 0000000..70e9f29 --- /dev/null +++ b/icu/src/main/native/CharacterInterface.c @@ -0,0 +1,194 @@ +/* + * Copyright 2006 The Android Open Source Project + * + * Internal native functions. All of the functions defined here make + * direct use of VM functions or data structures, so they can't be written + * with JNI and shouldn't really be in a shared library. + * + * All functions here either complete quickly or are used to enter a wait + * state, so we don't set the thread status to THREAD_NATIVE when executing + * these methods. This means that the GC will wait for these functions + * to finish. DO NOT perform long operations or blocking I/O in here. + * + * In some cases we're following the division of labor defined by GNU + * ClassPath, e.g. java.lang.Thread has "Thread" and "VMThread", with + * the VM-specific behavior isolated in VMThread. + */ + +#include "JNIHelp.h" +#include "AndroidSystemNatives.h" +#include "unicode/uchar.h" +#include <stdlib.h> +#include <math.h> + +static jint digitImpl(JNIEnv *env, jclass clazz, jint codePoint, jint radix) { + return u_digit(codePoint, radix); +} + +static jint getTypeImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_charType(codePoint); +} + +static jbyte getDirectionalityImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_charDirection (codePoint); +} + +static jboolean isMirroredImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isMirrored (codePoint); +} + +static jint getNumericValueImpl(JNIEnv *env, jclass clazz, jint codePoint){ + // The letters A-Z in their uppercase ('\u0041' through '\u005A'), + // lowercase ('\u0061' through '\u007A'), + // and full width variant ('\uFF21' through '\uFF3A' + // and '\uFF41' through '\uFF5A') forms + // have numeric values from 10 through 35. This is independent of the + // Unicode specification, which does not assign numeric values to these + // char values. + if (codePoint >= 0x41 && codePoint <= 0x5A) { + return codePoint - 0x37; + } + if (codePoint >= 0x61 && codePoint <= 0x7A) { + return codePoint - 0x57; + } + if (codePoint >= 0xFF21 && codePoint <= 0xFF3A) { + return codePoint - 0xFF17; + } + if (codePoint >= 0xFF41 && codePoint <= 0xFF5A) { + return codePoint - 0xFF37; + } + + double result = u_getNumericValue(codePoint); + + if (result == U_NO_NUMERIC_VALUE) { + return -1; + } else if (result < 0 || floor(result + 0.5) != result) { + return -2; + } + + return result; +} + +static jboolean isDefinedValueImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isdefined(codePoint); +} + +static jboolean isDigitImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isdigit(codePoint); +} + +static jboolean isIdentifierIgnorableImpl(JNIEnv *env, jclass clazz, + jint codePoint) { + + // Java also returns TRUE for U+0085 Next Line (it omits U+0085 from whitespace ISO controls) + if(codePoint == 0x0085) { + return JNI_TRUE; + } + + return u_isIDIgnorable(codePoint); +} + +static jboolean isLetterImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isalpha(codePoint); +} + +static jboolean isLetterOrDigitImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isalnum(codePoint); +} + +static jboolean isSpaceCharImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isJavaSpaceChar(codePoint); +} + +static jboolean isTitleCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_istitle(codePoint); +} + +static jboolean isUnicodeIdentifierPartImpl(JNIEnv *env, jclass clazz, + jint codePoint) { + return u_isIDPart(codePoint); +} + +static jboolean isUnicodeIdentifierStartImpl(JNIEnv *env, jclass clazz, + jint codePoint) { + return u_isIDStart(codePoint); +} + +static jboolean isWhitespaceImpl(JNIEnv *env, jclass clazz, jint codePoint) { + + // Java omits U+0085 + if(codePoint == 0x0085) { + return JNI_FALSE; + } + + return u_isWhitespace(codePoint); +} + +static jint toLowerCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_tolower(codePoint); +} + +static jint toTitleCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_totitle(codePoint); +} + +static jint toUpperCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_toupper(codePoint); +} + +static jboolean isUpperCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_isupper(codePoint); +} + +static jboolean isLowerCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) { + return u_islower(codePoint); +} + +static int forName(JNIEnv *env, jclass clazz, jstring blockName) { + const char *bName = (*env)->GetStringUTFChars(env, blockName, NULL); + int result = u_getPropertyValueEnum(UCHAR_BLOCK, bName); + (*env)->ReleaseStringUTFChars(env, blockName, bName); + return result; +} + +static int codeBlock(JNIEnv *env, jclass clazz, jint codePoint) { + return ublock_getCode(codePoint); +} + +/* + * JNI registration + */ +static JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "digitImpl", "(II)I", (void*) digitImpl }, + { "getTypeImpl", "(I)I", (void*) getTypeImpl }, + { "getDirectionalityImpl", "(I)B", (void*) getDirectionalityImpl }, + { "isMirroredImpl", "(I)Z", (void*) isMirroredImpl }, + { "getNumericValueImpl", "(I)I", (void*) getNumericValueImpl }, + { "isDefinedValueImpl", "(I)Z", (void*) isDefinedValueImpl }, + { "isDigitImpl", "(I)Z", (void*) isDigitImpl }, + { "isIdentifierIgnorableImpl", "(I)Z", (void*) isIdentifierIgnorableImpl }, + { "isLetterImpl", "(I)Z", (void*) isLetterImpl }, + { "isLetterOrDigitImpl", "(I)Z", (void*) isLetterOrDigitImpl }, + { "isSpaceCharImpl", "(I)Z", (void*) isSpaceCharImpl }, + { "isTitleCaseImpl", "(I)Z", (void*) isTitleCaseImpl }, + { "isUnicodeIdentifierPartImpl", "(I)Z", + (void*) isUnicodeIdentifierPartImpl }, + { "isUnicodeIdentifierStartImpl", "(I)Z", + (void*) isUnicodeIdentifierStartImpl }, + { "isWhitespaceImpl", "(I)Z", (void*) isWhitespaceImpl }, + { "toLowerCaseImpl", "(I)I", (void*) toLowerCaseImpl }, + { "toTitleCaseImpl", "(I)I", (void*) toTitleCaseImpl }, + { "toUpperCaseImpl", "(I)I", (void*) toUpperCaseImpl }, + { "isUpperCaseImpl", "(I)Z", (void*) isUpperCaseImpl }, + { "isLowerCaseImpl", "(I)Z", (void*) isLowerCaseImpl }, + { "forname", "(Ljava/lang/String;)I", (void*) forName }, + { "codeblock", "(I)I", (void*) codeBlock } +}; + +int register_com_ibm_icu4jni_lang_UCharacter(JNIEnv *env) { + return jniRegisterNativeMethods(env, "com/ibm/icu4jni/lang/UCharacter", + gMethods, NELEM(gMethods)); +} + + |