blob: 021ace1caa7d195f015a9290c0c9b9148b8ce152 [file] [log] [blame]
/*
* 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 <stdlib.h>
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));
}