1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
/*
* Copyright (C) 2015 The Android Open Source Project
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. The Android Open Source
* Project designates this particular file as subject to the "Classpath"
* exception as provided by The Android Open Source Project in the LICENSE
* file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "jni.h"
#include "jvm.h"
#include <nativehelper/JNIHelp.h>
#include "nativehelper/jni_macros.h"
#include "unicode/uchar.h"
#include "unicode/uscript.h"
#include <math.h>
#include <stdio.h> // For BUFSIZ
JNIEXPORT jboolean JNICALL
Character_isLowerCaseImpl(JNIEnv* env, jclass, jint codePoint) {
return u_islower(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isUpperCaseImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isupper(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isTitleCaseImpl(JNIEnv* env, jclass, jint codePoint) {
return u_istitle(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isDigitImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isdigit(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isLetterImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isalpha(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isLetterOrDigitImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isalnum(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isAlphabeticImpl(JNIEnv* env, jclass, jint codePoint) {
return u_hasBinaryProperty(codePoint, UCHAR_ALPHABETIC);
}
JNIEXPORT jboolean JNICALL
Character_isIdeographicImpl(JNIEnv* env, jclass, jint codePoint) {
return u_hasBinaryProperty(codePoint, UCHAR_IDEOGRAPHIC);
}
JNIEXPORT jint JNICALL
Character_getTypeImpl(JNIEnv* env, jclass, jint codePoint) {
return u_charType(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isUnicodeIdentifierStartImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isIDStart(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isUnicodeIdentifierPartImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isIDPart(codePoint);
}
JNIEXPORT jint JNICALL
Character_toLowerCaseImpl(JNIEnv* env, jclass, jint codePoint) {
return u_tolower(codePoint);
}
JNIEXPORT jint JNICALL
Character_toUpperCaseImpl(JNIEnv* env, jclass, jint codePoint) {
return u_toupper(codePoint);
}
JNIEXPORT jint JNICALL
Character_toTitleCaseImpl(JNIEnv* env, jclass, jint codePoint) {
return u_totitle(codePoint);
}
JNIEXPORT jint JNICALL
Character_digitImpl(JNIEnv* env, jclass, jint codePoint, jint radix) {
return u_digit(codePoint, radix);
}
JNIEXPORT jint JNICALL
Character_getNumericValueImpl(JNIEnv* env, jclass, jint codePoint) {
double result = u_getNumericValue(codePoint);
if (result == U_NO_NUMERIC_VALUE) {
return -1;
} else if (result < 0 || floor(result + 0.5) != result) {
return -2;
}
return static_cast<jint>(result);
}
JNIEXPORT jboolean JNICALL
Character_isWhitespaceImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isWhitespace(codePoint);
}
JNIEXPORT jbyte JNICALL
Character_getDirectionalityImpl(JNIEnv* env, jclass, jint codePoint) {
return u_charDirection(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isMirroredImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isMirrored(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isDefinedImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isdefined(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isIdentifierIgnorableImpl(JNIEnv* env, jclass, jint codePoint) {
return u_isIDIgnorable(codePoint);
}
JNIEXPORT jboolean JNICALL
Character_isSpaceCharImpl(JNIEnv*, jclass, jint codePoint) {
return u_isJavaSpaceChar(codePoint);
}
JNIEXPORT jstring JNICALL
Character_getNameImpl(JNIEnv* env, jclass, jint codePoint) {
// U_UNICODE_CHAR_NAME gives us the modern names for characters. For control characters,
// we need U_EXTENDED_CHAR_NAME to get "NULL" rather than "BASIC LATIN 0" and so on.
// We could just use U_EXTENDED_CHAR_NAME except that it returns strings for characters
// that aren't unassigned but that don't have names, and those strings aren't in the form
// Java specifies.
bool isControl = (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f));
UCharNameChoice nameType = isControl ? U_EXTENDED_CHAR_NAME : U_UNICODE_CHAR_NAME;
UErrorCode status = U_ZERO_ERROR;
char buf[BUFSIZ]; // TODO: is there a more sensible upper bound?
int32_t byteCount = u_charName(codePoint, nameType, &buf[0], sizeof(buf), &status);
return (U_FAILURE(status) || byteCount == 0) ? NULL : env->NewStringUTF(buf);
}
static JNINativeMethod gMethods[] = {
FAST_NATIVE_METHOD(Character, digitImpl, "(II)I"),
FAST_NATIVE_METHOD(Character, getDirectionalityImpl, "(I)B"),
NATIVE_METHOD(Character, getNameImpl, "(I)Ljava/lang/String;"),
FAST_NATIVE_METHOD(Character, getNumericValueImpl, "(I)I"),
FAST_NATIVE_METHOD(Character, getTypeImpl, "(I)I"),
FAST_NATIVE_METHOD(Character, isAlphabeticImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isDefinedImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isDigitImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isIdentifierIgnorableImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isIdeographicImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isLetterImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isLetterOrDigitImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isLowerCaseImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isMirroredImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isSpaceCharImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isTitleCaseImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isUnicodeIdentifierPartImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isUnicodeIdentifierStartImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isUpperCaseImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, isWhitespaceImpl, "(I)Z"),
FAST_NATIVE_METHOD(Character, toLowerCaseImpl, "(I)I"),
FAST_NATIVE_METHOD(Character, toTitleCaseImpl, "(I)I"),
FAST_NATIVE_METHOD(Character, toUpperCaseImpl, "(I)I"),
};
void register_java_lang_Character(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/Character", gMethods, NELEM(gMethods));
}
|