/* //device/libs/android_runtime/android_util_XmlBlock.cpp ** ** 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 ** ** 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 ** limitations under the License. */ #define LOG_TAG "XmlBlock" #include "jni.h" #include "JNIHelp.h" #include #include #include #include #include #include namespace android { // ---------------------------------------------------------------------------- static jlong android_content_XmlBlock_nativeCreate(JNIEnv* env, jobject clazz, jbyteArray bArray, jint off, jint len) { if (bArray == NULL) { jniThrowNullPointerException(env, NULL); return 0; } jsize bLen = env->GetArrayLength(bArray); if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) { jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL); return 0; } jbyte* b = env->GetByteArrayElements(bArray, NULL); ResXMLTree* osb = new ResXMLTree(); osb->setTo(b+off, len, true); env->ReleaseByteArrayElements(bArray, b, 0); if (osb->getError() != NO_ERROR) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return 0; } return reinterpret_cast(osb); } static jlong android_content_XmlBlock_nativeGetStringBlock(JNIEnv* env, jobject clazz, jlong token) { ResXMLTree* osb = reinterpret_cast(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return reinterpret_cast(&osb->getStrings()); } static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject clazz, jlong token) { ResXMLTree* osb = reinterpret_cast(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return 0; } ResXMLParser* st = new ResXMLParser(*osb); if (st == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return 0; } st->restart(); return reinterpret_cast(st); } static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { return ResXMLParser::END_DOCUMENT; } do { ResXMLParser::event_code_t code = st->next(); switch (code) { case ResXMLParser::START_TAG: return 2; case ResXMLParser::END_TAG: return 3; case ResXMLParser::TEXT: return 4; case ResXMLParser::START_DOCUMENT: return 0; case ResXMLParser::END_DOCUMENT: return 1; case ResXMLParser::BAD_DOCUMENT: goto bad; default: break; } } while (true); bad: jniThrowException(env, "org/xmlpull/v1/XmlPullParserException", "Corrupt XML binary file"); return ResXMLParser::BAD_DOCUMENT; } static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { return -1; } return static_cast(st->getElementNamespaceID()); } static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { return -1; } return static_cast(st->getElementNameID()); } static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { return -1; } return static_cast(st->getTextID()); } static jint android_content_XmlBlock_nativeGetLineNumber(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getLineNumber()); } static jint android_content_XmlBlock_nativeGetAttributeCount(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeCount()); } static jint android_content_XmlBlock_nativeGetAttributeNamespace(JNIEnv* env, jobject clazz, jlong token, jint idx) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeNamespaceID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeName(JNIEnv* env, jobject clazz, jlong token, jint idx) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeNameID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeResource(JNIEnv* env, jobject clazz, jlong token, jint idx) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeNameResID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeDataType(JNIEnv* env, jobject clazz, jlong token, jint idx) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeDataType(idx)); } static jint android_content_XmlBlock_nativeGetAttributeData(JNIEnv* env, jobject clazz, jlong token, jint idx) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeData(idx)); } static jint android_content_XmlBlock_nativeGetAttributeStringValue(JNIEnv* env, jobject clazz, jlong token, jint idx) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } return static_cast(st->getAttributeValueStringID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobject clazz, jlong token, jstring ns, jstring name) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL || name == NULL) { jniThrowNullPointerException(env, NULL); return 0; } const char16_t* ns16 = NULL; jsize nsLen = 0; if (ns) { ns16 = env->GetStringChars(ns, NULL); nsLen = env->GetStringLength(ns); } const char16_t* name16 = env->GetStringChars(name, NULL); jsize nameLen = env->GetStringLength(name); jint idx = static_cast(st->indexOfAttribute(ns16, nsLen, name16, nameLen)); if (ns) { env->ReleaseStringChars(ns, ns16); } env->ReleaseStringChars(name, name16); return idx; } static jint android_content_XmlBlock_nativeGetIdAttribute(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } ssize_t idx = st->indexOfID(); return idx >= 0 ? static_cast(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetClassAttribute(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } ssize_t idx = st->indexOfClass(); return idx >= 0 ? static_cast(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } ssize_t idx = st->indexOfStyle(); if (idx < 0) { return 0; } Res_value value; if (st->getAttributeValue(idx, &value) < 0) { return 0; } return value.dataType == value.TYPE_REFERENCE || value.dataType == value.TYPE_ATTRIBUTE ? value.data : 0; } static void android_content_XmlBlock_nativeDestroyParseState(JNIEnv* env, jobject clazz, jlong token) { ResXMLParser* st = reinterpret_cast(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return; } delete st; } static void android_content_XmlBlock_nativeDestroy(JNIEnv* env, jobject clazz, jlong token) { ResXMLTree* osb = reinterpret_cast(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return; } delete osb; } // ---------------------------------------------------------------------------- /* * JNI registration. */ static JNINativeMethod gXmlBlockMethods[] = { /* name, signature, funcPtr */ { "nativeCreate", "([BII)J", (void*) android_content_XmlBlock_nativeCreate }, { "nativeGetStringBlock", "(J)J", (void*) android_content_XmlBlock_nativeGetStringBlock }, { "nativeCreateParseState", "(J)J", (void*) android_content_XmlBlock_nativeCreateParseState }, { "nativeNext", "(J)I", (void*) android_content_XmlBlock_nativeNext }, { "nativeGetNamespace", "(J)I", (void*) android_content_XmlBlock_nativeGetNamespace }, { "nativeGetName", "(J)I", (void*) android_content_XmlBlock_nativeGetName }, { "nativeGetText", "(J)I", (void*) android_content_XmlBlock_nativeGetText }, { "nativeGetLineNumber", "(J)I", (void*) android_content_XmlBlock_nativeGetLineNumber }, { "nativeGetAttributeCount", "(J)I", (void*) android_content_XmlBlock_nativeGetAttributeCount }, { "nativeGetAttributeNamespace","(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeNamespace }, { "nativeGetAttributeName", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeName }, { "nativeGetAttributeResource", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeResource }, { "nativeGetAttributeDataType", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeDataType }, { "nativeGetAttributeData", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeData }, { "nativeGetAttributeStringValue", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeStringValue }, { "nativeGetAttributeIndex", "(JLjava/lang/String;Ljava/lang/String;)I", (void*) android_content_XmlBlock_nativeGetAttributeIndex }, { "nativeGetIdAttribute", "(J)I", (void*) android_content_XmlBlock_nativeGetIdAttribute }, { "nativeGetClassAttribute", "(J)I", (void*) android_content_XmlBlock_nativeGetClassAttribute }, { "nativeGetStyleAttribute", "(J)I", (void*) android_content_XmlBlock_nativeGetStyleAttribute }, { "nativeDestroyParseState", "(J)V", (void*) android_content_XmlBlock_nativeDestroyParseState }, { "nativeDestroy", "(J)V", (void*) android_content_XmlBlock_nativeDestroy }, }; int register_android_content_XmlBlock(JNIEnv* env) { return AndroidRuntime::registerNativeMethods(env, "android/content/res/XmlBlock", gXmlBlockMethods, NELEM(gXmlBlockMethods)); } }; // namespace android