/* * 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 "ErrorCode.h" #include "unicode/ubrk.h" #include "unicode/putil.h" #include static jstring getAvailableLocalesImpl(JNIEnv *env, jclass clazz, jint index) { const char * locale = ubrk_getAvailable(index); return (*env)->NewStringUTF(env, locale); } static jint getAvailableLocalesCountImpl(JNIEnv *env, jclass clazz) { return ubrk_countAvailable(); } static jint getCharacterInstanceImpl(JNIEnv *env, jclass clazz, jstring locale) { UErrorCode status = U_ZERO_ERROR; const char *localeChars = (*env)->GetStringUTFChars(env, locale, 0); UBreakIterator *iter = ubrk_open(UBRK_CHARACTER, localeChars, NULL, 0, &status); (*env)->ReleaseStringUTFChars(env, locale, localeChars); if ( icu4jni_error(env, status) != FALSE) { return 0; } return (long) iter; } static jint getLineInstanceImpl(JNIEnv *env, jclass clazz, jstring locale) { UErrorCode status = U_ZERO_ERROR; const char *localeChars = (*env)->GetStringUTFChars(env, locale, 0); enum UBreakIteratorType type = UBRK_LINE; UBreakIterator *iter = ubrk_open(type, localeChars, NULL, 0, &status); (*env)->ReleaseStringUTFChars(env, locale, localeChars); if ( icu4jni_error(env, status) != FALSE) { return 0; } return (long) iter; } static jint getSentenceInstanceImpl(JNIEnv *env, jclass clazz, jstring locale) { UErrorCode status = U_ZERO_ERROR; const char *localeChars = (*env)->GetStringUTFChars(env, locale, 0); enum UBreakIteratorType type = UBRK_SENTENCE; UBreakIterator *iter = ubrk_open(type, localeChars, NULL, 0, &status); (*env)->ReleaseStringUTFChars(env, locale, localeChars); if ( icu4jni_error(env, status) != FALSE) { return 0; } return (long) iter; } static jint getWordInstanceImpl(JNIEnv *env, jclass clazz, jstring locale) { UErrorCode status = U_ZERO_ERROR; const char *localeChars = (*env)->GetStringUTFChars(env, locale, 0); enum UBreakIteratorType type = UBRK_WORD; UBreakIterator *iter = ubrk_open(type, localeChars, NULL, 0, &status); (*env)->ReleaseStringUTFChars(env, locale, localeChars); if ( icu4jni_error(env, status) != FALSE) { return 0; } return (long) iter; } static void closeBreakIteratorImpl(JNIEnv *env, jclass clazz, jint address) { UBreakIterator *bi = (UBreakIterator *)(long)address; ubrk_close(bi); } static jint cloneImpl(JNIEnv *env, jclass clazz, jint address) { UErrorCode status = U_ZERO_ERROR; UBreakIterator *bi = (UBreakIterator *)(long)address; jint buffersize = U_BRK_SAFECLONE_BUFFERSIZE; UBreakIterator *iter = ubrk_safeClone(bi, NULL, &buffersize, &status); if (icu4jni_error(env, status) != FALSE) { return 0; } return (long) iter; } static void setTextImpl(JNIEnv *env, jclass clazz, jint address, jstring text) { UErrorCode status = U_ZERO_ERROR; UBreakIterator *bi = (UBreakIterator *)(long)address; const UChar *strUChars = (*env)->GetStringChars(env, text, NULL); int strLen = (*env)->GetStringLength(env, text); ubrk_setText(bi, strUChars, strLen, &status); (*env)->ReleaseStringChars(env, text, strUChars); icu4jni_error(env, status); } static jboolean isBoundaryImpl(JNIEnv *env, jclass clazz, jint address, jint offset) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_isBoundary(bi, offset); } static jint nextImpl(JNIEnv *env, jclass clazz, jint address, jint n) { UBreakIterator *bi = (UBreakIterator *)(long)address; if(n < 0) { while(n++ < -1) { ubrk_previous(bi); } return ubrk_previous(bi); } else if(n == 0) { return ubrk_current(bi); } else { while(n-- > 1) { ubrk_next(bi); } return ubrk_next(bi); } return -1; } static jint precedingImpl(JNIEnv *env, jclass clazz, jint address, jint offset) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_preceding(bi, offset); } static jint firstImpl(JNIEnv *env, jclass clazz, jint address) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_first(bi); } static jint followingImpl(JNIEnv *env, jclass clazz, jint address, jint offset) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_following(bi, offset); } static jint currentImpl(JNIEnv *env, jclass clazz, jint address) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_current(bi); } static jint previousImpl(JNIEnv *env, jclass clazz, jint address) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_previous(bi); } static jint lastImpl(JNIEnv *env, jclass clazz, jint address) { UBreakIterator *bi = (UBreakIterator *)(long)address; return ubrk_last(bi); } /* * JNI registration */ static JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { "getAvailableLocalesImpl", "(I)Ljava/lang/String;", (void*) getAvailableLocalesImpl }, { "getAvailableLocalesCountImpl", "()I", (void*) getAvailableLocalesCountImpl }, { "getCharacterInstanceImpl", "(Ljava/lang/String;)I", (void*) getCharacterInstanceImpl }, { "getLineInstanceImpl", "(Ljava/lang/String;)I", (void*) getLineInstanceImpl }, { "getSentenceInstanceImpl", "(Ljava/lang/String;)I", (void*) getSentenceInstanceImpl }, { "getWordInstanceImpl", "(Ljava/lang/String;)I", (void*) getWordInstanceImpl }, { "closeBreakIteratorImpl", "(I)V", (void*) closeBreakIteratorImpl }, { "cloneImpl", "(I)I", (void*) cloneImpl }, { "setTextImpl", "(ILjava/lang/String;)V", (void*) setTextImpl }, { "isBoundaryImpl", "(II)Z", (void*) isBoundaryImpl }, { "nextImpl", "(II)I", (void*) nextImpl }, { "precedingImpl", "(II)I", (void*) precedingImpl }, { "firstImpl", "(I)I", (void*) firstImpl }, { "lastImpl", "(I)I", (void*) lastImpl }, { "currentImpl", "(I)I", (void*) currentImpl }, { "followingImpl", "(II)I", (void*) followingImpl }, { "previousImpl", "(I)I", (void*) previousImpl }, }; int register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv* env) { return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeBreakIterator", gMethods, NELEM(gMethods)); }