blob: 958ddb22cbc7f934e6456f114fefdf9b90b6e65f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_util_StringBlock.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
Elliott Hughes8451b252011-04-07 19:17:57 -07005** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughes8451b252011-04-07 19:17:57 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughes8451b252011-04-07 19:17:57 -070011** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
18#define LOG_TAG "StringBlock"
19
20#include "jni.h"
Elliott Hughes8451b252011-04-07 19:17:57 -070021#include "JNIHelp.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include <utils/misc.h>
23#include <android_runtime/AndroidRuntime.h>
24#include <utils/Log.h>
25
26#include <utils/ResourceTypes.h>
27
28#include <stdio.h>
29
30namespace android {
31
32// ----------------------------------------------------------------------------
33
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034static jint android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz,
35 jbyteArray bArray,
36 jint off, jint len)
37{
38 if (bArray == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -070039 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 return 0;
41 }
42
43 jsize bLen = env->GetArrayLength(bArray);
44 if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
Elliott Hughes8451b252011-04-07 19:17:57 -070045 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 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) {
Elliott Hughes8451b252011-04-07 19:17:57 -070054 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 return 0;
56 }
57
58 return (jint)osb;
59}
60
61static jint android_content_StringBlock_nativeGetSize(JNIEnv* env, jobject clazz,
62 jint token)
63{
64 ResStringPool* osb = (ResStringPool*)token;
65 if (osb == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -070066 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 return 0;
68 }
69
70 return osb->size();
71}
72
73static jstring android_content_StringBlock_nativeGetString(JNIEnv* env, jobject clazz,
74 jint token, jint idx)
75{
76 ResStringPool* osb = (ResStringPool*)token;
77 if (osb == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -070078 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 return 0;
80 }
81
82 size_t len;
Kenny Root780d2a12010-02-22 22:36:26 -080083 const char* str8 = osb->string8At(idx, &len);
84 if (str8 != NULL) {
85 return env->NewStringUTF(str8);
86 }
87
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 const char16_t* str = osb->stringAt(idx, &len);
89 if (str == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -070090 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 return 0;
92 }
93
94 return env->NewString((const jchar*)str, len);
95}
96
97static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject clazz,
98 jint token, jint idx)
99{
100 ResStringPool* osb = (ResStringPool*)token;
101 if (osb == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700102 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 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));
Elliott Hughes8451b252011-04-07 19:17:57 -0700123 if (array == NULL) { // NewIntArray already threw OutOfMemoryError.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz,
141 jint token)
142{
143 ResStringPool* osb = (ResStringPool*)token;
144 if (osb == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700145 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 return;
147 }
148
149 delete osb;
150}
151
152// ----------------------------------------------------------------------------
153
154/*
155 * JNI registration.
156 */
157static 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 },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 { "nativeDestroy", "(I)V",
168 (void*) android_content_StringBlock_nativeDestroy },
169};
170
171int 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