android_util_StringBlock.cpp revision 896043d67d3ac75760bd99db8a1561e31ebee1e1
1/* //device/libs/android_runtime/android_util_StringBlock.cpp 2** 3** Copyright 2006, 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 "StringBlock" 19 20#include "jni.h" 21#include "JNIHelp.h" 22#include <utils/misc.h> 23#include <android_runtime/AndroidRuntime.h> 24#include <utils/Log.h> 25 26#include <androidfw/ResourceTypes.h> 27 28#include <stdio.h> 29 30namespace android { 31 32// ---------------------------------------------------------------------------- 33 34static jlong android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz, 35 jbyteArray bArray, 36 jint off, jint len) 37{ 38 if (bArray == NULL) { 39 jniThrowNullPointerException(env, NULL); 40 return 0; 41 } 42 43 jsize bLen = env->GetArrayLength(bArray); 44 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) { 45 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL); 46 return 0; 47 } 48 49 jbyte* b = env->GetByteArrayElements(bArray, NULL); 50 ResStringPool* osb = new ResStringPool(b+off, len, true); 51 env->ReleaseByteArrayElements(bArray, b, 0); 52 53 if (osb == NULL || osb->getError() != NO_ERROR) { 54 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 55 delete osb; 56 return 0; 57 } 58 59 return reinterpret_cast<jlong>(osb); 60} 61 62static jint android_content_StringBlock_nativeGetSize(JNIEnv* env, jobject clazz, 63 jlong token) 64{ 65 ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); 66 if (osb == NULL) { 67 jniThrowNullPointerException(env, NULL); 68 return 0; 69 } 70 71 return osb->size(); 72} 73 74static jstring android_content_StringBlock_nativeGetString(JNIEnv* env, jobject clazz, 75 jlong token, jint idx) 76{ 77 ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); 78 if (osb == NULL) { 79 jniThrowNullPointerException(env, NULL); 80 return 0; 81 } 82 83 size_t len; 84 const char* str8 = osb->string8At(idx, &len); 85 if (str8 != NULL) { 86 return env->NewStringUTF(str8); 87 } 88 89 const char16_t* str = osb->stringAt(idx, &len); 90 if (str == NULL) { 91 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL); 92 return 0; 93 } 94 95 return env->NewString((const jchar*)str, len); 96} 97 98static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject clazz, 99 jlong token, jint idx) 100{ 101 ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); 102 if (osb == NULL) { 103 jniThrowNullPointerException(env, NULL); 104 return NULL; 105 } 106 107 const ResStringPool_span* spans = osb->styleAt(idx); 108 if (spans == NULL) { 109 return NULL; 110 } 111 112 const ResStringPool_span* pos = spans; 113 int num = 0; 114 while (pos->name.index != ResStringPool_span::END) { 115 num++; 116 pos++; 117 } 118 119 if (num == 0) { 120 return NULL; 121 } 122 123 jintArray array = env->NewIntArray((num*sizeof(ResStringPool_span))/sizeof(jint)); 124 if (array == NULL) { // NewIntArray already threw OutOfMemoryError. 125 return NULL; 126 } 127 128 num = 0; 129 static const int numInts = sizeof(ResStringPool_span)/sizeof(jint); 130 while (spans->name.index != ResStringPool_span::END) { 131 env->SetIntArrayRegion(array, 132 num*numInts, numInts, 133 (jint*)spans); 134 spans++; 135 num++; 136 } 137 138 return array; 139} 140 141static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz, 142 jlong token) 143{ 144 ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); 145 if (osb == NULL) { 146 jniThrowNullPointerException(env, NULL); 147 return; 148 } 149 150 delete osb; 151} 152 153// ---------------------------------------------------------------------------- 154 155/* 156 * JNI registration. 157 */ 158static JNINativeMethod gStringBlockMethods[] = { 159 /* name, signature, funcPtr */ 160 { "nativeCreate", "([BII)J", 161 (void*) android_content_StringBlock_nativeCreate }, 162 { "nativeGetSize", "(J)I", 163 (void*) android_content_StringBlock_nativeGetSize }, 164 { "nativeGetString", "(JI)Ljava/lang/String;", 165 (void*) android_content_StringBlock_nativeGetString }, 166 { "nativeGetStyle", "(JI)[I", 167 (void*) android_content_StringBlock_nativeGetStyle }, 168 { "nativeDestroy", "(J)V", 169 (void*) android_content_StringBlock_nativeDestroy }, 170}; 171 172int register_android_content_StringBlock(JNIEnv* env) 173{ 174 return AndroidRuntime::registerNativeMethods(env, 175 "android/content/res/StringBlock", gStringBlockMethods, NELEM(gStringBlockMethods)); 176} 177 178}; // namespace android 179