19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_nio_utils.h" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct NioJNIData { 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass nioAccessClass; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jmethodID getBasePointerID; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jmethodID getBaseArrayID; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jmethodID getBaseArrayOffsetID; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic NioJNIData gNioJNI; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) { 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(array); 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jlong pointer; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint offset; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void *data; 35dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pointer = _env->CallStaticLongMethod(gNioJNI.nioAccessClass, 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.getBasePointerID, buffer); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pointer != 0L) { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *array = NULL; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (void *) (jint) pointer; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 42dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *array = (jarray) _env->CallStaticObjectMethod(gNioJNI.nioAccessClass, 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.getBaseArrayID, buffer); 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = _env->CallStaticIntMethod(gNioJNI.nioAccessClass, 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.getBaseArrayOffsetID, buffer); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); 48dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (void *) ((char *) data + offset); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid android::nio_releasePointer(JNIEnv *_env, jarray array, void *data, 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean commit) { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _env->ReleasePrimitiveArrayCritical(array, data, 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commit ? 0 : JNI_ABORT); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid::AutoBufferPointer::AutoBufferPointer(JNIEnv* env, jobject nioBuffer, 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jboolean commit) { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fEnv = env; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fCommit = commit; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fPointer = android::nio_getPointer(env, nioBuffer, &fArray); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid::AutoBufferPointer::~AutoBufferPointer() { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != fArray) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android::nio_releasePointer(fEnv, fArray, fPointer, fCommit); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass findClass(JNIEnv* env, const char name[]) { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass c = env->FindClass(name); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(!c, "Unable to find class %s", name); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return c; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID findStaticMethod(JNIEnv* env, jclass c, const char method[], 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char params[]) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jmethodID m = env->GetStaticMethodID(c, method, params); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(!m, "Unable to find method %s", method); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return m; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID getFieldID(JNIEnv* env, jclass c, const char name[], 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char type[]) { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID f = env->GetFieldID(c, name, type); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(!f, "Unable to find field %s", name); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return f; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 97dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_nio_utils(JNIEnv* env) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass localClass = findClass(env, "java/nio/NIOAccess"); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.getBasePointerID = findStaticMethod(env, localClass, 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "getBasePointer", "(Ljava/nio/Buffer;)J"); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.getBaseArrayID = findStaticMethod(env, localClass, 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;"); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.getBaseArrayOffsetID = findStaticMethod(env, localClass, 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "getBaseArrayOffset", "(Ljava/nio/Buffer;)I"); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now record a permanent version of the class ID 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gNioJNI.nioAccessClass = (jclass) env->NewGlobalRef(localClass); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 114