1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "android_nio_utils.h" 18 19 #include "core_jni_helpers.h" 20 21 struct NioJNIData { 22 jclass nioAccessClass; 23 24 jmethodID getBasePointerID; 25 jmethodID getBaseArrayID; 26 jmethodID getBaseArrayOffsetID; 27 }; 28 29 static NioJNIData gNioJNI; 30 31 void* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) { 32 assert(array); 33 34 jlong pointer; 35 jint offset; 36 void *data; 37 38 pointer = _env->CallStaticLongMethod(gNioJNI.nioAccessClass, 39 gNioJNI.getBasePointerID, buffer); 40 if (pointer != 0L) { 41 *array = NULL; 42 return reinterpret_cast<void *>(pointer); 43 } 44 45 *array = (jarray) _env->CallStaticObjectMethod(gNioJNI.nioAccessClass, 46 gNioJNI.getBaseArrayID, buffer); 47 offset = _env->CallStaticIntMethod(gNioJNI.nioAccessClass, 48 gNioJNI.getBaseArrayOffsetID, buffer); 49 data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); 50 51 return (void *) ((char *) data + offset); 52 } 53 54 55 void android::nio_releasePointer(JNIEnv *_env, jarray array, void *data, 56 jboolean commit) { 57 _env->ReleasePrimitiveArrayCritical(array, data, 58 commit ? 0 : JNI_ABORT); 59 } 60 61 /////////////////////////////////////////////////////////////////////////////// 62 63 android::AutoBufferPointer::AutoBufferPointer(JNIEnv* env, jobject nioBuffer, 64 jboolean commit) { 65 fEnv = env; 66 fCommit = commit; 67 fPointer = android::nio_getPointer(env, nioBuffer, &fArray); 68 } 69 70 android::AutoBufferPointer::~AutoBufferPointer() { 71 if (NULL != fArray) { 72 android::nio_releasePointer(fEnv, fArray, fPointer, fCommit); 73 } 74 } 75 76 /////////////////////////////////////////////////////////////////////////////// 77 78 namespace android { 79 80 int register_android_nio_utils(JNIEnv* env) { 81 jclass localClass = FindClassOrDie(env, "java/nio/NIOAccess"); 82 gNioJNI.getBasePointerID = GetStaticMethodIDOrDie(env, localClass, "getBasePointer", 83 "(Ljava/nio/Buffer;)J"); 84 gNioJNI.getBaseArrayID = GetStaticMethodIDOrDie(env, localClass, "getBaseArray", 85 "(Ljava/nio/Buffer;)Ljava/lang/Object;"); 86 gNioJNI.getBaseArrayOffsetID = GetStaticMethodIDOrDie(env, localClass, "getBaseArrayOffset", 87 "(Ljava/nio/Buffer;)I"); 88 89 // now record a permanent version of the class ID 90 gNioJNI.nioAccessClass = MakeGlobalRefOrDie(env, localClass); 91 92 return 0; 93 } 94 95 } 96