• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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