diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch) | |
tree | 35051494d2af230dce54d6b31c6af8fc24091316 /core/jni/android_util_XmlBlock.cpp | |
download | frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2 |
Initial Contribution
Diffstat (limited to 'core/jni/android_util_XmlBlock.cpp')
-rw-r--r-- | core/jni/android_util_XmlBlock.cpp | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/core/jni/android_util_XmlBlock.cpp b/core/jni/android_util_XmlBlock.cpp new file mode 100644 index 0000000..8887fdc --- /dev/null +++ b/core/jni/android_util_XmlBlock.cpp @@ -0,0 +1,426 @@ +/* //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 <utils/misc.h> +#include <android_runtime/AndroidRuntime.h> +#include <utils/AssetManager.h> +#include <utils/Log.h> + +#include <utils/ResourceTypes.h> + +#include <stdio.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) +{ + jclass npeClazz; + + npeClazz = env->FindClass(exc); + LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc); + + env->ThrowNew(npeClazz, msg); +} + +static jint android_content_XmlBlock_nativeCreate(JNIEnv* env, jobject clazz, + jbyteArray bArray, + jint off, jint len) +{ + if (bArray == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + jsize bLen = env->GetArrayLength(bArray); + if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) { + doThrow(env, "java/lang/IndexOutOfBoundsException"); + return 0; + } + + jbyte* b = env->GetByteArrayElements(bArray, NULL); + ResXMLTree* osb = new ResXMLTree(b+off, len, true); + env->ReleaseByteArrayElements(bArray, b, 0); + + if (osb == NULL || osb->getError() != NO_ERROR) { + doThrow(env, "java/lang/IllegalArgumentException"); + return 0; + } + + return (jint)osb; +} + +static jint android_content_XmlBlock_nativeGetStringBlock(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLTree* osb = (ResXMLTree*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)&osb->getStrings(); +} + +static jint android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLTree* osb = (ResXMLTree*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + ResXMLParser* st = new ResXMLParser(*osb); + if (st == NULL) { + doThrow(env, "java/lang/OutOfMemoryError"); + return 0; + } + + st->restart(); + + return (jint)st; +} + +static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + return ResXMLParser::END_DOCUMENT; + } + + do { + jint code = (jint)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; + } + } while (true); + +bad: + doThrow(env, "org/xmlpull/v1/XmlPullParserException", + "Corrupt XML binary file"); + return ResXMLParser::BAD_DOCUMENT; +} + +static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + return -1; + } + + return (jint)st->getElementNamespaceID(); +} + +static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + return -1; + } + + return (jint)st->getElementNameID(); +} + +static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + return -1; + } + + return (jint)st->getTextID(); +} + +static jint android_content_XmlBlock_nativeGetLineNumber(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getLineNumber(); +} + +static jint android_content_XmlBlock_nativeGetAttributeCount(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeCount(); +} + +static jint android_content_XmlBlock_nativeGetAttributeNamespace(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeNamespaceID(idx); +} + +static jint android_content_XmlBlock_nativeGetAttributeName(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeNameID(idx); +} + +static jint android_content_XmlBlock_nativeGetAttributeResource(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeNameResID(idx); +} + +static jint android_content_XmlBlock_nativeGetAttributeDataType(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeDataType(idx); +} + +static jint android_content_XmlBlock_nativeGetAttributeData(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeData(idx); +} + +static jint android_content_XmlBlock_nativeGetAttributeStringValue(JNIEnv* env, jobject clazz, + jint token, jint idx) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + return (jint)st->getAttributeValueStringID(idx); +} + +static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobject clazz, + jint token, + jstring ns, jstring name) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL || name == NULL) { + doThrow(env, "java/lang/NullPointerException"); + 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 = (jint)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, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + ssize_t idx = st->indexOfID(); + return idx >= 0 ? (jint)st->getAttributeValueStringID(idx) : -1; +} + +static jint android_content_XmlBlock_nativeGetClassAttribute(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return 0; + } + + ssize_t idx = st->indexOfClass(); + return idx >= 0 ? (jint)st->getAttributeValueStringID(idx) : -1; +} + +static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + 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, + jint token) +{ + ResXMLParser* st = (ResXMLParser*)token; + if (st == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return; + } + + delete st; +} + +static void android_content_XmlBlock_nativeDestroy(JNIEnv* env, jobject clazz, + jint token) +{ + ResXMLTree* osb = (ResXMLTree*)token; + if (osb == NULL) { + doThrow(env, "java/lang/NullPointerException"); + return; + } + + delete osb; +} + +// ---------------------------------------------------------------------------- + +/* + * JNI registration. + */ +static JNINativeMethod gXmlBlockMethods[] = { + /* name, signature, funcPtr */ + { "nativeCreate", "([BII)I", + (void*) android_content_XmlBlock_nativeCreate }, + { "nativeGetStringBlock", "(I)I", + (void*) android_content_XmlBlock_nativeGetStringBlock }, + { "nativeCreateParseState", "(I)I", + (void*) android_content_XmlBlock_nativeCreateParseState }, + { "nativeNext", "(I)I", + (void*) android_content_XmlBlock_nativeNext }, + { "nativeGetNamespace", "(I)I", + (void*) android_content_XmlBlock_nativeGetNamespace }, + { "nativeGetName", "(I)I", + (void*) android_content_XmlBlock_nativeGetName }, + { "nativeGetText", "(I)I", + (void*) android_content_XmlBlock_nativeGetText }, + { "nativeGetLineNumber", "(I)I", + (void*) android_content_XmlBlock_nativeGetLineNumber }, + { "nativeGetAttributeCount", "(I)I", + (void*) android_content_XmlBlock_nativeGetAttributeCount }, + { "nativeGetAttributeNamespace","(II)I", + (void*) android_content_XmlBlock_nativeGetAttributeNamespace }, + { "nativeGetAttributeName", "(II)I", + (void*) android_content_XmlBlock_nativeGetAttributeName }, + { "nativeGetAttributeResource", "(II)I", + (void*) android_content_XmlBlock_nativeGetAttributeResource }, + { "nativeGetAttributeDataType", "(II)I", + (void*) android_content_XmlBlock_nativeGetAttributeDataType }, + { "nativeGetAttributeData", "(II)I", + (void*) android_content_XmlBlock_nativeGetAttributeData }, + { "nativeGetAttributeStringValue", "(II)I", + (void*) android_content_XmlBlock_nativeGetAttributeStringValue }, + { "nativeGetAttributeIndex", "(ILjava/lang/String;Ljava/lang/String;)I", + (void*) android_content_XmlBlock_nativeGetAttributeIndex }, + { "nativeGetIdAttribute", "(I)I", + (void*) android_content_XmlBlock_nativeGetIdAttribute }, + { "nativeGetClassAttribute", "(I)I", + (void*) android_content_XmlBlock_nativeGetClassAttribute }, + { "nativeGetStyleAttribute", "(I)I", + (void*) android_content_XmlBlock_nativeGetStyleAttribute }, + { "nativeDestroyParseState", "(I)V", + (void*) android_content_XmlBlock_nativeDestroyParseState }, + { "nativeDestroy", "(I)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 + |