1 /* //device/libs/android_runtime/android_text_AndroidBidi.cpp 2 ** 3 ** Copyright 2010, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #define LOG_TAG "AndroidUnicode" 19 20 #include <jni.h> 21 #include <android_runtime/AndroidRuntime.h> 22 #include "utils/misc.h" 23 #include "utils/Log.h" 24 #include "unicode/ubidi.h" 25 26 namespace android { 27 28 static void jniThrowException(JNIEnv* env, const char* exc, const char* msg = NULL) 29 { 30 jclass excClazz = env->FindClass(exc); 31 LOG_ASSERT(excClazz, "Unable to find class %s", exc); 32 33 env->ThrowNew(excClazz, msg); 34 } 35 36 static jint runBidi(JNIEnv* env, jobject obj, jint dir, jcharArray chsArray, 37 jbyteArray infoArray, int n, jboolean haveInfo) 38 { 39 // Parameters are checked on java side 40 // Failures from GetXXXArrayElements indicate a serious out-of-memory condition 41 // that we don't bother to report, we're probably dead anyway. 42 jint result = 0; 43 jchar* chs = env->GetCharArrayElements(chsArray, NULL); 44 if (chs != NULL) { 45 jbyte* info = env->GetByteArrayElements(infoArray, NULL); 46 if (info != NULL) { 47 UErrorCode status = U_ZERO_ERROR; 48 UBiDi* bidi = ubidi_openSized(n, 0, &status); 49 ubidi_setPara(bidi, chs, n, dir, NULL, &status); 50 if (U_SUCCESS(status)) { 51 for (int i = 0; i < n; ++i) { 52 info[i] = ubidi_getLevelAt(bidi, i); 53 } 54 result = ubidi_getParaLevel(bidi); 55 } else { 56 jniThrowException(env, "java/lang/RuntimeException", NULL); 57 } 58 ubidi_close(bidi); 59 60 env->ReleaseByteArrayElements(infoArray, info, 0); 61 } 62 env->ReleaseCharArrayElements(chsArray, chs, JNI_ABORT); 63 } 64 return result; 65 } 66 67 static JNINativeMethod gMethods[] = { 68 { "runBidi", "(I[C[BIZ)I", 69 (void*) runBidi } 70 }; 71 72 int register_android_text_AndroidBidi(JNIEnv* env) 73 { 74 jclass clazz = env->FindClass("android/text/AndroidBidi"); 75 LOG_ASSERT(clazz, "Cannot find android/text/AndroidBidi"); 76 77 return AndroidRuntime::registerNativeMethods(env, "android/text/AndroidBidi", 78 gMethods, NELEM(gMethods)); 79 } 80 81 } 82