1 /*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "NativeBreakIterator"
18
19 #include "JNIHelp.h"
20 #include "JniConstants.h"
21 #include "ErrorCode.h"
22 #include "ScopedJavaUnicodeString.h"
23 #include "ScopedUtfChars.h"
24 #include "unicode/ubrk.h"
25 #include "unicode/putil.h"
26 #include <stdlib.h>
27
getIterator(JNIEnv * env,jstring locale,UBreakIteratorType type)28 static jint getIterator(JNIEnv* env, jstring locale, UBreakIteratorType type) {
29 UErrorCode status = U_ZERO_ERROR;
30 ScopedUtfChars localeChars(env, locale);
31 if (localeChars.c_str() == NULL) {
32 return 0;
33 }
34 UBreakIterator* it = ubrk_open(type, localeChars.c_str(), NULL, 0, &status);
35 icu4jni_error(env, status);
36 return reinterpret_cast<uintptr_t>(it);
37 }
38
NativeBreakIterator_getCharacterInstanceImpl(JNIEnv * env,jclass,jstring locale)39 static jint NativeBreakIterator_getCharacterInstanceImpl(JNIEnv* env, jclass, jstring locale) {
40 return getIterator(env, locale, UBRK_CHARACTER);
41 }
42
NativeBreakIterator_getLineInstanceImpl(JNIEnv * env,jclass,jstring locale)43 static jint NativeBreakIterator_getLineInstanceImpl(JNIEnv* env, jclass, jstring locale) {
44 return getIterator(env, locale, UBRK_LINE);
45 }
46
NativeBreakIterator_getSentenceInstanceImpl(JNIEnv * env,jclass,jstring locale)47 static jint NativeBreakIterator_getSentenceInstanceImpl(JNIEnv* env, jclass, jstring locale) {
48 return getIterator(env, locale, UBRK_SENTENCE);
49 }
50
NativeBreakIterator_getWordInstanceImpl(JNIEnv * env,jclass,jstring locale)51 static jint NativeBreakIterator_getWordInstanceImpl(JNIEnv* env, jclass, jstring locale) {
52 return getIterator(env, locale, UBRK_WORD);
53 }
54
breakIterator(jint address)55 static UBreakIterator* breakIterator(jint address) {
56 return reinterpret_cast<UBreakIterator*>(static_cast<uintptr_t>(address));
57 }
58
NativeBreakIterator_closeBreakIteratorImpl(JNIEnv *,jclass,jint address)59 static void NativeBreakIterator_closeBreakIteratorImpl(JNIEnv*, jclass, jint address) {
60 ubrk_close(breakIterator(address));
61 }
62
NativeBreakIterator_cloneImpl(JNIEnv * env,jclass,jint address)63 static jint NativeBreakIterator_cloneImpl(JNIEnv* env, jclass, jint address) {
64 UErrorCode status = U_ZERO_ERROR;
65 jint bufferSize = U_BRK_SAFECLONE_BUFFERSIZE;
66 UBreakIterator* it = ubrk_safeClone(breakIterator(address), NULL, &bufferSize, &status);
67 icu4jni_error(env, status);
68 return reinterpret_cast<uintptr_t>(it);
69 }
70
NativeBreakIterator_setTextImpl(JNIEnv * env,jclass,jint address,jstring javaText)71 static void NativeBreakIterator_setTextImpl(JNIEnv* env, jclass, jint address, jstring javaText) {
72 ScopedJavaUnicodeString text(env, javaText);
73 UnicodeString& s(text.unicodeString());
74 UErrorCode status = U_ZERO_ERROR;
75 ubrk_setText(breakIterator(address), s.getBuffer(), s.length(), &status);
76 icu4jni_error(env, status);
77 }
78
NativeBreakIterator_isBoundaryImpl(JNIEnv *,jclass,jint address,jint offset)79 static jboolean NativeBreakIterator_isBoundaryImpl(JNIEnv*, jclass, jint address, jint offset) {
80 return ubrk_isBoundary(breakIterator(address), offset);
81 }
82
NativeBreakIterator_nextImpl(JNIEnv *,jclass,jint address,jint n)83 static jint NativeBreakIterator_nextImpl(JNIEnv*, jclass, jint address, jint n) {
84 UBreakIterator* bi = breakIterator(address);
85 if (n < 0) {
86 while (n++ < -1) {
87 ubrk_previous(bi);
88 }
89 return ubrk_previous(bi);
90 } else if (n == 0) {
91 return ubrk_current(bi);
92 } else {
93 while (n-- > 1) {
94 ubrk_next(bi);
95 }
96 return ubrk_next(bi);
97 }
98 return -1;
99 }
100
NativeBreakIterator_precedingImpl(JNIEnv *,jclass,jint address,jint offset)101 static jint NativeBreakIterator_precedingImpl(JNIEnv*, jclass, jint address, jint offset) {
102 return ubrk_preceding(breakIterator(address), offset);
103 }
104
NativeBreakIterator_firstImpl(JNIEnv *,jclass,jint address)105 static jint NativeBreakIterator_firstImpl(JNIEnv*, jclass, jint address) {
106 return ubrk_first(breakIterator(address));
107 }
108
NativeBreakIterator_followingImpl(JNIEnv *,jclass,jint address,jint offset)109 static jint NativeBreakIterator_followingImpl(JNIEnv*, jclass, jint address, jint offset) {
110 return ubrk_following(breakIterator(address), offset);
111 }
112
NativeBreakIterator_currentImpl(JNIEnv *,jclass,jint address)113 static jint NativeBreakIterator_currentImpl(JNIEnv*, jclass, jint address) {
114 return ubrk_current(breakIterator(address));
115 }
116
NativeBreakIterator_previousImpl(JNIEnv *,jclass,jint address)117 static jint NativeBreakIterator_previousImpl(JNIEnv*, jclass, jint address) {
118 return ubrk_previous(breakIterator(address));
119 }
120
NativeBreakIterator_lastImpl(JNIEnv *,jclass,jint address)121 static jint NativeBreakIterator_lastImpl(JNIEnv*, jclass, jint address) {
122 return ubrk_last(breakIterator(address));
123 }
124
125 static JNINativeMethod gMethods[] = {
126 NATIVE_METHOD(NativeBreakIterator, cloneImpl, "(I)I"),
127 NATIVE_METHOD(NativeBreakIterator, closeBreakIteratorImpl, "(I)V"),
128 NATIVE_METHOD(NativeBreakIterator, currentImpl, "(I)I"),
129 NATIVE_METHOD(NativeBreakIterator, firstImpl, "(I)I"),
130 NATIVE_METHOD(NativeBreakIterator, followingImpl, "(II)I"),
131 NATIVE_METHOD(NativeBreakIterator, getCharacterInstanceImpl, "(Ljava/lang/String;)I"),
132 NATIVE_METHOD(NativeBreakIterator, getLineInstanceImpl, "(Ljava/lang/String;)I"),
133 NATIVE_METHOD(NativeBreakIterator, getSentenceInstanceImpl, "(Ljava/lang/String;)I"),
134 NATIVE_METHOD(NativeBreakIterator, getWordInstanceImpl, "(Ljava/lang/String;)I"),
135 NATIVE_METHOD(NativeBreakIterator, isBoundaryImpl, "(II)Z"),
136 NATIVE_METHOD(NativeBreakIterator, lastImpl, "(I)I"),
137 NATIVE_METHOD(NativeBreakIterator, nextImpl, "(II)I"),
138 NATIVE_METHOD(NativeBreakIterator, precedingImpl, "(II)I"),
139 NATIVE_METHOD(NativeBreakIterator, previousImpl, "(I)I"),
140 NATIVE_METHOD(NativeBreakIterator, setTextImpl, "(ILjava/lang/String;)V"),
141 };
register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv * env)142 int register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv* env) {
143 return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeBreakIterator",
144 gMethods, NELEM(gMethods));
145 }
146