blob: 600f5019022b413bb526b2ba4442380202fc9e20 [file] [log] [blame]
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "JNIHelp.h"
#include "AndroidSystemNatives.h"
#include "ErrorCode.h"
#include "unicode/ubrk.h"
#include "unicode/putil.h"
#include <stdlib.h>
static jobjectArray getAvailableLocalesImpl(JNIEnv* env, jclass) {
jclass stringClass = env->FindClass("java/lang/String");
if (stringClass == NULL) {
return NULL;
}
size_t count = ubrk_countAvailable();
jobjectArray result = env->NewObjectArray(count, stringClass, NULL);
for (size_t i = 0; i < count; ++i) {
jstring s = env->NewStringUTF(ubrk_getAvailable(i));
env->SetObjectArrayElement(result, i, s);
env->DeleteLocalRef(s);
}
return result;
}
static jint getIterator(JNIEnv* env, jstring locale, UBreakIteratorType type) {
UErrorCode status = U_ZERO_ERROR;
const char* localeChars = env->GetStringUTFChars(locale, NULL);
UBreakIterator* it = ubrk_open(type, localeChars, NULL, 0, &status);
env->ReleaseStringUTFChars(locale, localeChars);
icu4jni_error(env, status);
return reinterpret_cast<uintptr_t>(it);
}
static jint getCharacterInstanceImpl(JNIEnv* env, jclass clazz, jstring locale) {
return getIterator(env, locale, UBRK_CHARACTER);
}
static jint getLineInstanceImpl(JNIEnv* env, jclass, jstring locale) {
return getIterator(env, locale, UBRK_LINE);
}
static jint getSentenceInstanceImpl(JNIEnv* env, jclass, jstring locale) {
return getIterator(env, locale, UBRK_SENTENCE);
}
static jint getWordInstanceImpl(JNIEnv* env, jclass, jstring locale) {
return getIterator(env, locale, UBRK_WORD);
}
static UBreakIterator* breakIterator(jint address) {
return reinterpret_cast<UBreakIterator*>(static_cast<uintptr_t>(address));
}
static void closeBreakIteratorImpl(JNIEnv* env, jclass, jint address) {
ubrk_close(breakIterator(address));
}
static jint cloneImpl(JNIEnv* env, jclass, jint address) {
UErrorCode status = U_ZERO_ERROR;
jint bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
UBreakIterator* it = ubrk_safeClone(breakIterator(address), NULL, &bufferSize, &status);
icu4jni_error(env, status);
return reinterpret_cast<uintptr_t>(it);
}
static void setTextImpl(JNIEnv* env, jclass, jint address, jstring text) {
UErrorCode status = U_ZERO_ERROR;
const UChar* chars = env->GetStringChars(text, NULL);
ubrk_setText(breakIterator(address), chars, env->GetStringLength(text), &status);
env->ReleaseStringChars(text, chars);
icu4jni_error(env, status);
}
static jboolean isBoundaryImpl(JNIEnv*, jclass, jint address, jint offset) {
return ubrk_isBoundary(breakIterator(address), offset);
}
static jint nextImpl(JNIEnv* env, jclass, jint address, jint n) {
UBreakIterator* bi = breakIterator(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*, jclass, jint address, jint offset) {
return ubrk_preceding(breakIterator(address), offset);
}
static jint firstImpl(JNIEnv*, jclass, jint address) {
return ubrk_first(breakIterator(address));
}
static jint followingImpl(JNIEnv*, jclass, jint address, jint offset) {
return ubrk_following(breakIterator(address), offset);
}
static jint currentImpl(JNIEnv*, jclass, jint address) {
return ubrk_current(breakIterator(address));
}
static jint previousImpl(JNIEnv*, jclass, jint address) {
return ubrk_previous(breakIterator(address));
}
static jint lastImpl(JNIEnv*, jclass, jint address) {
return ubrk_last(breakIterator(address));
}
static JNINativeMethod gMethods[] = {
{ "cloneImpl", "(I)I", (void*) cloneImpl },
{ "closeBreakIteratorImpl", "(I)V", (void*) closeBreakIteratorImpl },
{ "currentImpl", "(I)I", (void*) currentImpl },
{ "firstImpl", "(I)I", (void*) firstImpl },
{ "followingImpl", "(II)I", (void*) followingImpl },
{ "getAvailableLocalesImpl", "()[Ljava/lang/String;", (void*) getAvailableLocalesImpl },
{ "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 },
{ "isBoundaryImpl", "(II)Z", (void*) isBoundaryImpl },
{ "lastImpl", "(I)I", (void*) lastImpl },
{ "nextImpl", "(II)I", (void*) nextImpl },
{ "precedingImpl", "(II)I", (void*) precedingImpl },
{ "previousImpl", "(I)I", (void*) previousImpl },
{ "setTextImpl", "(ILjava/lang/String;)V", (void*) setTextImpl },
};
int register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv* env) {
return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeBreakIterator",
gMethods, NELEM(gMethods));
}