/* --------------------------------------------------------------------------- Open Asset Import Library (ASSIMP) --------------------------------------------------------------------------- Copyright (c) 2006-2008, ASSIMP Development Team All rights reserved. See the disclaimer in JNIEnvironment.h for licensing and distribution conditions. --------------------------------------------------------------------------- */ /** @file Implementation of the JNI API for jAssimp */ #include "JNIEnvironment.h" #include "JNILogger.h" using namespace Assimp; namespace Assimp { namespace JNIBridge { // ------------------------------------------------------------------------------------------------ bool JNIEnvironment::AttachToCurrentThread (JNIEnv* pcEnv) { ai_assert(NULL != pcEnv); // now initialize the thread-local storage if (NULL == this->ptr.get()) { // attach to the current thread JavaVM* vm; pcEnv->GetJavaVM(&vm); vm->AttachCurrentThread((void **) &pcEnv, NULL); this->ptr.reset(new JNIThreadData(pcEnv)); } // increase the reference counter else this->ptr->m_iNumRef++; // attach the logger ((JNILogDispatcher*)DefaultLogger::get())->OnAttachToCurrentThread(this->ptr.get()); // get handles to all methods/fields/classes this->Initialize(); return true; } // ------------------------------------------------------------------------------------------------ bool JNIEnvironment::DetachFromCurrentThread () { ai_assert(NULL != pcEnv); // detach the logger ((JNILogDispatcher*)DefaultLogger::get())->OnDetachFromCurrentThread(this->ptr.get()); // decrease the reference counter if (NULL != this->ptr.get()) { this->ptr->m_iNumRef--; if (0 == this->ptr->m_iNumRef) { JavaVM* vm; this->ptr->m_pcEnv->GetJavaVM(&vm); vm->DetachCurrentThread(); } } return true; } // ------------------------------------------------------------------------------------------------ JNIThreadData* JNIEnvironment::GetThread() { ai_assert(NULL != this->ptr.get()); return this->ptr.get(); } // ------------------------------------------------------------------------------------------------ void JNIEnvironment::_java::_lang::_String::Initialize() { JNIEnv* pcEnv = JNIEnvironment::Get()->GetThread()->m_pcEnv; // first initialize some members if( !(this->Class = pcEnv->FindClass("java.lang.String"))) JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class java.lang.String"); if( !(this->getBytes = pcEnv->GetMethodID(this->Class,"getBytes","()[byte"))) JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class java.lang.String"); if( !(this->constructor_ByteArray = pcEnv->GetStaticMethodID( this->Class,"","([byte)V"))) JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class java.lang.String"); } // ------------------------------------------------------------------------------------------------ void JNIEnvironment::_java::_lang::_Array::Initialize() { JNIEnv* pcEnv = JNIEnvironment::Get()->GetThread()->m_pcEnv; if( !(this->FloatArray_Class = pcEnv->FindClass("[F"))) JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class float[]"); if( !(this->IntArray_Class = pcEnv->FindClass("[I"))) JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class int[]"); } // ------------------------------------------------------------------------------------------------ jstring JNU_NewStringNative(JNIEnv *env, const char *str) { jstring result; jbyteArray bytes = 0; int len; if (env->EnsureLocalCapacity( 2) < 0) { return NULL; /* out of memory error */ } len = (int)::strlen(str); bytes = env->NewByteArray(len); if (bytes != NULL) { env->SetByteArrayRegion(bytes, 0, len, (jbyte *)str); result = (jstring)env->NewObject(AIJ_GET_HANDLE(java.lang.String.Class), AIJ_GET_HANDLE(java.lang.String.constructor_ByteArray), bytes); env->DeleteLocalRef(bytes); return result; } /* else fall through */ return NULL; } // ------------------------------------------------------------------------------------------------ char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr) { jbyteArray bytes = 0; jthrowable exc; char *result = 0; if (env->EnsureLocalCapacity(2) < 0) { return 0; /* out of memory error */ } bytes = (jbyteArray)env->CallObjectMethod(jstr,AIJ_GET_HANDLE(java.lang.String.getBytes)); exc = env->ExceptionOccurred(); if (!exc) { jint len = env->GetArrayLength(bytes); result = (char *)malloc(len + 1); if (result == 0) { env->DeleteLocalRef(bytes); return 0; } env->GetByteArrayRegion(bytes, 0, len, (jbyte *)result); result[len] = 0; /* NULL-terminate */ } else { env->DeleteLocalRef(exc); } env->DeleteLocalRef(bytes); return result; } // ------------------------------------------------------------------------------------------------ void JNU_CopyDataToArray(JNIEnv* pc, jarray jfl, void* data, unsigned int size) { void* pf; jboolean iscopy = FALSE; // lock the array and get direct access to its buffer if(!(pf = pc->GetPrimitiveArrayCritical(jfl,&iscopy))) JNIEnvironment::Get()->ThrowNativeError("Unable to lock array"); // copy the data to the array ::memcpy(pf,data,size); // release our reference to the array pc->ReleasePrimitiveArrayCritical(jfl,pf,0); } // ------------------------------------------------------------------------------------------------ void JNU_CopyObjectArrayToVM(JNIEnv* pc, const void** in, unsigned int num, JNIEnvironment::_Base& type, jobjectArray& out) { jobjectArray jarr = pc->NewObjectArray(num,type.Class,0); for (unsigned int i = 0; i < num;++i) { jobject jobj = pc->NewObject(type.Class,type.DefaultCtor); type.Fill(jobj,in[i]); pc->SetObjectArrayElement(jarr,i,jobj); } out = jarr; } };};