use libandroidfw for resource XML parsing

androidfw is implemented in native code and has much better performance
than ARSClib
This commit is contained in:
Julian Winkler
2024-05-12 17:03:27 +02:00
committed by Mis012
parent e2edbb0b59
commit cc5d4a3cb3
9 changed files with 280 additions and 115 deletions

View File

@@ -447,3 +447,16 @@ JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_list(JNIEnv
return array;
}
JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openXmlAssetNative(JNIEnv *env, jobject this, jint cookie, jstring _file_name)
{
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
const char *file_name = (*env)->GetStringUTFChars(env, _file_name, NULL);
struct Asset *asset = AssetManager_openNonAsset(asset_manager, file_name, ACCESS_BUFFER);
(*env)->ReleaseStringUTFChars(env, _file_name, file_name);
struct ResXMLTree *res_xml = ResXMLTree_new();
ResXMLTree_setTo(res_xml, Asset_getBuffer(asset, true), Asset_getLength(asset), true);
Asset_delete(asset);
return _INTPTR(res_xml);
}

View File

@@ -0,0 +1,127 @@
#include <androidfw/androidfw_c_api.h>
#include "../generated_headers/android_content_res_XmlBlock.h"
#include "../defines.h"
JNIEXPORT jlong JNICALL Java_android_content_res_XmlBlock_nativeCreateParseState(JNIEnv *env, jobject this, jlong block)
{
struct ResXMLTree *tree = (struct ResXMLTree *)_PTR(block);
struct ResXMLParser *parser = ResXMLParser_new(tree);
ResXMLParser_restart(parser);
return _INTPTR(parser);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeNext(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
enum event_code_t ret = ResXMLParser_next(parser);
if (ret > 0x100)
return ret - 0x100;
return ret;
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetPooledString(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
const struct ResStringPool *string_pool = ResXMLParser_getStrings(parser);
size_t len;
const char16_t *string = ResStringPool_stringAt(string_pool, index, &len);
if (!string)
return NULL;
return (*env)->NewString(env, string, len);
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetName(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_getElementNameID(parser);
if (idx < 0)
return NULL;
return Java_android_content_res_XmlBlock_nativeGetPooledString(env, this, parser_ptr, idx);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeCount(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeCount(parser);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeResource(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeNameResID(parser, index);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeIndex(JNIEnv *env, jobject this, jlong parser_ptr, jstring namespace_str, jstring name_str)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
const char16_t *namespace = NULL;
int namespace_len = 0;
if (namespace_str) {
namespace = (*env)->GetStringChars(env, namespace_str, NULL);
namespace_len = (*env)->GetStringLength(env, namespace_str);
}
const char16_t *name = (*env)->GetStringChars(env, name_str, NULL);
int name_len = (*env)->GetStringLength(env, name_str);
int ret = ResXMLParser_indexOfAttribute(parser, namespace, namespace_len, name, name_len);
if (namespace_str)
(*env)->ReleaseStringChars(env, namespace_str, namespace);
(*env)->ReleaseStringChars(env, name_str, name);
return ret;
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeStringValue(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_getAttributeValueStringID(parser, index);
if (idx < 0)
return NULL;
return Java_android_content_res_XmlBlock_nativeGetPooledString(env, this, parser_ptr, idx);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetLineNumber(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getLineNumber(parser);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeDataType(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeDataType(parser, index);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeData(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeData(parser, index);
}
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroyParseState(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
ResXMLParser_delete(parser);
}
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroy(JNIEnv *env, jobject this, jlong block)
{
struct ResXMLTree *tree = (struct ResXMLTree *)_PTR(block);
ResXMLTree_delete(tree);
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetClassAttribute(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_indexOfClass(parser);
return Java_android_content_res_XmlBlock_nativeGetAttributeStringValue(env, this, parser_ptr, idx);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStyleAttribute(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_indexOfStyle(parser);
struct Res_value value;
ResXMLParser_getAttributeValue(parser, idx, &value);
return value.data;
}

View File

@@ -329,6 +329,14 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeV
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_dumpTheme
(JNIEnv *, jclass, jlong, jint, jstring, jstring);
/*
* Class: android_content_res_AssetManager
* Method: openXmlAssetNative
* Signature: (ILjava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openXmlAssetNative
(JNIEnv *, jobject, jint, jstring);
/*
* Class: android_content_res_AssetManager
* Method: getArrayStringResource

View File

@@ -20,162 +20,170 @@ JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeCreate
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetStringBlock
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStringBlock
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeCreateParseState
* Signature: (I)I
* Signature: (J)J
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeCreateParseState
(JNIEnv *, jclass, jint);
JNIEXPORT jlong JNICALL Java_android_content_res_XmlBlock_nativeCreateParseState
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeNext
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeNext
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetNamespace
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetNamespace
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetName
* Signature: (I)I
* Signature: (J)Ljava/lang/String;
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetName
(JNIEnv *, jclass, jint);
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetName
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetText
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetText
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetLineNumber
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetLineNumber
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeCount
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeCount
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeNamespace
* Signature: (II)I
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeNamespace
(JNIEnv *, jclass, jint, jint);
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeName
* Signature: (II)I
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeName
(JNIEnv *, jclass, jint, jint);
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeResource
* Signature: (II)I
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeResource
(JNIEnv *, jclass, jint, jint);
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeDataType
* Signature: (II)I
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeDataType
(JNIEnv *, jclass, jint, jint);
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeData
* Signature: (II)I
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeData
(JNIEnv *, jclass, jint, jint);
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeStringValue
* Signature: (II)I
* Signature: (JI)Ljava/lang/String;
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeStringValue
(JNIEnv *, jclass, jint, jint);
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeStringValue
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetIdAttribute
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetIdAttribute
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetClassAttribute
* Signature: (I)I
* Signature: (J)Ljava/lang/String;
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetClassAttribute
(JNIEnv *, jclass, jint);
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetClassAttribute
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetStyleAttribute
* Signature: (I)I
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStyleAttribute
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetAttributeIndex
* Signature: (ILjava/lang/String;Ljava/lang/String;)I
* Signature: (JLjava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeIndex
(JNIEnv *, jclass, jint, jstring, jstring);
(JNIEnv *, jclass, jlong, jstring, jstring);
/*
* Class: android_content_res_XmlBlock
* Method: nativeDestroyParseState
* Signature: (I)V
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroyParseState
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetPooledString
* Signature: (JI)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetPooledString
(JNIEnv *, jclass, jlong, jint);
/*
* Class: android_content_res_XmlBlock
* Method: nativeDestroy
* Signature: (I)V
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroy
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jlong);
#ifdef __cplusplus
}