blob: c569dd64fc7b0a344f6bfed2cdc5c1aee4389bab [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
#include "InteropUtil.h"
#include "Clr2JavaImpl.h"
using namespace System::Runtime::InteropServices;
ref class ManagedLog {
internal:
static BridgeLogger^ LOGGER = BridgeLogger::GetLogger("<C++>InteropUtil");
};
const wchar_t* UnicodeCppStringFromJavaString (
JNIEnv *env,
jstring javaString) {
const wchar_t* cppString = NULL;
if (NULL != javaString) {
cppString = (const wchar_t* )env->GetStringChars( javaString, 0);
}
return cppString;
}
void ReleaseUnicodeCppString (
JNIEnv* env,
jstring javaString,
jchar* cppString) {
if (NULL != cppString) {
env->ReleaseStringChars(javaString, (jchar *)cppString);
}
}
String^ ManagedStringFromJavaString (
JNIEnv *env,
jstring javaString) {
if (javaString != NULL) {
int len = env->GetStringLength(javaString);
const wchar_t* wcsStr = UnicodeCppStringFromJavaString (env, javaString);
String^ managedStr = (NULL == wcsStr || 0 == len) ? nullptr : Marshal::PtrToStringUni((IntPtr)(unsigned short*)wcsStr, len);
ReleaseUnicodeCppString (env, javaString, (jchar*)wcsStr);
return managedStr;
}
return nullptr;
}
bool ClrBoolFromJavaBoolean(
JNIEnv * env,
jboolean jbool) {
return jbool != JNI_FALSE;
}
jstring JavaStringFromManagedString(
JNIEnv *env,
String^ managedString) {
pin_ptr<const wchar_t> wch = PtrToStringChars(managedString);
return env->NewString((const jchar*)wch, managedString->Length);
}
jobject JavaArrayListFromManagedList(
JNIEnv *env,
System::Collections::Generic::ICollection<String^>^ managedNodeNames) {
jclass arrayListClazz = (*env).FindClass("java/util/ArrayList");
jobject arrayListObj = (*env).NewObject(arrayListClazz, (*env).GetMethodID(arrayListClazz, "<init>", "()V"));
for each (String^ nodeName in managedNodeNames)
{
jstring nodeNamestr = JavaStringFromManagedString(env, nodeName);
(*env).CallBooleanMethod(arrayListObj, (*env).GetMethodID(arrayListClazz, "add", "(Ljava/lang/Object;)Z"), nodeNamestr);
}
return arrayListObj;
}
void HandleClr2JavaError(
JNIEnv *env,
String^ errorMessage,
jobject javaObject) {
ManagedLog::LOGGER->LogStart("InteropUtil::HandleClr2JavaError");
jclass javaClass = env->GetObjectClass (javaObject);
jmethodID jmidOnError = env->GetMethodID(javaClass, "onError", "(Ljava/lang/String;)V");
if (jmidOnError == NULL) {
ManagedLog::LOGGER->Log("jmidOnError is NULL");
return;
}
env -> CallObjectMethod(
javaObject,
jmidOnError,
JavaStringFromManagedString(env, errorMessage));
ManagedLog::LOGGER->LogStop("InteropUtil::HandleClr2JavaError");
}
array<byte>^ ManagedByteArrayFromJavaByteArray(
JNIEnv *env,
jbyteArray javaByteArray) {
if (javaByteArray != NULL) {
byte* bytes = (byte*)env->GetByteArrayElements (javaByteArray, FALSE);
int len = env->GetArrayLength(javaByteArray);
array<byte>^ managedByteArray = gcnew array<byte>(len);
//System::Array
for (int i = 0; i < len; i++) {
managedByteArray[i] = bytes[i];
}
env->ReleaseByteArrayElements(javaByteArray, (jbyte*)bytes, JNI_ABORT);
return managedByteArray;
}
return nullptr;
}
jbyteArray JavaByteArrayFromManagedByteArray(
JNIEnv *env,
array<byte>^ managedByteArray) {
if (managedByteArray != nullptr) {
jbyteArray javaByteArray = env->NewByteArray(managedByteArray->Length);
pin_ptr<Byte> p = &managedByteArray[0];
env->SetByteArrayRegion(javaByteArray, 0, managedByteArray->Length, (jbyte*)p);
return javaByteArray;
}
return NULL;
}
__declspec(thread) JNIEnv *t_env = NULL;
JNIEnv* RetrieveEnv(JavaVM* jvm) {
if (NULL == t_env)
{
if (jvm->AttachCurrentThread((void **)&t_env, NULL) != 0) {
ManagedLog::LOGGER->Log("cannot attach jni env to current jvm thread.");
throw;
}
}
return t_env;
}
String^ FormatJavaExceptionMessage(String^ errorMessage, Exception^ exception, int recursionDepth) {
return (!exception)
? String::Concat(errorMessage, "null")
: recursionDepth >= 0
? String::Concat(errorMessage, Environment::NewLine,
exception->Message, Environment::NewLine,
exception->StackTrace, Environment::NewLine,
FormatJavaExceptionMessage( "Inner Exception: ", exception->InnerException, --recursionDepth))
: String::Concat(errorMessage, exception->GetType(), " ...");
}