Home | History | Annotate | Download | only in jni
      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 
     30 namespace android {
     31 
     32 // ----------------------------------------------------------------------------
     33 
     34 static jint 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         return 0;
     56     }
     57 
     58     return (jint)osb;
     59 }
     60 
     61 static jint android_content_StringBlock_nativeGetSize(JNIEnv* env, jobject clazz,
     62                                                    jint token)
     63 {
     64     ResStringPool* osb = (ResStringPool*)token;
     65     if (osb == NULL) {
     66         jniThrowNullPointerException(env, NULL);
     67         return 0;
     68     }
     69 
     70     return osb->size();
     71 }
     72 
     73 static jstring android_content_StringBlock_nativeGetString(JNIEnv* env, jobject clazz,
     74                                                         jint token, jint idx)
     75 {
     76     ResStringPool* osb = (ResStringPool*)token;
     77     if (osb == NULL) {
     78         jniThrowNullPointerException(env, NULL);
     79         return 0;
     80     }
     81 
     82     size_t len;
     83     const char* str8 = osb->string8At(idx, &len);
     84     if (str8 != NULL) {
     85         return env->NewStringUTF(str8);
     86     }
     87 
     88     const char16_t* str = osb->stringAt(idx, &len);
     89     if (str == NULL) {
     90         jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
     91         return 0;
     92     }
     93 
     94     return env->NewString((const jchar*)str, len);
     95 }
     96 
     97 static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject clazz,
     98                                                          jint token, jint idx)
     99 {
    100     ResStringPool* osb = (ResStringPool*)token;
    101     if (osb == NULL) {
    102         jniThrowNullPointerException(env, NULL);
    103         return NULL;
    104     }
    105 
    106     const ResStringPool_span* spans = osb->styleAt(idx);
    107     if (spans == NULL) {
    108         return NULL;
    109     }
    110 
    111     const ResStringPool_span* pos = spans;
    112     int num = 0;
    113     while (pos->name.index != ResStringPool_span::END) {
    114         num++;
    115         pos++;
    116     }
    117 
    118     if (num == 0) {
    119         return NULL;
    120     }
    121 
    122     jintArray array = env->NewIntArray((num*sizeof(ResStringPool_span))/sizeof(jint));
    123     if (array == NULL) { // NewIntArray already threw OutOfMemoryError.
    124         return NULL;
    125     }
    126 
    127     num = 0;
    128     static const int numInts = sizeof(ResStringPool_span)/sizeof(jint);
    129     while (spans->name.index != ResStringPool_span::END) {
    130         env->SetIntArrayRegion(array,
    131                                   num*numInts, numInts,
    132                                   (jint*)spans);
    133         spans++;
    134         num++;
    135     }
    136 
    137     return array;
    138 }
    139 
    140 static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz,
    141                                                    jint token)
    142 {
    143     ResStringPool* osb = (ResStringPool*)token;
    144     if (osb == NULL) {
    145         jniThrowNullPointerException(env, NULL);
    146         return;
    147     }
    148 
    149     delete osb;
    150 }
    151 
    152 // ----------------------------------------------------------------------------
    153 
    154 /*
    155  * JNI registration.
    156  */
    157 static JNINativeMethod gStringBlockMethods[] = {
    158     /* name, signature, funcPtr */
    159     { "nativeCreate",      "([BII)I",
    160             (void*) android_content_StringBlock_nativeCreate },
    161     { "nativeGetSize",      "(I)I",
    162             (void*) android_content_StringBlock_nativeGetSize },
    163     { "nativeGetString",    "(II)Ljava/lang/String;",
    164             (void*) android_content_StringBlock_nativeGetString },
    165     { "nativeGetStyle",    "(II)[I",
    166             (void*) android_content_StringBlock_nativeGetStyle },
    167     { "nativeDestroy",      "(I)V",
    168             (void*) android_content_StringBlock_nativeDestroy },
    169 };
    170 
    171 int register_android_content_StringBlock(JNIEnv* env)
    172 {
    173     return AndroidRuntime::registerNativeMethods(env,
    174             "android/content/res/StringBlock", gStringBlockMethods, NELEM(gStringBlockMethods));
    175 }
    176 
    177 }; // namespace android
    178