diff options
author | Elliott Hughes <enh@google.com> | 2011-04-08 14:10:28 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2011-04-08 15:01:19 -0700 |
commit | 69a017bc1d1649350f830dfada5c6ed5eac0b770 (patch) | |
tree | 6ecc6d9658272b268ce931d417930e2ea1bfa3f7 /core/jni/android_util_AssetManager.cpp | |
parent | 5008e92d1fd573d926cd55c39ca723a6fbdf7c4b (diff) | |
download | frameworks_base-69a017bc1d1649350f830dfada5c6ed5eac0b770.zip frameworks_base-69a017bc1d1649350f830dfada5c6ed5eac0b770.tar.gz frameworks_base-69a017bc1d1649350f830dfada5c6ed5eac0b770.tar.bz2 |
More JNI exception-throwing cleanup.
There are a few (unimportant) bug fixes here. There were several attempts to
throw exceptions in situations where there's already a pending exception.
There were also cases where the code was wrong; it was checking for a NULL
return from Get*ArrayElements and throwing NPE, but passing NULL is an error
that causes a crash and a NULL return means an exception has already been
thrown. I didn't want to get into the Scoped* classes just yet, but that
was by far the easiest way to fix this.
Change-Id: I0b31160ee51b96e82539f6514b8412b149dba7c3
Diffstat (limited to 'core/jni/android_util_AssetManager.cpp')
-rw-r--r-- | core/jni/android_util_AssetManager.cpp | 306 |
1 files changed, 128 insertions, 178 deletions
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 65b5990..8ea7e90 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -2,16 +2,16 @@ ** ** 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 +** 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 +** 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 +** 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. */ @@ -24,6 +24,8 @@ #include "jni.h" #include "JNIHelp.h" +#include "ScopedStringChars.h" +#include "ScopedUtfChars.h" #include "android_util_Binder.h" #include <utils/misc.h> #include <android_runtime/AndroidRuntime.h> @@ -121,8 +123,8 @@ static jint android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz, LOGV("openAsset in %p (Java object %p)\n", am, clazz); - if (fileName == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "fileName"); + ScopedUtfChars fileName8(env, fileName); + if (fileName8.c_str() == NULL) { return -1; } @@ -132,15 +134,12 @@ static jint android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz, return -1; } - const char* fileName8 = env->GetStringUTFChars(fileName, NULL); - Asset* a = am->open(fileName8, (Asset::AccessMode)mode); + Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode); if (a == NULL) { - jniThrowException(env, "java/io/FileNotFoundException", fileName8); - env->ReleaseStringUTFChars(fileName, fileName8); + jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str()); return -1; } - env->ReleaseStringUTFChars(fileName, fileName8); //printf("Created Asset Stream: %p\n", a); @@ -152,30 +151,30 @@ static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outO off64_t startOffset, length; int fd = a->openFileDescriptor(&startOffset, &length); delete a; - + if (fd < 0) { jniThrowException(env, "java/io/FileNotFoundException", "This file can not be opened as a file descriptor; it is probably compressed"); return NULL; } - + jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0); if (offsets == NULL) { close(fd); return NULL; } - + offsets[0] = startOffset; offsets[1] = length; - + env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0); - + jobject fileDesc = newFileDescriptor(env, fd); if (fileDesc == NULL) { close(fd); return NULL; } - + return newParcelFileDescriptor(env, fileDesc); } @@ -189,20 +188,17 @@ static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject cla LOGV("openAssetFd in %p (Java object %p)\n", am, clazz); - if (fileName == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "fileName"); + ScopedUtfChars fileName8(env, fileName); + if (fileName8.c_str() == NULL) { return NULL; } - const char* fileName8 = env->GetStringUTFChars(fileName, NULL); - Asset* a = am->open(fileName8, Asset::ACCESS_RANDOM); + Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM); if (a == NULL) { - jniThrowException(env, "java/io/FileNotFoundException", fileName8); - env->ReleaseStringUTFChars(fileName, fileName8); + jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str()); return NULL; } - env->ReleaseStringUTFChars(fileName, fileName8); //printf("Created Asset Stream: %p\n", a); @@ -221,8 +217,8 @@ static jint android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject LOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz); - if (fileName == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "fileName"); + ScopedUtfChars fileName8(env, fileName); + if (fileName8.c_str() == NULL) { return -1; } @@ -232,17 +228,14 @@ static jint android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject return -1; } - const char* fileName8 = env->GetStringUTFChars(fileName, NULL); Asset* a = cookie - ? am->openNonAsset((void*)cookie, fileName8, (Asset::AccessMode)mode) - : am->openNonAsset(fileName8, (Asset::AccessMode)mode); + ? am->openNonAsset((void*)cookie, fileName8.c_str(), (Asset::AccessMode)mode) + : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode); if (a == NULL) { - jniThrowException(env, "java/io/FileNotFoundException", fileName8); - env->ReleaseStringUTFChars(fileName, fileName8); + jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str()); return -1; } - env->ReleaseStringUTFChars(fileName, fileName8); //printf("Created Asset Stream: %p\n", a); @@ -261,22 +254,19 @@ static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jo LOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz); - if (fileName == NULL ) { - jniThrowException(env, "java/lang/NullPointerException", "fileName"); + ScopedUtfChars fileName8(env, fileName); + if (fileName8.c_str() == NULL) { return NULL; } - const char* fileName8 = env->GetStringUTFChars(fileName, NULL); Asset* a = cookie - ? am->openNonAsset((void*)cookie, fileName8, Asset::ACCESS_RANDOM) - : am->openNonAsset(fileName8, Asset::ACCESS_RANDOM); + ? am->openNonAsset((void*)cookie, fileName8.c_str(), Asset::ACCESS_RANDOM) + : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM); if (a == NULL) { - jniThrowException(env, "java/io/FileNotFoundException", fileName8); - env->ReleaseStringUTFChars(fileName, fileName8); + jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str()); return NULL; } - env->ReleaseStringUTFChars(fileName, fileName8); //printf("Created Asset Stream: %p\n", a); @@ -291,19 +281,15 @@ static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz return NULL; } - if (fileName == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "fileName"); + ScopedUtfChars fileName8(env, fileName); + if (fileName8.c_str() == NULL) { return NULL; } - const char* fileName8 = env->GetStringUTFChars(fileName, NULL); - - AssetDir* dir = am->openDir(fileName8); - - env->ReleaseStringUTFChars(fileName, fileName8); + AssetDir* dir = am->openDir(fileName8.c_str()); if (dir == NULL) { - jniThrowException(env, "java/io/FileNotFoundException", fileName8); + jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str()); return NULL; } @@ -347,7 +333,7 @@ static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz //printf("Destroying Asset Stream: %p\n", a); if (a == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "asset"); + jniThrowNullPointerException(env, "asset"); return; } @@ -360,7 +346,7 @@ static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject claz Asset* a = (Asset*)asset; if (a == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "asset"); + jniThrowNullPointerException(env, "asset"); return -1; } @@ -376,14 +362,14 @@ static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz, Asset* a = (Asset*)asset; if (a == NULL || bArray == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "asset"); + jniThrowNullPointerException(env, "asset"); return -1; } if (len == 0) { return 0; } - + jsize bLen = env->GetArrayLength(bArray); if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) { jniThrowException(env, "java/lang/IndexOutOfBoundsException", ""); @@ -409,7 +395,7 @@ static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz, Asset* a = (Asset*)asset; if (a == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "asset"); + jniThrowNullPointerException(env, "asset"); return -1; } @@ -423,7 +409,7 @@ static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject cl Asset* a = (Asset*)asset; if (a == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "asset"); + jniThrowNullPointerException(env, "asset"); return -1; } @@ -436,7 +422,7 @@ static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, j Asset* a = (Asset*)asset; if (a == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "asset"); + jniThrowNullPointerException(env, "asset"); return -1; } @@ -446,9 +432,9 @@ static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, j static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz, jstring path) { - if (path == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "path"); - return JNI_FALSE; + ScopedUtfChars path8(env, path); + if (path8.c_str() == NULL) { + return NULL; } AssetManager* am = assetManagerForJavaObject(env, clazz); @@ -456,12 +442,8 @@ static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz return JNI_FALSE; } - const char* path8 = env->GetStringUTFChars(path, NULL); - void* cookie; - bool res = am->addAssetPath(String8(path8), &cookie); - - env->ReleaseStringUTFChars(path, path8); + bool res = am->addAssetPath(String8(path8.c_str()), &cookie); return (res) ? (jint)cookie : 0; } @@ -478,21 +460,17 @@ static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject cla static void android_content_AssetManager_setLocale(JNIEnv* env, jobject clazz, jstring locale) { - if (locale == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "locale"); + ScopedUtfChars locale8(env, locale); + if (locale8.c_str() == NULL) { return; } - const char* locale8 = env->GetStringUTFChars(locale, NULL); - AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return; } - am->setLocale(locale8); - - env->ReleaseStringUTFChars(locale, locale8); + am->setLocale(locale8.c_str()); } static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz) @@ -543,9 +521,9 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c ResTable_config config; memset(&config, 0, sizeof(config)); - + const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL; - + config.mcc = (uint16_t)mcc; config.mnc = (uint16_t)mnc; config.orientation = (uint8_t)orientation; @@ -563,7 +541,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c config.sdkVersion = (uint16_t)sdkVersion; config.minorVersion = 0; am->setConfiguration(config, locale8); - + if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8); } @@ -572,8 +550,8 @@ static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobj jstring defType, jstring defPackage) { - if (name == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "name"); + ScopedStringChars name16(env, name); + if (name16.get() == NULL) { return 0; } @@ -582,8 +560,6 @@ static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobj return 0; } - const char16_t* name16 = env->GetStringChars(name, NULL); - jsize nameLen = env->GetStringLength(name); const char16_t* defType16 = defType ? env->GetStringChars(defType, NULL) : NULL; jsize defTypeLen = defType @@ -594,7 +570,7 @@ static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobj ? env->GetStringLength(defPackage) : 0; jint ident = am->getResources().identifierForName( - name16, nameLen, defType16, defTypeLen, defPackage16, defPackageLen); + name16.get(), name16.size(), defType16, defTypeLen, defPackage16, defPackageLen); if (defPackage16) { env->ReleaseStringChars(defPackage, defPackage16); @@ -602,7 +578,6 @@ static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobj if (defType16) { env->ReleaseStringChars(defType, defType16); } - env->ReleaseStringChars(name, name16); return ident; } @@ -614,12 +589,12 @@ static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject if (am == NULL) { return NULL; } - + ResTable::resource_name name; if (!am->getResources().getResourceName(resid, &name)) { return NULL; } - + String16 str; if (name.package != NULL) { str.setTo(name.package, name.packageLen); @@ -638,7 +613,7 @@ static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject } str.append(name.name, name.nameLen); } - + return env->NewString((const jchar*)str.string(), str.size()); } @@ -649,16 +624,16 @@ static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, if (am == NULL) { return NULL; } - + ResTable::resource_name name; if (!am->getResources().getResourceName(resid, &name)) { return NULL; } - + if (name.package != NULL) { return env->NewString((const jchar*)name.package, name.packageLen); } - + return NULL; } @@ -669,16 +644,16 @@ static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, job if (am == NULL) { return NULL; } - + ResTable::resource_name name; if (!am->getResources().getResourceName(resid, &name)) { return NULL; } - + if (name.type != NULL) { return env->NewString((const jchar*)name.type, name.typeLen); } - + return NULL; } @@ -689,16 +664,16 @@ static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jo if (am == NULL) { return NULL; } - + ResTable::resource_name name; if (!am->getResources().getResourceName(resid, &name)) { return NULL; } - + if (name.name != NULL) { return env->NewString((const jchar*)name.name, name.nameLen); } - + return NULL; } @@ -746,10 +721,10 @@ static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobje return 0; } const ResTable& res(am->getResources()); - + // Now lock down the resource object and start pulling stuff from it. res.lock(); - + ssize_t block = -1; Res_value value; @@ -770,7 +745,7 @@ static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobje if (block < 0) { return block; } - + uint32_t ref = ident; if (resolve) { block = res.resolveReference(&value, block, &ref, &typeSpecFlags); @@ -881,25 +856,9 @@ static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz, { ResTable::Theme* theme = (ResTable::Theme*)themeInt; const ResTable& res(theme->getResTable()); - - if (tag == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "tag"); - return; - } - - const char* tag8 = env->GetStringUTFChars(tag, NULL); - const char* prefix8 = NULL; - if (prefix != NULL) { - prefix8 = env->GetStringUTFChars(prefix, NULL); - } - + // XXX Need to use params. theme->dumpToLog(); - - if (prefix8 != NULL) { - env->ReleaseStringUTFChars(prefix, prefix8); - } - env->ReleaseStringUTFChars(tag, tag8); } static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject clazz, @@ -912,21 +871,21 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla jintArray outIndices) { if (themeToken == 0) { - jniThrowException(env, "java/lang/NullPointerException", "theme token"); + jniThrowNullPointerException(env, "theme token"); return JNI_FALSE; } if (attrs == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "attrs"); + jniThrowNullPointerException(env, "attrs"); return JNI_FALSE; } if (outValues == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "out values"); + jniThrowNullPointerException(env, "out values"); return JNI_FALSE; } DEBUG_STYLES(LOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x xml=0x%x", themeToken, defStyleAttr, defStyleRes, xmlParserToken)); - + ResTable::Theme* theme = (ResTable::Theme*)themeToken; const ResTable& res = theme->getResTable(); ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken; @@ -942,7 +901,6 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0); if (src == NULL) { - jniThrowException(env, "java/lang/OutOfMemoryError", ""); return JNI_FALSE; } @@ -950,7 +908,6 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla jint* dest = baseDest; if (dest == NULL) { env->ReleasePrimitiveArrayCritical(attrs, src, 0); - jniThrowException(env, "java/lang/OutOfMemoryError", ""); return JNI_FALSE; } @@ -1025,7 +982,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla const uint32_t curIdent = (uint32_t)src[ii]; DEBUG_STYLES(LOGI("RETRIEVING ATTR 0x%08x...", curIdent)); - + // Try to find a value for this attribute... we prioritize values // coming from, first XML attributes, then XML style, then default // style, and finally the theme. @@ -1128,12 +1085,12 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla dest[STYLE_RESOURCE_ID] = resid; dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags; dest[STYLE_DENSITY] = config.density; - + if (indices != NULL && value.dataType != Res_value::TYPE_NULL) { indicesIdx++; indices[indicesIdx] = ii; } - + dest += STYLE_NUM_ENTRIES; } @@ -1156,18 +1113,18 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job jintArray outIndices) { if (xmlParserToken == 0) { - jniThrowException(env, "java/lang/NullPointerException", "xmlParserToken"); + jniThrowNullPointerException(env, "xmlParserToken"); return JNI_FALSE; } if (attrs == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "attrs"); + jniThrowNullPointerException(env, "attrs"); return JNI_FALSE; } if (outValues == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "out values"); + jniThrowNullPointerException(env, "out values"); return JNI_FALSE; } - + AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return JNI_FALSE; @@ -1176,28 +1133,26 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken; ResTable_config config; Res_value value; - + const jsize NI = env->GetArrayLength(attrs); const jsize NV = env->GetArrayLength(outValues); if (NV < (NI*STYLE_NUM_ENTRIES)) { jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small"); return JNI_FALSE; } - + jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0); if (src == NULL) { - jniThrowException(env, "java/lang/OutOfMemoryError", ""); return JNI_FALSE; } - + jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0); jint* dest = baseDest; if (dest == NULL) { env->ReleasePrimitiveArrayCritical(attrs, src, 0); - jniThrowException(env, "java/lang/OutOfMemoryError", ""); return JNI_FALSE; } - + jint* indices = NULL; int indicesIdx = 0; if (outIndices != NULL) { @@ -1208,27 +1163,27 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job // Now lock down the resource object and start pulling stuff from it. res.lock(); - + // Retrieve the XML attributes, if requested. const jsize NX = xmlParser->getAttributeCount(); jsize ix=0; uint32_t curXmlAttr = xmlParser->getAttributeNameResID(ix); - + static const ssize_t kXmlBlock = 0x10000000; - + // Now iterate through all of the attributes that the client has requested, // filling in each with whatever data we can find. ssize_t block = 0; uint32_t typeSetFlags; for (jsize ii=0; ii<NI; ii++) { const uint32_t curIdent = (uint32_t)src[ii]; - + // Try to find a value for this attribute... value.dataType = Res_value::TYPE_NULL; value.data = 0; typeSetFlags = 0; config.density = 0; - + // Skip through XML attributes until the end or the next possible match. while (ix < NX && curIdent > curXmlAttr) { ix++; @@ -1241,7 +1196,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job ix++; curXmlAttr = xmlParser->getAttributeNameResID(ix); } - + //printf("Attribute 0x%08x: type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data); uint32_t resid = 0; if (value.dataType != Res_value::TYPE_NULL) { @@ -1257,14 +1212,14 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job #endif if (newBlock >= 0) block = newBlock; } - + // Deal with the special @null value -- it turns back to TYPE_NULL. if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) { value.dataType = Res_value::TYPE_NULL; } - + //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data); - + // Write the final value back to Java. dest[STYLE_TYPE] = value.dataType; dest[STYLE_DATA] = value.data; @@ -1273,25 +1228,25 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job dest[STYLE_RESOURCE_ID] = resid; dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags; dest[STYLE_DENSITY] = config.density; - + if (indices != NULL && value.dataType != Res_value::TYPE_NULL) { indicesIdx++; indices[indicesIdx] = ii; } - + dest += STYLE_NUM_ENTRIES; } - + res.unlock(); - + if (indices != NULL) { indices[0] = indicesIdx; env->ReleasePrimitiveArrayCritical(outIndices, indices, 0); } - + env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0); env->ReleasePrimitiveArrayCritical(attrs, src, 0); - + return JNI_TRUE; } @@ -1303,12 +1258,12 @@ static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz return 0; } const ResTable& res(am->getResources()); - + res.lock(); const ResTable::bag_entry* defStyleEnt = NULL; ssize_t bagOff = res.getBagLocked(id, &defStyleEnt); res.unlock(); - + return bagOff; } @@ -1317,10 +1272,10 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz jintArray outValues) { if (outValues == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "out values"); + jniThrowNullPointerException(env, "out values"); return JNI_FALSE; } - + AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return JNI_FALSE; @@ -1329,25 +1284,25 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz ResTable_config config; Res_value value; ssize_t block; - + const jsize NV = env->GetArrayLength(outValues); - + jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0); jint* dest = baseDest; if (dest == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", ""); return JNI_FALSE; } - + // Now lock down the resource object and start pulling stuff from it. res.lock(); - + const ResTable::bag_entry* arrayEnt = NULL; uint32_t arrayTypeSetFlags = 0; ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags); const ResTable::bag_entry* endArrayEnt = arrayEnt + (bagOff >= 0 ? bagOff : 0); - + int i = 0; uint32_t typeSetFlags; while (i < NV && arrayEnt < endArrayEnt) { @@ -1355,7 +1310,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz typeSetFlags = arrayTypeSetFlags; config.density = 0; value = arrayEnt->map.value; - + uint32_t resid = 0; if (value.dataType != Res_value::TYPE_NULL) { // Take care of resolving the found resource to its final value. @@ -1389,13 +1344,13 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz i+= STYLE_NUM_ENTRIES; arrayEnt++; } - + i /= STYLE_NUM_ENTRIES; - + res.unlock(); - + env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0); - + return i; } @@ -1410,22 +1365,19 @@ static jint android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject LOGV("openXmlAsset in %p (Java object %p)\n", am, clazz); - if (fileName == NULL) { - jniThrowException(env, "java/lang/NullPointerException", "fileName"); + ScopedUtfChars fileName8(env, fileName); + if (fileName8.c_str() == NULL) { return 0; } - const char* fileName8 = env->GetStringUTFChars(fileName, NULL); Asset* a = cookie - ? am->openNonAsset((void*)cookie, fileName8, Asset::ACCESS_BUFFER) - : am->openNonAsset(fileName8, Asset::ACCESS_BUFFER); + ? am->openNonAsset((void*)cookie, fileName8.c_str(), Asset::ACCESS_BUFFER) + : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER); if (a == NULL) { - jniThrowException(env, "java/io/FileNotFoundException", fileName8); - env->ReleaseStringUTFChars(fileName, fileName8); + jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str()); return 0; } - env->ReleaseStringUTFChars(fileName, fileName8); ResXMLTree* block = new ResXMLTree(); status_t err = block->setTo(a->getBuffer(true), a->getLength(), true); @@ -1457,7 +1409,6 @@ static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jo jintArray array = env->NewIntArray(N * 2); if (array == NULL) { - jniThrowException(env, "java/lang/OutOfMemoryError", ""); res.unlockBag(startOfBag); return NULL; } @@ -1468,20 +1419,20 @@ static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jo jint stringIndex = -1; jint stringBlock = 0; value = bag->map.value; - + // Take care of resolving the found resource to its final value. stringBlock = res.resolveReference(&value, bag->stringBlock, NULL); if (value.dataType == Res_value::TYPE_STRING) { stringIndex = value.data; } - + #if THROW_ON_BAD_ID if (stringBlock == BAD_INDEX) { jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!"); return array; } #endif - + //todo: It might be faster to allocate a C array to contain // the blocknums and indices, put them in there and then // do just one SetIntArrayRegion() @@ -1581,7 +1532,6 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j jintArray array = env->NewIntArray(N); if (array == NULL) { - jniThrowException(env, "java/lang/OutOfMemoryError", ""); res.unlockBag(startOfBag); return NULL; } @@ -1590,7 +1540,7 @@ static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, j const ResTable::bag_entry* bag = startOfBag; for (size_t i=0; ((ssize_t)i)<N; i++, bag++) { value = bag->map.value; - + // Take care of resolving the found resource to its final value. ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL); #if THROW_ON_BAD_ID @@ -1645,7 +1595,7 @@ static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, job if (alloc.length() <= 0) { return NULL; } - + jstring str = env->NewStringUTF(alloc.string()); return str; } |