diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:31:44 -0800 |
commit | 9066cfe9886ac131c34d59ed0e2d287b0e3c0087 (patch) | |
tree | d88beb88001f2482911e3d28e43833b50e4b4e97 /core/jni/android_util_StringBlock.cpp | |
parent | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (diff) | |
download | frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.zip frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.gz frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/jni/android_util_StringBlock.cpp')
-rw-r--r-- | core/jni/android_util_StringBlock.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/core/jni/android_util_StringBlock.cpp b/core/jni/android_util_StringBlock.cpp new file mode 100644 index 0000000..ffb271c --- /dev/null +++ b/core/jni/android_util_StringBlock.cpp @@ -0,0 +1,204 @@ +/* //device/libs/android_runtime/android_util_StringBlock.cpp +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#define LOG_TAG "StringBlock" + +#include "jni.h" +#include <utils/misc.h> +#include <android_runtime/AndroidRuntime.h> +#include <utils/Log.h> + +#include <utils/ResourceTypes.h> + +#include <stdio.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) +{ + jclass npeClazz; + + npeClazz = env->FindClass(exc); + LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc); + + env->ThrowNew(npeClazz, msg); +} + +static jint android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz, + jbyteArray bArray, + jint off, jint len) +{ + if (bArray == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + jsize bLen = env->GetArrayLength(bArray); + if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) { + doThrow(env, "java/lang/IndexOutOfBoundsException"); + return 0; + } + + jbyte* b = env->GetByteArrayElements(bArray, NULL); + ResStringPool* osb = new ResStringPool(b+off, len, true); + env->ReleaseByteArrayElements(bArray, b, 0); + + if (osb == NULL || osb->getError() != NO_ERROR) { + doThrow(env, "java/lang/IllegalArgumentException"); + return 0; + } + + return (jint)osb; +} + +static jint android_content_StringBlock_nativeGetSize(JNIEnv* env, jobject clazz, + jint token) +{ + ResStringPool* osb = (ResStringPool*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return osb->size(); +} + +static jstring android_content_StringBlock_nativeGetString(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResStringPool* osb = (ResStringPool*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + size_t len; + const char16_t* str = osb->stringAt(idx, &len); + if (str == NULL) { + doThrow(env, "java/lang/IndexOutOfBoundsException"); + return 0; + } + + return env->NewString((const jchar*)str, len); +} + +static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResStringPool* osb = (ResStringPool*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return NULL; + } + + const ResStringPool_span* spans = osb->styleAt(idx); + if (spans == NULL) { + return NULL; + } + + const ResStringPool_span* pos = spans; + int num = 0; + while (pos->name.index != ResStringPool_span::END) { + num++; + pos++; + } + + if (num == 0) { + return NULL; + } + + jintArray array = env->NewIntArray((num*sizeof(ResStringPool_span))/sizeof(jint)); + if (array == NULL) { + doThrow(env, "java/lang/OutOfMemoryError"); + return NULL; + } + + num = 0; + static const int numInts = sizeof(ResStringPool_span)/sizeof(jint); + while (spans->name.index != ResStringPool_span::END) { + env->SetIntArrayRegion(array, + num*numInts, numInts, + (jint*)spans); + spans++; + num++; + } + + return array; +} + +static jint android_content_StringBlock_nativeIndexOfString(JNIEnv* env, jobject clazz, + jint token, jstring str) +{ + ResStringPool* osb = (ResStringPool*)token; + if (osb == NULL || str == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + const char16_t* str16 = env->GetStringChars(str, NULL); + jsize strLen = env->GetStringLength(str); + + ssize_t idx = osb->indexOfString(str16, strLen); + + env->ReleaseStringChars(str, str16); + + return idx; +} + +static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz, + jint token) +{ + ResStringPool* osb = (ResStringPool*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return; + } + + delete osb; +} + +// ---------------------------------------------------------------------------- + +/* + * JNI registration. + */ +static JNINativeMethod gStringBlockMethods[] = { + /* name, signature, funcPtr */ + { "nativeCreate", "([BII)I", + (void*) android_content_StringBlock_nativeCreate }, + { "nativeGetSize", "(I)I", + (void*) android_content_StringBlock_nativeGetSize }, + { "nativeGetString", "(II)Ljava/lang/String;", + (void*) android_content_StringBlock_nativeGetString }, + { "nativeGetStyle", "(II)[I", + (void*) android_content_StringBlock_nativeGetStyle }, + { "nativeIndexOfString","(ILjava/lang/String;)I", + (void*) android_content_StringBlock_nativeIndexOfString }, + { "nativeDestroy", "(I)V", + (void*) android_content_StringBlock_nativeDestroy }, +}; + +int register_android_content_StringBlock(JNIEnv* env) +{ + return AndroidRuntime::registerNativeMethods(env, + "android/content/res/StringBlock", gStringBlockMethods, NELEM(gStringBlockMethods)); +} + +}; // namespace android + |