• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Internal native functions.  All of the functions defined here make
5  * direct use of VM functions or data structures, so they can't be written
6  * with JNI and shouldn't really be in a shared library.
7  *
8  * All functions here either complete quickly or are used to enter a wait
9  * state, so we don't set the thread status to THREAD_NATIVE when executing
10  * these methods.  This means that the GC will wait for these functions
11  * to finish.  DO NOT perform long operations or blocking I/O in here.
12  *
13  * In some cases we're following the division of labor defined by GNU
14  * ClassPath, e.g. java.lang.Thread has "Thread" and "VMThread", with
15  * the VM-specific behavior isolated in VMThread.
16  */
17 
18 #include "JNIHelp.h"
19 #include "AndroidSystemNatives.h"
20 #include "unicode/uchar.h"
21 #include <stdlib.h>
22 #include <math.h>
23 
digitImpl(JNIEnv * env,jclass clazz,jint codePoint,jint radix)24 static jint digitImpl(JNIEnv *env, jclass clazz, jint codePoint, jint radix) {
25     return u_digit(codePoint, radix);
26 }
27 
getTypeImpl(JNIEnv * env,jclass clazz,jint codePoint)28 static jint getTypeImpl(JNIEnv *env, jclass clazz, jint codePoint) {
29     return u_charType(codePoint);
30 }
31 
getDirectionalityImpl(JNIEnv * env,jclass clazz,jint codePoint)32 static jbyte getDirectionalityImpl(JNIEnv *env, jclass clazz, jint codePoint) {
33     return u_charDirection (codePoint);
34 }
35 
isMirroredImpl(JNIEnv * env,jclass clazz,jint codePoint)36 static jboolean isMirroredImpl(JNIEnv *env, jclass clazz, jint codePoint) {
37     return u_isMirrored (codePoint);
38 }
39 
getNumericValueImpl(JNIEnv * env,jclass clazz,jint codePoint)40 static jint getNumericValueImpl(JNIEnv *env, jclass clazz, jint codePoint){
41     // The letters A-Z in their uppercase ('\u0041' through '\u005A'),
42     //                          lowercase ('\u0061' through '\u007A'),
43     //             and full width variant ('\uFF21' through '\uFF3A'
44     //                                 and '\uFF41' through '\uFF5A') forms
45     // have numeric values from 10 through 35. This is independent of the
46     // Unicode specification, which does not assign numeric values to these
47     // char values.
48     if (codePoint >= 0x41 && codePoint <= 0x5A) {
49         return codePoint - 0x37;
50     }
51     if (codePoint >= 0x61 && codePoint <= 0x7A) {
52         return codePoint - 0x57;
53     }
54     if (codePoint >= 0xFF21 && codePoint <= 0xFF3A) {
55         return codePoint - 0xFF17;
56     }
57     if (codePoint >= 0xFF41 && codePoint <= 0xFF5A) {
58         return codePoint - 0xFF37;
59     }
60 
61     double result = u_getNumericValue(codePoint);
62 
63     if (result == U_NO_NUMERIC_VALUE) {
64         return -1;
65     } else if (result < 0 || floor(result + 0.5) != result) {
66         return -2;
67     }
68 
69     return result;
70 }
71 
isDefinedValueImpl(JNIEnv * env,jclass clazz,jint codePoint)72 static jboolean isDefinedValueImpl(JNIEnv *env, jclass clazz, jint codePoint) {
73     return u_isdefined(codePoint);
74 }
75 
isDigitImpl(JNIEnv * env,jclass clazz,jint codePoint)76 static jboolean isDigitImpl(JNIEnv *env, jclass clazz, jint codePoint) {
77     return u_isdigit(codePoint);
78 }
79 
isIdentifierIgnorableImpl(JNIEnv * env,jclass clazz,jint codePoint)80 static jboolean isIdentifierIgnorableImpl(JNIEnv *env, jclass clazz,
81         jint codePoint) {
82 
83     // Java also returns TRUE for U+0085 Next Line (it omits U+0085 from whitespace ISO controls)
84     if(codePoint == 0x0085) {
85         return JNI_TRUE;
86     }
87 
88     return u_isIDIgnorable(codePoint);
89 }
90 
isLetterImpl(JNIEnv * env,jclass clazz,jint codePoint)91 static jboolean isLetterImpl(JNIEnv *env, jclass clazz, jint codePoint) {
92     return u_isalpha(codePoint);
93 }
94 
isLetterOrDigitImpl(JNIEnv * env,jclass clazz,jint codePoint)95 static jboolean isLetterOrDigitImpl(JNIEnv *env, jclass clazz, jint codePoint) {
96     return u_isalnum(codePoint);
97 }
98 
isSpaceCharImpl(JNIEnv * env,jclass clazz,jint codePoint)99 static jboolean isSpaceCharImpl(JNIEnv *env, jclass clazz, jint codePoint) {
100     return u_isJavaSpaceChar(codePoint);
101 }
102 
isTitleCaseImpl(JNIEnv * env,jclass clazz,jint codePoint)103 static jboolean isTitleCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) {
104     return u_istitle(codePoint);
105 }
106 
isUnicodeIdentifierPartImpl(JNIEnv * env,jclass clazz,jint codePoint)107 static jboolean isUnicodeIdentifierPartImpl(JNIEnv *env, jclass clazz,
108         jint codePoint) {
109     return u_isIDPart(codePoint);
110 }
111 
isUnicodeIdentifierStartImpl(JNIEnv * env,jclass clazz,jint codePoint)112 static jboolean isUnicodeIdentifierStartImpl(JNIEnv *env, jclass clazz,
113         jint codePoint) {
114     return u_isIDStart(codePoint);
115 }
116 
isWhitespaceImpl(JNIEnv * env,jclass clazz,jint codePoint)117 static jboolean isWhitespaceImpl(JNIEnv *env, jclass clazz, jint codePoint) {
118 
119     // Java omits U+0085
120     if(codePoint == 0x0085) {
121         return JNI_FALSE;
122     }
123 
124     return u_isWhitespace(codePoint);
125 }
126 
toLowerCaseImpl(JNIEnv * env,jclass clazz,jint codePoint)127 static jint toLowerCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) {
128     return u_tolower(codePoint);
129 }
130 
toTitleCaseImpl(JNIEnv * env,jclass clazz,jint codePoint)131 static jint toTitleCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) {
132     return u_totitle(codePoint);
133 }
134 
toUpperCaseImpl(JNIEnv * env,jclass clazz,jint codePoint)135 static jint toUpperCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) {
136     return u_toupper(codePoint);
137 }
138 
isUpperCaseImpl(JNIEnv * env,jclass clazz,jint codePoint)139 static jboolean isUpperCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) {
140     return u_isupper(codePoint);
141 }
142 
isLowerCaseImpl(JNIEnv * env,jclass clazz,jint codePoint)143 static jboolean isLowerCaseImpl(JNIEnv *env, jclass clazz, jint codePoint) {
144     return u_islower(codePoint);
145 }
146 
forName(JNIEnv * env,jclass clazz,jstring blockName)147 static int forName(JNIEnv *env, jclass clazz, jstring blockName) {
148     const char *bName = (*env)->GetStringUTFChars(env, blockName, NULL);
149     int result =  u_getPropertyValueEnum(UCHAR_BLOCK, bName);
150     (*env)->ReleaseStringUTFChars(env, blockName, bName);
151     return result;
152 }
153 
codeBlock(JNIEnv * env,jclass clazz,jint codePoint)154 static int codeBlock(JNIEnv *env, jclass clazz, jint codePoint) {
155     return ublock_getCode(codePoint);
156 }
157 
158 /*
159  * JNI registration
160  */
161 static JNINativeMethod gMethods[] = {
162     /* name, signature, funcPtr */
163     { "digitImpl", "(II)I", (void*) digitImpl },
164     { "getTypeImpl", "(I)I", (void*) getTypeImpl },
165     { "getDirectionalityImpl", "(I)B", (void*) getDirectionalityImpl },
166     { "isMirroredImpl", "(I)Z", (void*) isMirroredImpl },
167     { "getNumericValueImpl", "(I)I", (void*) getNumericValueImpl },
168     { "isDefinedValueImpl", "(I)Z", (void*) isDefinedValueImpl },
169     { "isDigitImpl", "(I)Z", (void*) isDigitImpl },
170     { "isIdentifierIgnorableImpl", "(I)Z", (void*) isIdentifierIgnorableImpl },
171     { "isLetterImpl", "(I)Z", (void*) isLetterImpl },
172     { "isLetterOrDigitImpl", "(I)Z", (void*) isLetterOrDigitImpl },
173     { "isSpaceCharImpl", "(I)Z", (void*) isSpaceCharImpl },
174     { "isTitleCaseImpl", "(I)Z", (void*) isTitleCaseImpl },
175     { "isUnicodeIdentifierPartImpl", "(I)Z",
176             (void*) isUnicodeIdentifierPartImpl },
177     { "isUnicodeIdentifierStartImpl", "(I)Z",
178             (void*) isUnicodeIdentifierStartImpl },
179     { "isWhitespaceImpl", "(I)Z", (void*) isWhitespaceImpl },
180     { "toLowerCaseImpl", "(I)I", (void*) toLowerCaseImpl },
181     { "toTitleCaseImpl", "(I)I", (void*) toTitleCaseImpl },
182     { "toUpperCaseImpl", "(I)I", (void*) toUpperCaseImpl },
183     { "isUpperCaseImpl", "(I)Z", (void*) isUpperCaseImpl },
184     { "isLowerCaseImpl", "(I)Z", (void*) isLowerCaseImpl },
185     { "forname", "(Ljava/lang/String;)I", (void*) forName },
186     { "codeblock", "(I)I", (void*) codeBlock }
187 };
188 
register_com_ibm_icu4jni_lang_UCharacter(JNIEnv * env)189 int register_com_ibm_icu4jni_lang_UCharacter(JNIEnv *env) {
190     return jniRegisterNativeMethods(env, "com/ibm/icu4jni/lang/UCharacter",
191                 gMethods, NELEM(gMethods));
192 }
193 
194 
195