blob: b66eccd085c536318195f50b6e810e3d87b7a683 [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 <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CommonUtils.h"
jbyteArray getStringBytes(JNIEnv* jEnv, jstring jString) {
jbyteArray result = NULL;
if (jString != NULL) {
jmethodID jGetBytesMethod = (*jEnv)->GetMethodID(jEnv, (*jEnv)->GetObjectClass(jEnv, jString), "getBytes", "()[B");
if (jGetBytesMethod != NULL) {
jbyteArray jBuffer = (jbyteArray) (*jEnv)->CallObjectMethod(jEnv, jString, jGetBytesMethod);
if (jBuffer != NULL) {
jsize jLength = (*jEnv)->GetArrayLength(jEnv, jBuffer);
result = (*jEnv)->NewByteArray(jEnv, jLength + 1);
if (jLength != 0) {
jbyte* jChars = (*jEnv)->GetByteArrayElements(jEnv, jBuffer, NULL);
(*jEnv)->SetByteArrayRegion(jEnv, result, 0, jLength, jChars);
(*jEnv)->ReleaseByteArrayElements(jEnv, jBuffer, jChars, JNI_ABORT);
}
(*jEnv)->DeleteLocalRef(jEnv, jBuffer);
}
//(*jEnv)->DeleteLocalRef(jEnv, getBytesMethod);
}
}
return result;
}
jstring newStringFromJByteArray(JNIEnv* jEnv, jbyteArray jByteArray, int length) {
jstring result = NULL;
jclass jStringClass = (*jEnv)->FindClass(jEnv, "java/lang/String");
if (jStringClass != NULL) {
jmethodID jStringConstructor = (*jEnv)->GetMethodID(jEnv, jStringClass, "<init>", "([BII)V");
if (jStringConstructor != NULL) {
result = (jstring) (*jEnv)->NewObject(jEnv, jStringClass, jStringConstructor, jByteArray, 0, length);
//(*jEnv)->DeleteLocalRef(jEnv, stringConstructor);
}
(*jEnv)->DeleteLocalRef(jEnv, jStringClass);
}
return result;
}
jstring newStringFromJCharArray(JNIEnv* jEnv, jcharArray jCharArray, int length) {
jstring result = NULL;
jclass jStringClass = (*jEnv)->FindClass(jEnv, "java/lang/String");
if (jStringClass != NULL) {
jmethodID jStringConstructor = (*jEnv)->GetMethodID(jEnv, jStringClass, "<init>", "([CII)V");
if (jStringConstructor != NULL) {
result = (jstring) (*jEnv)->NewObject(jEnv, jStringClass, jStringConstructor, jCharArray, 0, length);
}
(*jEnv)->DeleteLocalRef(jEnv, jStringClass);
}
return result;
}
jstring getString(JNIEnv* jEnv, const char* chars) {
return (jstring) getStringWithLength(jEnv, chars, (int) STRLEN(chars));
}
jstring getStringW(JNIEnv* jEnv, const wchar_t * chars) {
return (jstring) getStringWithLengthW(jEnv, chars, (int) WCSLEN(chars));
}
jstring getStringWithLength(JNIEnv* jEnv, const char* chars, int length) {
jstring result = NULL;
if (chars != NULL) {
if (length == 0) {
result = (*jEnv)->NewString(jEnv, (const jchar *) L"", 0);
} else {
jbyteArray jByteArray = (*jEnv)->NewByteArray(jEnv, length);
if (jByteArray != NULL) {
(*jEnv)->SetByteArrayRegion(jEnv, jByteArray, 0, length, (jbyte*) chars);
result = newStringFromJByteArray(jEnv, jByteArray, length);
(*jEnv)->DeleteLocalRef(jEnv, jByteArray);
}
}
}
return result;
}
jstring getStringWithLengthW(JNIEnv* jEnv, const wchar_t* chars, int length) {
jstring result = NULL;
if (chars != NULL) {
if (length == 0) {
result = (*jEnv)->NewString(jEnv, (const jchar *) L"", 0);
} else {
jcharArray jCharArray = (*jEnv)->NewCharArray(jEnv, length);
if (jCharArray != NULL) {
(*jEnv)->SetCharArrayRegion(jEnv, jCharArray, 0, length, (jchar*) chars);
result = newStringFromJCharArray(jEnv, jCharArray, length);
(*jEnv)->DeleteLocalRef(jEnv, jCharArray);
}
}
}
return result;
}
char* getChars(JNIEnv* jEnv, jstring jString) {
char* result = NULL;
jbyteArray jByteArray = getStringBytes(jEnv, jString);
if (jByteArray != NULL) {
jbyte* jBytes = (*jEnv)->GetByteArrayElements(jEnv, jByteArray, NULL);
long index = 0;
if (jBytes != NULL) {
int length = (int) STRLEN((char*) jBytes);
result = (char*) MALLOC(sizeof(char) * (length + 1));
if (result != NULL) {
ZERO(result, length);
STRNCPY(result, (char*) jBytes, length);
result[length] = 0;
}
(*jEnv)->ReleaseByteArrayElements(jEnv, jByteArray, jBytes, JNI_ABORT);
}
(*jEnv)->DeleteLocalRef(jEnv, jByteArray);
}
return result;
}
char* getStringFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) {
char* result = NULL;
jclass clazz = (*jEnv)->GetObjectClass(jEnv, object);
if (clazz != NULL) {
jmethodID method = (*jEnv)->GetMethodID(jEnv, clazz, methodName, "()Ljava/lang/String;");
if (method != NULL) {
jstring string = (jstring) (*jEnv)->CallObjectMethod(jEnv, object, method);
if (string != NULL) {
result = getChars(jEnv, string);
(*jEnv)->DeleteLocalRef(jEnv, string);
}
//(*jEnv)->DeleteLocalRef(jEnv, method);
}
(*jEnv)->DeleteLocalRef(jEnv, clazz);
}
return result;
}
wchar_t * getWideStringFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) {
wchar_t* result = NULL;
jclass clazz = (*jEnv)->GetObjectClass(jEnv, object);
if (clazz != NULL) {
jmethodID method = (*jEnv)->GetMethodID(jEnv, clazz, methodName, "()Ljava/lang/String;");
if (method != NULL) {
jstring string = (jstring) (*jEnv)->CallObjectMethod(jEnv, object, method);
if (string != NULL) {
result = getWideChars(jEnv, string);
(*jEnv)->DeleteLocalRef(jEnv, string);
}
//(*jEnv)->DeleteLocalRef(jEnv, method);
}
(*jEnv)->DeleteLocalRef(jEnv, clazz);
}
return result;
}
jboolean isInstanceOf(JNIEnv* jEnv, jobject object, const char* className) {
jboolean result = 0;
jclass clazz = clazz = (*jEnv)->FindClass(jEnv, className);
if (clazz != NULL) {
result = (*jEnv)->IsInstanceOf(jEnv, object, clazz);
(*jEnv)->DeleteLocalRef(jEnv, clazz);
}
return result;
}
jint getIntFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) {
jint value = 0;
jclass clazz = (*jEnv)->GetObjectClass(jEnv, object);
if (clazz != NULL) {
jmethodID method = (*jEnv)->GetMethodID(jEnv, clazz, methodName, "()I");
if (method != NULL) {
value = (*jEnv)->CallIntMethod(jEnv, object, method);
}
(*jEnv)->DeleteLocalRef(jEnv, clazz);
}
return value;
}
void throwException(JNIEnv* jEnv, const char* message) {
jclass clazz = (*jEnv)->FindClass(jEnv, "org/netbeans/installer/utils/exceptions/NativeException");
if (clazz != NULL) {
(*jEnv)->ThrowNew(jEnv, clazz, message);
(*jEnv)->DeleteLocalRef(jEnv, clazz);
}
}
void writeLog(JNIEnv* jEnv, int level, const char* message) {
const char* prefix = "[jni] ";
jclass clazz = (*jEnv)->FindClass(jEnv, "org/netbeans/installer/utils/LogManager");
if (clazz != NULL) {
jmethodID method = (*jEnv)->GetStaticMethodID(jEnv, clazz, "log", "(ILjava/lang/String;)V");
if (method != NULL) {
jstring jMessage = NULL;
int prefix_length = STRLEN(prefix);
int message_length = STRLEN(message);
char* string = (char*) MALLOC(sizeof(char) * (prefix_length + message_length + 1));
int i = 0;
for(i=0;i<prefix_length;i++) {
string[i]=prefix[i];
}
for(i=0;i<message_length;i++) {
string[i + prefix_length]=message[i];
}
string[i+prefix_length + message_length] = '\0';
jMessage = getString(jEnv, string);
if (jMessage != NULL) {
(*jEnv)->CallStaticVoidMethod(jEnv, clazz, method, (jint) level, jMessage);
(*jEnv)->DeleteLocalRef(jEnv, jMessage);
}
FREE(string);
//(*jEnv)->DeleteLocalRef(jEnv, method);
}
(*jEnv)->DeleteLocalRef(jEnv, clazz);
}
}
int createDirs(JNIEnv* jEnv, jstring jPath) {
int result = 0;
jclass jFileClass = (*jEnv)->FindClass(jEnv, "java/io/File");
if (jFileClass != NULL) {
jmethodID jFileConstructor = (*jEnv)->GetMethodID(jEnv, jFileClass, "<init>", "(Ljava/lang/String;)V");
jmethodID jGetParentFileMethod = (*jEnv)->GetMethodID(jEnv, jFileClass, "getParentFile", "()Ljava/io/File;");
jmethodID jExistsMethod = (*jEnv)->GetMethodID(jEnv, jFileClass, "exists", "()Z");
jmethodID jMkdirsMethod = (*jEnv)->GetMethodID(jEnv, jFileClass, "mkdirs", "()Z");
if ((jFileConstructor != NULL) && (jGetParentFileMethod != NULL) && (jExistsMethod != NULL) && (jMkdirsMethod != NULL)) {
jobject jFile = (*jEnv)->NewObject(jEnv, jFileClass, jFileConstructor, jPath);
if (jFile != NULL ) {
if(!((*jEnv)->CallBooleanMethod(jEnv, jFile, jExistsMethod))) {
jobject jParent = (*jEnv)->CallObjectMethod(jEnv, jFile, jGetParentFileMethod);
if (jParent != NULL) {
result = (*jEnv)->CallBooleanMethod(jEnv, jParent, jExistsMethod);
if (!result) {
result = (*jEnv)->CallBooleanMethod(jEnv, jParent, jMkdirsMethod);
}
(*jEnv)->DeleteLocalRef(jEnv, jParent);
}
} else {
result = 1;
}
(*jEnv)->DeleteLocalRef(jEnv, jFile);
}
}
(*jEnv)->DeleteLocalRef(jEnv, jFileClass);
}
return result;
}
int mkdirs(JNIEnv* jEnv, const char *path) {
int result = 1;
jstring jPath = getString(jEnv, path);
if (jPath != NULL) {
result = createDirs(jEnv, jPath);
(*jEnv)->DeleteLocalRef(jEnv, jPath);
}
return result;
}
int mkdirsW(JNIEnv* jEnv, const wchar_t *path) {
int result = 1;
jstring jPath = getStringW(jEnv, path);
if (jPath != NULL) {
result = createDirs(jEnv, jPath);
(*jEnv)->DeleteLocalRef(jEnv, jPath);
}
return result;
}
unsigned char* getByteFromMultiString(JNIEnv *jEnv, jobjectArray jObjectArray, unsigned long* size) {
unsigned short * result = NULL;
int totalLength = 0;
unsigned int arrayLength = (*jEnv)->GetArrayLength(jEnv, jObjectArray);
jstring jString = NULL;
unsigned int i, j; // just counters
for (i = 0; i < arrayLength; i++) {
jString = (jstring) (*jEnv)->GetObjectArrayElement(jEnv, jObjectArray, i);
totalLength += (*jEnv)->GetStringLength(jEnv, jString) + 1;
}
totalLength++; // add null to the end of array
result = (unsigned short*) MALLOC(sizeof(unsigned short) * totalLength);
if (result != NULL) {
int index = 0 ;
for (i = 0; i < arrayLength; i++) {
jString = (jstring) (*jEnv)->GetObjectArrayElement(jEnv, jObjectArray, i);
if (jString != NULL) {
wchar_t * chars = getWideChars(jEnv, jString);
if (chars != NULL) {
for (j = 0; j < (WCSLEN(chars)); j++) {
result[index++] = chars[j];
}
FREE(chars);
}
}
result[index++] = '\0';
}
result[index++] = '\0'; //double \0 at the end
}
* size = sizeof(unsigned short) * totalLength;
return (unsigned char*)result;
}
wchar_t * getWideChars(JNIEnv *jEnv, jstring jString) {
if(jString==NULL) {
return NULL;
} else {
long length = (*jEnv)->GetStringLength( jEnv, jString);
const jchar * unicodeStr = (*jEnv)->GetStringChars( jEnv, jString, 0 );
wchar_t * copy = (wchar_t *) MALLOC(sizeof(wchar_t) * (length + 1));
ZERO(copy, sizeof(wchar_t)*(length + 1));
WCSNCPY(copy, (const wchar_t *) unicodeStr, length + 1);
(*jEnv)->ReleaseStringChars( jEnv, jString, unicodeStr);
return copy;
}
}