Mercurial > hg > octave-lyh
diff libinterp/dldfcn/__java__.cc @ 15745:19850dfc2f88
* __java__.h, __java__.cc: Style fixes.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 07 Dec 2012 16:04:58 -0500 |
parents | 686580b1a934 |
children | da26f72408a7 |
line wrap: on
line diff
--- a/libinterp/dldfcn/__java__.cc +++ b/libinterp/dldfcn/__java__.cc @@ -18,21 +18,11 @@ #include <config.h> #endif -#ifdef HAVE_JAVA -#include "__java__.h" +#if defined HAVE_JAVA -#include "parse.h" -#include "Cell.h" -#include "file-stat.h" -#include "file-ops.h" -#include "cmd-edit.h" -#ifdef __WIN32__ +#if defined (HAVE_WINDWOS_H) #include <windows.h> #endif -#include "load-path.h" -#include "oct-env.h" -#include "oct-shlib.h" -#include "oct-env.h" #include <algorithm> #include <map> @@ -41,23 +31,41 @@ #include <clocale> +#include "Cell.h" +#include "__java__.h" +#include "cmd-edit.h" +#include "file-ops.h" +#include "file-stat.h" +#include "load-path.h" +#include "oct-env.h" +#include "oct-env.h" +#include "oct-shlib.h" +#include "parse.h" + typedef jint (JNICALL *JNI_CreateJavaVM_t) (JavaVM **pvm, JNIEnv **penv, void *args); typedef jint (JNICALL *JNI_GetCreatedJavaVMs_t) (JavaVM **pvm, jsize bufLen, jsize *nVMs); -extern "C" JNIEXPORT jboolean JNICALL Java_org_octave_Octave_call - (JNIEnv *, jclass, jstring, jobjectArray, jobjectArray); -extern "C" JNIEXPORT void JNICALL Java_org_octave_OctaveReference_doFinalize - (JNIEnv *, jclass, jint); -extern "C" JNIEXPORT void JNICALL Java_org_octave_Octave_doInvoke - (JNIEnv *, jclass, jint, jobjectArray); -extern "C" JNIEXPORT void JNICALL Java_org_octave_Octave_doEvalString - (JNIEnv *, jclass, jstring); -extern "C" JNIEXPORT jboolean JNICALL Java_org_octave_Octave_needThreadedInvokation - (JNIEnv *, jclass); +extern "C" +{ + JNIEXPORT jboolean JNICALL + Java_org_octave_Octave_call (JNIEnv *, jclass, jstring, jobjectArray, + jobjectArray); + JNIEXPORT void JNICALL + Java_org_octave_OctaveReference_doFinalize (JNIEnv *, jclass, jint); + + JNIEXPORT void JNICALL + Java_org_octave_Octave_doInvoke (JNIEnv *, jclass, jint, jobjectArray); -static octave_value _java_new ( const octave_value_list& args ); -static octave_value _java_invoke ( const octave_value_list& args ); - + JNIEXPORT void JNICALL + Java_org_octave_Octave_doEvalString (JNIEnv *, jclass, jstring); + + JNIEXPORT jboolean JNICALL + Java_org_octave_Octave_needThreadedInvokation (JNIEnv *, jclass); +} + +static octave_value _java_new (const octave_value_list& args); +static octave_value _java_invoke (const octave_value_list& args); + static JavaVM *jvm = 0; static bool jvm_attached = false; @@ -76,96 +84,103 @@ class JVMArgs { public: - JVMArgs () - { - vm_args.version = JNI_VERSION_1_2; - vm_args.nOptions = 0; - vm_args.options = 0; - vm_args.ignoreUnrecognized = false; - } - ~JVMArgs () - { - clean (); - } + JVMArgs (void) + { + vm_args.version = JNI_VERSION_1_2; + vm_args.nOptions = 0; + vm_args.options = 0; + vm_args.ignoreUnrecognized = false; + } + + ~JVMArgs (void) + { + clean (); + } JavaVMInitArgs* to_args () - { - update (); - return &vm_args; - } + { + update (); + return &vm_args; + } void add (const std::string& opt) - { - java_opts.push_back (opt); - } + { + java_opts.push_back (opt); + } void read_java_opts (const std::string& filename) - { - std::ifstream js (filename.c_str ()); + { + std::ifstream js (filename.c_str ()); - if (! js.bad () && ! js.fail ()) - { - std::string line; + if (! js.bad () && ! js.fail ()) + { + std::string line; - while (! js.eof () && ! js.fail ()) - { - std::getline (js, line); - if (line.length () > 2 && - (line.find ("-D") == 0 || line.find ("-X") == 0)) - java_opts.push_back (line); - else if (line.length () > 0 && Vjava_debug) - std::cerr << "invalid JVM option, skipping: " << line << std::endl; - } - } - } + while (! js.eof () && ! js.fail ()) + { + std::getline (js, line); + if (line.length () > 2 + && (line.find ("-D") == 0 || line.find ("-X") == 0)) + java_opts.push_back (line); + else if (line.length () > 0 && Vjava_debug) + std::cerr << "invalid JVM option, skipping: " << line << std::endl; + } + } + } private: - void clean () - { - if (vm_args.options != 0) - { - for (int i=0; i<vm_args.nOptions; i++) - delete [] vm_args.options[i].optionString; - delete [] vm_args.options; - vm_args.options = 0; - vm_args.nOptions = 0; - } - } + void clean (void) + { + if (vm_args.options != 0) + { + for (int i = 0; i < vm_args.nOptions; i++) + delete [] vm_args.options[i].optionString; + delete [] vm_args.options; + + vm_args.options = 0; + vm_args.nOptions = 0; + } + } - void update () - { - clean (); - if (java_opts.size () > 0) - { - int index = 0; + void update (void) + { + clean (); + + if (java_opts.size () > 0) + { + int index = 0; - vm_args.nOptions = java_opts.size (); - vm_args.options = new JavaVMOption [vm_args.nOptions]; - for (std::list<std::string>::const_iterator it = java_opts.begin (); it != java_opts.end (); ++it) - { - if (Vjava_debug) - std::cout << *it << std::endl; - vm_args.options[index++].optionString = strsave ((*it).c_str ()); - } - java_opts.clear (); - } - } + vm_args.nOptions = java_opts.size (); + vm_args.options = new JavaVMOption [vm_args.nOptions]; + for (std::list<std::string>::const_iterator it = java_opts.begin (); it != java_opts.end (); ++it) + { + if (Vjava_debug) + std::cout << *it << std::endl; + vm_args.options[index++].optionString = strsave ((*it).c_str ()); + } + java_opts.clear (); + } + } private: + JavaVMInitArgs vm_args; + std::list<std::string> java_opts; }; static dim_vector compute_array_dimensions (JNIEnv* jni_env, jobject obj); #ifdef __WIN32__ -static std::string read_registry_string (const std::string& key, const std::string& value) +static std::string +read_registry_string (const std::string& key, const std::string& value) { HKEY hkey; DWORD len; - std::string retval = ""; + + std::string retval; if (! RegOpenKeyEx (HKEY_LOCAL_MACHINE, key.c_str (), 0, KEY_READ, &hkey)) { @@ -174,18 +189,20 @@ retval.resize (len); if (RegQueryValueEx (hkey, value.c_str (), 0, 0, (LPBYTE)&retval[0], &len)) retval = ""; - else if (retval[len-1] == '\0') - retval.resize (--len); + else if (retval[len-1] == '\0') + retval.resize (--len); } RegCloseKey (hkey); } + return retval; } -static std::string get_module_filename (HMODULE hMod) +static std::string +get_module_filename (HMODULE hMod) { int n = 1024; - std::string retval(n, '\0'); + std::string retval (n, '\0'); bool found = false; while (n < 65536) @@ -207,7 +224,8 @@ return (found ? retval : ""); } -static void set_dll_directory (const std::string& dir = "") +static void +set_dll_directory (const std::string& dir = "") { typedef BOOL (WINAPI *dllfcn_t) (LPCTSTR path); @@ -226,11 +244,12 @@ } #endif -static std::string get_module_path (const std::string& name, bool strip_name = true) +static std::string +get_module_path (const std::string& name, bool strip_name = true) { std::string retval; - retval = octave_env::make_absolute (load_path::find_file (name), + retval = octave_env::make_absolute (load_path::find_file (name), octave_env::get_current_directory ()); if (! retval.empty ()) @@ -251,7 +270,8 @@ return retval; } -static std::string initial_java_dir (bool arch_dependent = false) +static std::string +initial_java_dir (bool arch_dependent = false) { static std::string path1; static std::string path2; @@ -260,196 +280,197 @@ { if (path1.empty ()) path1 = get_module_path ("__java__.oct", true); + return path1; } else { if (path2.empty ()) path2 = get_module_path ("javaclasspath.m", true); + return path2; } } -/* - * Read the content of a file filename (usually "classpath.txt") - * - * Returns a string with all lines concatenated and separated - * by the path separator character. - * The return string also starts with a path separator so that - * it can be appended easily to a base classpath. - * - * The file "classpath.txt" must contain single lines, each - * with a classpath. - * Comment lines starting with a '#' or a '%' in column 1 are allowed. - * - * On Windiows the usual path separator is a ';', on Unix a ':'. - * - * Created: 28 Aug 2010 Martin Hepperle - */ -static std::string read_classpath_txt (const std::string& filepath) +// Read the content of a file filename (usually "classpath.txt") +// +// Returns a string with all lines concatenated and separated +// by the path separator character. +// The return string also starts with a path separator so that +// it can be appended easily to a base classpath. +// +// The file "classpath.txt" must contain single lines, each +// with a classpath. +// Comment lines starting with a '#' or a '%' in column 1 are allowed. + +static std::string +read_classpath_txt (const std::string& filepath) { - std::string classpath; + std::string classpath; + + std::ifstream fs (filepath.c_str ()); - std::ifstream fs (filepath.c_str ()); - - if (! fs.bad () && ! fs.fail ()) + if (! fs.bad () && ! fs.fail ()) { - std::string line; + std::string line; - while (! fs.eof () && ! fs.fail ()) + while (! fs.eof () && ! fs.fail ()) { - std::getline (fs, line); - if (line.length () > 1 ) + std::getline (fs, line); + + if (line.length () > 1) { - if ( (line.at(0) == '#') || - (line.at(0) == '%') ) - { - // this is a comment line: skip - } - else - { + if (line.at(0) == '#' || line.at(0) == '%') + ; // skip comments + else + { // prepend separator character - classpath.append(dir_path::path_sep_str()); + classpath.append (dir_path::path_sep_str ()); + // append content of line without trailing blanks - int iLast = line.find_last_not_of(' '); - classpath.append(file_ops::tilde_expand(line.substr(0,iLast+1))); - } + int iLast = line.find_last_not_of (' '); + + classpath.append (file_ops::tilde_expand (line.substr (0, iLast+1))); + } } } } - return ( classpath ); + + return (classpath); } -static std::string initial_class_path () +static std::string +initial_class_path (void) { - std::string retval = initial_java_dir (); + std::string retval = initial_java_dir (); - // find octave.jar file - if (! retval.empty ()) + // find octave.jar file + if (! retval.empty ()) { std::string jar_file = get_module_path ("octave.jar", false); file_stat jar_exists (jar_file); if (jar_exists) - { - // initialize static classpath to octave.jar - retval = jar_file; + { + // initialize static classpath to octave.jar + retval = jar_file; + + + // The base classpath has been set. Try to find the optional + // file "classpath.txt" in two places. The users classes will + // take precedence over the settings defined in the package + // directory + + std::string str_filename = "classpath.txt"; + std::string cp_file; + file_stat cp_exists; + + // Try to read the file "classpath.txt" in the user's home + // directory. - /* - * The base classpath has been set. - * Try to find the optional file "classpath.txt" in two places. - * The users classes will take precedence over the settings - * defined in the package directory - */ - std::string str_filename = "classpath.txt"; - std::string cp_file; - file_stat cp_exists; - /* - * Try to read the file "classpath.txt" in the user's home directory - */ - cp_file = file_ops::tilde_expand ( "~" + file_ops::dir_sep_str () + str_filename ); - cp_exists = file_stat(cp_file); - if (cp_exists) - { - /* - * The file "classpath.txt" has been found: add its contents to the static classpath - */ - std::string theClassPath = read_classpath_txt (cp_file); - retval.append(theClassPath); - } - /* - * Try to read a file "classpath.txt" in the package directory - */ - cp_file = initial_java_dir () + file_ops::dir_sep_str () + str_filename; - cp_exists = file_stat(cp_file); - if (cp_exists) - { - /* - * The file "classpath.txt" has been found: add its contents to the static classpath - */ - std::string theClassPath = read_classpath_txt (cp_file); - retval.append(theClassPath); - } - } + cp_file = file_ops::tilde_expand ("~" + file_ops::dir_sep_str () + str_filename); + cp_exists = file_stat (cp_file); + if (cp_exists) + { + // The file "classpath.txt" has been found: add its + // contents to the static classpath. + + std::string theClassPath = read_classpath_txt (cp_file); + retval.append (theClassPath); + } + + // Try to read a file "classpath.txt" in the package directory. + + cp_file = initial_java_dir () + file_ops::dir_sep_str () + str_filename; + cp_exists = file_stat (cp_file); + if (cp_exists) + { + // The file "classpath.txt" has been found: add its + // contents to the static classpath. + + std::string theClassPath = read_classpath_txt (cp_file); + retval.append (theClassPath); + } + } else - { - throw std::string("octave jar does not exist: ") + jar_file; - } + throw std::string ("octave jar does not exist: ") + jar_file; } else - { - throw std::string("initial java dir is empty"); - } + throw std::string ("initial java dir is empty"); return retval; } -static void initialize_jvm () +static void +initialize_jvm (void) { JNIEnv *current_env; - if (jvm) return; + if (jvm) + return; - const char *static_locale = setlocale(LC_ALL, NULL); - const std::string locale(static_locale); + const char *static_locale = setlocale (LC_ALL, NULL); + const std::string locale (static_locale); #if defined (__WIN32__) - HMODULE hMod = GetModuleHandle("jvm.dll"); + HMODULE hMod = GetModuleHandle ("jvm.dll"); std::string jvm_lib_path; std::string old_cwd; if (hMod == NULL) - { - // In windows, find the location of the JRE from the registry - // and load the symbol from the dll. - std::string key, value; + { + // In windows, find the location of the JRE from the registry + // and load the symbol from the dll. + std::string key, value; - key = "software\\javasoft\\java runtime environment"; + key = "software\\javasoft\\java runtime environment"; - value = octave_env::getenv ("JAVA_VERSION"); - if (value.empty ()) - { - value = "Currentversion"; - std::string regval = read_registry_string (key,value); - if (regval.empty ()) - throw std::string ("unable to find Java Runtime Environment: ")+key+"::"+value; - value = regval; - } + value = octave_env::getenv ("JAVA_VERSION"); + if (value.empty ()) + { + value = "Currentversion"; + std::string regval = read_registry_string (key,value); - key = key + "\\" + value; - value = "RuntimeLib"; - jvm_lib_path = read_registry_string (key,value); - if (jvm_lib_path.empty()) - throw std::string ("unable to find Java Runtime Environment: ")+key+"::"+value; + if (regval.empty ()) + throw std::string ("unable to find Java Runtime Environment: ") + key + "::" + value; + value = regval; + } + + key = key + "\\" + value; + value = "RuntimeLib"; + jvm_lib_path = read_registry_string (key, value); + if (jvm_lib_path.empty ()) + throw std::string ("unable to find Java Runtime Environment: ") + key + "::" + value; - std::string jvm_bin_path; + std::string jvm_bin_path; - value = "JavaHome"; - jvm_bin_path = read_registry_string (key, value); - if (! jvm_bin_path.empty ()) - { - jvm_bin_path = (jvm_bin_path + std::string ("\\bin")); + value = "JavaHome"; + jvm_bin_path = read_registry_string (key, value); + if (! jvm_bin_path.empty ()) + { + jvm_bin_path = (jvm_bin_path + std::string ("\\bin")); - old_cwd = octave_env::get_current_directory (); + old_cwd = octave_env::get_current_directory (); - set_dll_directory (jvm_bin_path); - octave_env::chdir (jvm_bin_path); - } - } + set_dll_directory (jvm_bin_path); + octave_env::chdir (jvm_bin_path); + } + } else - { - // JVM seems to be already loaded, better to use that DLL instead - // of looking in the registry, to avoid opening a different JVM. - jvm_lib_path = get_module_filename(hMod); - if (jvm_lib_path.empty()) - throw std::string ("unable to find Java Runtime Environment"); - } + { + // JVM seems to be already loaded, better to use that DLL instead + // of looking in the registry, to avoid opening a different JVM. + jvm_lib_path = get_module_filename (hMod); + + if (jvm_lib_path.empty ()) + throw std::string ("unable to find Java Runtime Environment"); + } #else - std::string jvm_lib_path = JAVA_HOME+std::string("/jre/lib/")+JAVA_ARCH+"/server/libjvm.so"; + std::string jvm_lib_path = JAVA_HOME + std::string ("/jre/lib/") + JAVA_ARCH + "/server/libjvm.so"; #endif @@ -458,23 +479,29 @@ # if !defined (__APPLE__) && !defined (__MACH__) octave_shlib lib (jvm_lib_path); - if (!lib) - throw std::string("unable to load Java Runtime Environment from ")+jvm_lib_path; + + if (!lib) + throw std::string ("unable to load Java Runtime Environment from ") + jvm_lib_path; #if defined (__WIN32__) + set_dll_directory (); + if (! old_cwd.empty ()) octave_env::chdir (old_cwd); + #endif - JNI_CreateJavaVM_t create_vm = reinterpret_cast<JNI_CreateJavaVM_t> (lib.search("JNI_CreateJavaVM")); - JNI_GetCreatedJavaVMs_t get_vm = reinterpret_cast<JNI_GetCreatedJavaVMs_t> (lib.search("JNI_GetCreatedJavaVMs")); + JNI_CreateJavaVM_t create_vm = reinterpret_cast<JNI_CreateJavaVM_t> (lib.search ("JNI_CreateJavaVM")); + JNI_GetCreatedJavaVMs_t get_vm = reinterpret_cast<JNI_GetCreatedJavaVMs_t> (lib.search ("JNI_GetCreatedJavaVMs")); + if (!create_vm) - throw std::string("unable to find JNI_CreateJavaVM in ")+jvm_lib_path; + throw std::string ("unable to find JNI_CreateJavaVM in ") + jvm_lib_path; + if (!get_vm) - throw std::string("unable to find JNI_GetCreatedJavaVMs in ")+jvm_lib_path; + throw std::string ("unable to find JNI_GetCreatedJavaVMs in ") + jvm_lib_path; - if (get_vm(&jvm, 1, &nVMs) == 0 && nVMs > 0) + if (get_vm (&jvm, 1, &nVMs) == 0 && nVMs > 0) #else @@ -482,70 +509,73 @@ // octave_shlib lib (jvm_lib_path) // doesn't work with 'not-bundled' *.oct files. - if (JNI_GetCreatedJavaVMs(&jvm, 1, &nVMs) == 0 && nVMs > 0) + if (JNI_GetCreatedJavaVMs (&jvm, 1, &nVMs) == 0 && nVMs > 0) #endif - { - // At least one JVM exists, try to attach to it - - switch (jvm->GetEnv(reinterpret_cast<void **> (¤t_env), JNI_VERSION_1_2)) { - case JNI_EDETACHED: - // Attach the current thread - JavaVMAttachArgs vm_args; - vm_args.version = JNI_VERSION_1_2; - vm_args.name = const_cast<char *> ("octave"); - vm_args.group = NULL; - if (jvm->AttachCurrentThread (reinterpret_cast<void **> (¤t_env), &vm_args) < 0) - throw std::string("JVM internal error, unable to attach octave to existing JVM"); - break; - case JNI_EVERSION: - throw std::string("JVM internal error, the required JNI version is not supported"); - break; - case JNI_OK: - // Don't do anything, the current thread is already attached to JVM - break; + // At least one JVM exists, try to attach to it + + switch (jvm->GetEnv (reinterpret_cast<void **> (¤t_env), JNI_VERSION_1_2)) + { + case JNI_EDETACHED: + // Attach the current thread + JavaVMAttachArgs vm_args; + vm_args.version = JNI_VERSION_1_2; + vm_args.name = const_cast<char *> ("octave"); + vm_args.group = NULL; + if (jvm->AttachCurrentThread (reinterpret_cast<void **> (¤t_env), &vm_args) < 0) + throw std::string ("JVM internal error, unable to attach octave to existing JVM"); + break; + + case JNI_EVERSION: + throw std::string ("JVM internal error, the required JNI version is not supported"); + break; + + case JNI_OK: + // Don't do anything, the current thread is already attached to JVM + break; + } + + jvm_attached = true; + //printf ("JVM attached\n"); } + else + { + // No JVM exists, create one - jvm_attached = true; - //printf("JVM attached\n"); - } - else - { - // No JVM exists, create one + JVMArgs vm_args; - JVMArgs vm_args; - - vm_args.add ("-Djava.class.path=" + initial_class_path ()); - vm_args.add ("-Doctave.java.path=" + initial_java_dir (true)); - vm_args.add ("-Xrs"); - vm_args.add ("-Djava.system.class.loader=org.octave.OctClassLoader"); - vm_args.read_java_opts (initial_java_dir (false) + file_ops::dir_sep_str () + "java.opts"); + vm_args.add ("-Djava.class.path=" + initial_class_path ()); + vm_args.add ("-Doctave.java.path=" + initial_java_dir (true)); + vm_args.add ("-Xrs"); + vm_args.add ("-Djava.system.class.loader=org.octave.OctClassLoader"); + vm_args.read_java_opts (initial_java_dir (false) + file_ops::dir_sep_str () + "java.opts"); # if !defined (__APPLE__) && !defined (__MACH__) - if (create_vm (&jvm, ¤t_env, vm_args.to_args ()) != JNI_OK) - throw std::string("unable to start Java VM in ")+jvm_lib_path; - //printf("JVM created\n"); - } - + if (create_vm (&jvm, ¤t_env, vm_args.to_args ()) != JNI_OK) + throw std::string ("unable to start Java VM in ")+jvm_lib_path; + //printf ("JVM created\n"); + } + jvm_lib = lib; #else - if (JNI_CreateJavaVM (&jvm, reinterpret_cast<void **>(¤t_env), - vm_args.to_args ()) != JNI_OK) - throw std::string("unable to start Java VM in ")+jvm_lib_path; + if (JNI_CreateJavaVM (&jvm, reinterpret_cast<void **> (¤t_env), + vm_args.to_args ()) != JNI_OK) + throw std::string ("unable to start Java VM in ")+jvm_lib_path; - } + } #endif - setlocale(LC_ALL, locale.c_str()); + setlocale (LC_ALL, locale.c_str ()); } -static void terminate_jvm(void) +static void +terminate_jvm (void) { if (jvm) { @@ -553,6 +583,7 @@ jvm->DetachCurrentThread (); else jvm->DestroyJavaVM (); + jvm = 0; jvm_attached = false; @@ -561,21 +592,26 @@ } } -std::string jstring_to_string (JNIEnv* jni_env, jstring s) +std::string +jstring_to_string (JNIEnv* jni_env, jstring s) { std::string retval; + if (jni_env) { const char *cstr = jni_env->GetStringUTFChars (s, 0); retval = cstr; jni_env->ReleaseStringUTFChars (s, cstr); } + return retval; } -std::string jstring_to_string (JNIEnv* jni_env, jobject obj) +std::string +jstring_to_string (JNIEnv* jni_env, jobject obj) { std::string retval; + if (jni_env && obj) { jclass_ref cls (jni_env, jni_env->FindClass ("java/lang/String")); @@ -585,18 +621,22 @@ retval = jstring_to_string (jni_env, reinterpret_cast<jstring> (obj)); } } + return retval; } -static octave_value check_exception (JNIEnv* jni_env) +static octave_value +check_exception (JNIEnv* jni_env) { octave_value retval; + jthrowable_ref ex (jni_env, jni_env->ExceptionOccurred ()); if (ex) { if (Vjava_debug) jni_env->ExceptionDescribe (); + jni_env->ExceptionClear (); jclass_ref jcls (jni_env, jni_env->GetObjectClass (ex)); @@ -608,14 +648,16 @@ } else retval = Matrix (); + return retval; } -static jclass find_octave_class (JNIEnv *jni_env, const char *name) +static jclass +find_octave_class (JNIEnv *jni_env, const char *name) { static std::string class_loader; static jclass uiClass = 0; - + jclass jcls = jni_env->FindClass (name); if (jcls == 0) @@ -631,7 +673,7 @@ jstring_ref js (jni_env, jni_env->NewStringUTF ("octave.class.loader")); js = reinterpret_cast<jstring> (jni_env->CallStaticObjectMethod (syscls, mID, jstring (js))); class_loader = jstring_to_string (jni_env, jstring (js)); - std::replace (class_loader.begin(), class_loader.end (), '.', '/'); + std::replace (class_loader.begin (), class_loader.end (), '.', '/'); } jclass_ref uicls (jni_env, jni_env->FindClass (class_loader.c_str ())); @@ -641,7 +683,7 @@ jni_env->ExceptionClear (); /* Try the netbeans way */ - std::replace (class_loader.begin(), class_loader.end (), '/', '.'); + std::replace (class_loader.begin (), class_loader.end (), '/', '.'); jclass_ref jcls2 (jni_env, jni_env->FindClass ("org/openide/util/Lookup")); jmethodID mID = jni_env->GetStaticMethodID (jcls2, "getDefault", "()Lorg/openide/util/Lookup;"); jobject_ref lObj (jni_env, jni_env->CallStaticObjectMethod (jcls2, mID)); @@ -664,16 +706,19 @@ jcls = reinterpret_cast<jclass> (jni_env->CallStaticObjectMethod (uiClass, mID, jstring (js))); } } + return jcls; } -static dim_vector compute_array_dimensions (JNIEnv* jni_env, jobject obj) +static dim_vector +compute_array_dimensions (JNIEnv* jni_env, jobject obj) { jobjectArray_ref jobj (jni_env, reinterpret_cast<jobjectArray> (obj)); jclass_ref jcls (jni_env, jni_env->GetObjectClass (obj)); jclass_ref ccls (jni_env, jni_env->GetObjectClass (jcls)); jmethodID isArray_ID = jni_env->GetMethodID (ccls, "isArray", "()Z"), getComponentType_ID = jni_env->GetMethodID (ccls, "getComponentType", "()Ljava/lang/Class;"); + dim_vector dv (1, 1); int idx = 0; @@ -683,45 +728,56 @@ int len = (jobj ? jni_env->GetArrayLength (jobj) : 0); if (idx >= dv.length ()) dv.resize (idx+1); - dv (idx) = len; + dv(idx) = len; jcls = reinterpret_cast<jclass> (jni_env->CallObjectMethod (jcls, getComponentType_ID)); jobj = (len > 0 ? reinterpret_cast<jobjectArray> (jni_env->GetObjectArrayElement (jobj, 0)) : 0); idx++; } + return dv; } -static jobject make_java_index (JNIEnv* jni_env, const octave_value_list& idx) +static jobject +make_java_index (JNIEnv* jni_env, const octave_value_list& idx) { jclass_ref ocls (jni_env, jni_env->FindClass ("[I")); jobjectArray retval = jni_env->NewObjectArray (idx.length (), ocls, 0); - for (int i=0; i<idx.length (); i++) + + for (int i = 0; i < idx.length (); i++) { idx_vector v = idx(i).index_vector (); + if (! error_state) { jintArray_ref i_array (jni_env, jni_env->NewIntArray (v.length ())); jint *buf = jni_env->GetIntArrayElements (i_array, 0); - for (int k=0; k<v.length (); k++) + + for (int k = 0; k < v.length (); k++) buf[k] = v(k); + jni_env->ReleaseIntArrayElements (i_array, buf, 0); jni_env->SetObjectArrayElement (retval, i, i_array); + check_exception (jni_env); + if (error_state) break; } else break; } + return retval; } -static octave_value get_array_elements (JNIEnv* jni_env, jobject jobj, const octave_value_list& idx) +static octave_value +get_array_elements (JNIEnv* jni_env, jobject jobj, + const octave_value_list& idx) { octave_value retval; jobject_ref resObj (jni_env); jobject_ref java_idx (jni_env, make_java_index (jni_env, idx)); - + if (! error_state) { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); @@ -737,13 +793,16 @@ return retval; } -static octave_value set_array_elements (JNIEnv* jni_env, jobject jobj, const octave_value_list& idx, const octave_value& rhs) +static octave_value +set_array_elements (JNIEnv* jni_env, jobject jobj, + const octave_value_list& idx, const octave_value& rhs) { octave_value retval; + jclass_ref rhsCls (jni_env); jobject_ref resObj (jni_env), rhsObj (jni_env); jobject_ref java_idx (jni_env, make_java_index (jni_env, idx)); - + if (! error_state && unbox (jni_env, rhs, rhsObj, rhsCls)) { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); @@ -761,69 +820,81 @@ return retval; } -static string_vector get_invoke_list (JNIEnv* jni_env, jobject jobj) +static string_vector +get_invoke_list (JNIEnv* jni_env, jobject jobj) { std::list<std::string> name_list; + if (jni_env) - { - jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj)); - jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls)); - jmethodID getMethods_ID = jni_env->GetMethodID (ccls, "getMethods", "()[Ljava/lang/reflect/Method;"), - getFields_ID = jni_env->GetMethodID (ccls, "getFields", "()[Ljava/lang/reflect/Field;"); - jobjectArray_ref mList (jni_env, reinterpret_cast<jobjectArray> (jni_env->CallObjectMethod (cls, getMethods_ID))), - fList (jni_env, reinterpret_cast<jobjectArray> (jni_env->CallObjectMethod (cls, getFields_ID))); - int mLen = jni_env->GetArrayLength (mList), fLen = jni_env->GetArrayLength (fList); - jclass_ref mCls (jni_env, jni_env->FindClass ("java/lang/reflect/Method")), - fCls (jni_env, jni_env->FindClass ("java/lang/reflect/Field")); - jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName", "()Ljava/lang/String;"), - f_getName_ID = jni_env->GetMethodID (fCls, "getName", "()Ljava/lang/String;"); - for (int i=0; i<mLen; i++) - { - jobject_ref meth (jni_env, jni_env->GetObjectArrayElement (mList, i)); - jstring_ref methName (jni_env, reinterpret_cast<jstring> (jni_env->CallObjectMethod (meth, m_getName_ID))); - name_list.push_back (jstring_to_string (jni_env, methName)); - } - for (int i=0; i<fLen; i++) - { - jobject_ref field (jni_env, jni_env->GetObjectArrayElement (fList, i)); - jstring_ref fieldName (jni_env, reinterpret_cast<jstring> (jni_env->CallObjectMethod (field, f_getName_ID))); - name_list.push_back (jstring_to_string (jni_env, fieldName)); - } - } + { + jclass_ref cls (jni_env, jni_env->GetObjectClass (jobj)); + jclass_ref ccls (jni_env, jni_env->GetObjectClass (cls)); + jmethodID getMethods_ID = jni_env->GetMethodID (ccls, "getMethods", "()[Ljava/lang/reflect/Method;"), + getFields_ID = jni_env->GetMethodID (ccls, "getFields", "()[Ljava/lang/reflect/Field;"); + jobjectArray_ref mList (jni_env, reinterpret_cast<jobjectArray> (jni_env->CallObjectMethod (cls, getMethods_ID))), + fList (jni_env, reinterpret_cast<jobjectArray> (jni_env->CallObjectMethod (cls, getFields_ID))); + int mLen = jni_env->GetArrayLength (mList), fLen = jni_env->GetArrayLength (fList); + jclass_ref mCls (jni_env, jni_env->FindClass ("java/lang/reflect/Method")), + fCls (jni_env, jni_env->FindClass ("java/lang/reflect/Field")); + jmethodID m_getName_ID = jni_env->GetMethodID (mCls, "getName", "()Ljava/lang/String;"), + f_getName_ID = jni_env->GetMethodID (fCls, "getName", "()Ljava/lang/String;"); + + for (int i = 0; i < mLen; i++) + { + jobject_ref meth (jni_env, jni_env->GetObjectArrayElement (mList, i)); + jstring_ref methName (jni_env, reinterpret_cast<jstring> (jni_env->CallObjectMethod (meth, m_getName_ID))); + name_list.push_back (jstring_to_string (jni_env, methName)); + } + + for (int i = 0; i < fLen; i++) + { + jobject_ref field (jni_env, jni_env->GetObjectArrayElement (fList, i)); + jstring_ref fieldName (jni_env, reinterpret_cast<jstring> (jni_env->CallObjectMethod (field, f_getName_ID))); + name_list.push_back (jstring_to_string (jni_env, fieldName)); + } + } string_vector v (name_list); + return v.sort (true); } -static octave_value convert_to_string (JNIEnv *jni_env, jobject java_object, bool force, char type) +static octave_value +convert_to_string (JNIEnv *jni_env, jobject java_object, bool force, char type) { octave_value retval; if (jni_env && java_object) { jclass_ref cls (jni_env, jni_env->FindClass ("java/lang/String")); + if (jni_env->IsInstanceOf (java_object, cls)) retval = octave_value (jstring_to_string (jni_env, java_object), type); else if (force) { cls = jni_env->FindClass ("[Ljava/lang/String;"); + if (jni_env->IsInstanceOf (java_object, cls)) { jobjectArray array = reinterpret_cast<jobjectArray> (java_object); int len = jni_env->GetArrayLength (array); Cell c (len, 1); - for (int i=0; i<len; i++) + + for (int i = 0; i < len; i++) { jstring_ref js (jni_env, reinterpret_cast<jstring> (jni_env->GetObjectArrayElement (array, i))); + if (js) c(i) = octave_value (jstring_to_string (jni_env, js), type); else { c(i) = check_exception (jni_env); + if (error_state) break; } } + retval = octave_value (c); } else @@ -831,6 +902,7 @@ cls = jni_env->FindClass ("java/lang/Object"); jmethodID mID = jni_env->GetMethodID (cls, "toString", "()Ljava/lang/String;"); jstring_ref js (jni_env, reinterpret_cast<jstring> (jni_env->CallObjectMethod (java_object, mID))); + if (js) retval = octave_value (jstring_to_string (jni_env, js), type); else @@ -844,9 +916,10 @@ return retval; } -#define TO_JAVA(obj) dynamic_cast<octave_java*>((obj).internal_rep()) +#define TO_JAVA(obj) dynamic_cast<octave_java*> ((obj).internal_rep ()) -octave_value box (JNIEnv* jni_env, jobject jobj, jclass jcls) +octave_value +box (JNIEnv* jni_env, jobject jobj, jclass jcls) { octave_value retval; jclass_ref cls (jni_env); @@ -857,6 +930,7 @@ if (retval.is_undefined ()) { cls = jni_env->FindClass ("java/lang/Integer"); + if (jni_env->IsInstanceOf (jobj, cls)) { jmethodID m = jni_env->GetMethodID (cls, "intValue", "()I"); @@ -867,6 +941,7 @@ if (retval.is_undefined ()) { cls = jni_env->FindClass ("java/lang/Double"); + if (jni_env->IsInstanceOf (jobj, cls)) { jmethodID m = jni_env->GetMethodID (cls, "doubleValue", "()D"); @@ -877,17 +952,19 @@ if (retval.is_undefined ()) { cls = jni_env->FindClass ("java/lang/Boolean"); + if (jni_env->IsInstanceOf (jobj, cls)) { jmethodID m = jni_env->GetMethodID (cls, "booleanValue", "()Z"); // MH retval = jni_env->CallBooleanMethod (jobj, m); - retval = (jni_env->CallBooleanMethod (jobj, m) ? true : false); - } + retval = (jni_env->CallBooleanMethod (jobj, m) ? true : false); + } } if (retval.is_undefined ()) { cls = jni_env->FindClass ("java/lang/String"); + if (jni_env->IsInstanceOf (jobj, cls)) { retval = jstring_to_string (jni_env, jobj); @@ -897,6 +974,7 @@ if (retval.is_undefined () && Vjava_convert_matrix) { cls = find_octave_class (jni_env, "org/octave/Matrix"); + if (jni_env->IsInstanceOf (jobj, cls)) { jmethodID mID = jni_env->GetMethodID (cls, "getDims", "()[I"); @@ -904,12 +982,16 @@ jint *iv_data = jni_env->GetIntArrayElements (jintArray (iv), 0); dim_vector dims; dims.resize (jni_env->GetArrayLength (jintArray (iv))); - for (int i=0; i<dims.length (); i++) + + for (int i = 0; i < dims.length (); i++) dims(i) = iv_data[i]; + jni_env->ReleaseIntArrayElements (jintArray (iv), iv_data, 0); mID = jni_env->GetMethodID (cls, "getClassName", "()Ljava/lang/String;"); jstring_ref js (jni_env, reinterpret_cast<jstring> (jni_env->CallObjectMethod (jobj, mID))); + std::string s = jstring_to_string (jni_env, js); + if (s == "double") { NDArray m (dims); @@ -962,6 +1044,7 @@ if (retval.is_undefined ()) { cls = find_octave_class (jni_env, "org/octave/OctaveReference"); + if (jni_env->IsInstanceOf (jobj, cls)) { jmethodID mID = jni_env->GetMethodID (cls, "getID", "()I"); @@ -979,7 +1062,8 @@ return retval; } -octave_value box_more (JNIEnv* jni_env, jobject jobj, jclass jcls) +octave_value +box_more (JNIEnv* jni_env, jobject jobj, jclass jcls) { octave_value retval = box (jni_env, jobj, jcls); @@ -992,61 +1076,70 @@ if (retval.is_undefined ()) { cls = jni_env->FindClass ("[D"); + if (jni_env->IsInstanceOf (jobj, cls)) { jdoubleArray jarr = reinterpret_cast<jdoubleArray> (jobj); int len = jni_env->GetArrayLength (jarr); + if (len > 0) { Matrix m (1, len); jni_env->GetDoubleArrayRegion (jarr, 0, len, m.fortran_vec ()); retval = m; } - else + else retval = Matrix (); } } - - if (retval.is_undefined ()) - { - cls = jni_env->FindClass ("[[D"); - if (jni_env->IsInstanceOf (jobj, cls)) - { - jobjectArray jarr = reinterpret_cast<jobjectArray> (jobj); - int rows = jni_env->GetArrayLength (jarr), cols = 0; - if (rows > 0) - { - Matrix m; - for (int r = 0; r < rows; r++) - { - jdoubleArray_ref row (jni_env, reinterpret_cast<jdoubleArray> (jni_env->GetObjectArrayElement (jarr, r))); - if (m.length () == 0) - { - cols = jni_env->GetArrayLength (row); - m.resize (cols, rows); - } - jni_env->GetDoubleArrayRegion (row, 0, cols, m.fortran_vec () + r * cols); - } - retval = m.transpose (); - } - else - retval = Matrix(); - } - } + + if (retval.is_undefined ()) + { + cls = jni_env->FindClass ("[[D"); + + if (jni_env->IsInstanceOf (jobj, cls)) + { + jobjectArray jarr = reinterpret_cast<jobjectArray> (jobj); + int rows = jni_env->GetArrayLength (jarr), cols = 0; + + if (rows > 0) + { + Matrix m; + + for (int r = 0; r < rows; r++) + { + jdoubleArray_ref row (jni_env, reinterpret_cast<jdoubleArray> (jni_env->GetObjectArrayElement (jarr, r))); + + if (m.length () == 0) + { + cols = jni_env->GetArrayLength (row); + m.resize (cols, rows); + } + jni_env->GetDoubleArrayRegion (row, 0, cols, m.fortran_vec () + r * cols); + } + retval = m.transpose (); + } + else + retval = Matrix (); + } + } if (retval.is_undefined ()) { cls = jni_env->FindClass ("[Ljava/lang/String;"); + if (jni_env->IsInstanceOf (jobj, cls)) { jobjectArray jarr = reinterpret_cast<jobjectArray> (jobj); int len = jni_env->GetArrayLength (jarr); - Cell m(len, 1); - for (int i=0; i<len; i++) + Cell m (len, 1); + + for (int i = 0; i < len; i++) { jstring_ref js (jni_env, reinterpret_cast<jstring> (jni_env->GetObjectArrayElement (jarr, i))); m(i) = jstring_to_string (jni_env, js); } + retval = m; } } @@ -1058,7 +1151,9 @@ return retval; } -int unbox (JNIEnv* jni_env, const octave_value& val, jobject_ref& jobj, jclass_ref& jcls) +int +unbox (JNIEnv* jni_env, const octave_value& val, jobject_ref& jobj, + jclass_ref& jcls) { int found = 1; @@ -1072,18 +1167,19 @@ else if (val.is_string ()) { std::string s = val.string_value (); + jobj = jni_env->NewStringUTF (s.c_str ()); jcls = jni_env->GetObjectClass (jobj); } - else if (val.is_bool_scalar ()) - { - bool bval = val.bool_value (); - jclass_ref bcls (jni_env, jni_env->FindClass ("java/lang/Boolean")); - jfieldID fid = jni_env->GetStaticFieldID (bcls, "TYPE", "Ljava/lang/Class;"); - jmethodID mid = jni_env->GetMethodID (bcls, "<init>", "(Z)V"); - jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (bcls, fid)); - jobj = jni_env->NewObject (bcls, mid, bval); - } + else if (val.is_bool_scalar ()) + { + bool bval = val.bool_value (); + jclass_ref bcls (jni_env, jni_env->FindClass ("java/lang/Boolean")); + jfieldID fid = jni_env->GetStaticFieldID (bcls, "TYPE", "Ljava/lang/Class;"); + jmethodID mid = jni_env->GetMethodID (bcls, "<init>", "(Z)V"); + jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (bcls, fid)); + jobj = jni_env->NewObject (bcls, mid, bval); + } else if (val.is_real_scalar ()) { double dval = val.double_value (); @@ -1099,24 +1195,31 @@ //jcls = jni_env->FindClass ("java/lang/Object"); jcls = 0; } - else if (!Vjava_convert_matrix && ((val.is_real_matrix () && (val.rows() == 1 || val.columns() == 1)) || val.is_range ())) + else if (!Vjava_convert_matrix + && ((val.is_real_matrix () + && (val.rows () == 1 || val.columns () == 1)) + || val.is_range ())) { Matrix m = val.matrix_value (); jdoubleArray dv = jni_env->NewDoubleArray (m.length ()); - //for (int i=0; i<m.length (); i++) + //for (int i = 0; i < m.length (); i++) jni_env->SetDoubleArrayRegion (dv, 0, m.length (), m.fortran_vec ()); jobj = dv; jcls = jni_env->GetObjectClass (jobj); } - else if (Vjava_convert_matrix && (val.is_matrix_type () || val.is_range()) && val.is_real_type ()) + else if (Vjava_convert_matrix + && (val.is_matrix_type () || val.is_range ()) && val.is_real_type ()) { jclass_ref mcls (jni_env, find_octave_class (jni_env, "org/octave/Matrix")); dim_vector dims = val.dims (); jintArray_ref iv (jni_env, jni_env->NewIntArray (dims.length ())); jint *iv_data = jni_env->GetIntArrayElements (jintArray (iv), 0); - for (int i=0; i<dims.length (); i++) + + for (int i = 0; i < dims.length (); i++) iv_data[i] = dims(i); + jni_env->ReleaseIntArrayElements (jintArray (iv), iv_data, 0); + if (val.is_double_type ()) { NDArray m = val.array_value (); @@ -1164,9 +1267,9 @@ Cell cellStr = val.cell_value (); jclass_ref scls (jni_env, jni_env->FindClass ("java/lang/String")); jobjectArray array = jni_env->NewObjectArray (cellStr.length (), scls, 0); - for (int i=0; i<cellStr.length (); i++) + for (int i = 0; i < cellStr.length (); i++) { - jstring_ref jstr (jni_env, jni_env->NewStringUTF (cellStr(i).string_value().c_str())); + jstring_ref jstr (jni_env, jni_env->NewStringUTF (cellStr(i).string_value().c_str ())); jni_env->SetObjectArrayElement (array, i, jstr); } jobj = array; @@ -1186,17 +1289,22 @@ return found; } -int unbox (JNIEnv* jni_env, const octave_value_list& args, jobjectArray_ref& jobjs, jobjectArray_ref& jclss) +int +unbox (JNIEnv* jni_env, const octave_value_list& args, + jobjectArray_ref& jobjs, jobjectArray_ref& jclss) { int found = 1; + jclass_ref ocls (jni_env, jni_env->FindClass ("java/lang/Object")); jclass_ref ccls (jni_env, jni_env->FindClass ("java/lang/Class")); if (! jobjs) jobjs = jni_env->NewObjectArray (args.length (), ocls, 0); + if (! jclss) jclss = jni_env->NewObjectArray (args.length (), ccls, 0); - for (int i=0; i<args.length (); i++) + + for (int i = 0; i < args.length (); i++) { jobject_ref jobj (jni_env); jclass_ref jcls (jni_env); @@ -1206,6 +1314,7 @@ found = 0; break; } + jni_env->SetObjectArrayElement (jobjs, i, jobj); jni_env->SetObjectArrayElement (jclss, i, jcls); } @@ -1214,26 +1323,30 @@ } -static long get_current_thread_ID(JNIEnv *jni_env) +static long +get_current_thread_ID (JNIEnv *jni_env) { if (jni_env) { jclass_ref cls (jni_env, jni_env->FindClass ("java/lang/Thread")); jmethodID mID = jni_env->GetStaticMethodID (cls, "currentThread", "()Ljava/lang/Thread;"); jobject_ref jthread (jni_env, jni_env->CallStaticObjectMethod (cls, mID)); + if (jthread) { jclass_ref jth_cls (jni_env, jni_env->GetObjectClass (jthread)); mID = jni_env->GetMethodID (jth_cls, "getId", "()J"); - long result = jni_env->CallLongMethod (jthread, mID); - //printf("current java thread ID = %ld\n", result); - return result; + long result = jni_env->CallLongMethod (jthread, mID); + //printf ("current java thread ID = %ld\n", result); + return result; } } + return -1; } -static int java_event_hook (void) +static int +java_event_hook (void) { JNIEnv *current_env = octave_java::thread_jni_env (); @@ -1243,23 +1356,25 @@ jmethodID mID = current_env->GetStaticMethodID (cls, "checkPendingAction", "()V"); current_env->CallStaticVoidMethod (cls, mID); } + return 0; } -static void initialize_java (void) +static void +initialize_java (void) { if (! jvm) { try { initialize_jvm (); - - JNIEnv *current_env = octave_java::thread_jni_env (); + + JNIEnv *current_env = octave_java::thread_jni_env (); octave_java::register_type (); command_editor::add_event_hook (java_event_hook); octave_thread_ID = get_current_thread_ID (current_env); - //printf("octave thread ID=%ld\n", octave_thread_ID); + //printf ("octave thread ID=%ld\n", octave_thread_ID); } catch (std::string msg) { @@ -1268,9 +1383,12 @@ } } -DEFUN_DLD (java_init, , , "") +DEFUN_DLD (java_init, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} java_init ()\n\ +Undocumented internal function.\n\ +@end deftypefn") { - octave_value retval; retval = 0; @@ -1281,7 +1399,11 @@ return retval; } -DEFUN_DLD (java_exit, , , "") +DEFUN_DLD (java_exit, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} java_exit ()\n\ +Undocumented internal function.\n\ +@end deftypefn") { octave_value retval; @@ -1291,7 +1413,7 @@ } DEFUN_DLD (java_new, args, , - "-*- texinfo -*-\n\ + "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{obj} =} java_new (@var{name}, @var{arg1}, ...)\n\ Create a Java object of class @var{name}, by calling the class constructor with the\n\ arguments @var{arg1}, ...\n\ @@ -1303,12 +1425,11 @@ @seealso{java_invoke, java_get, java_set}\n\ @end deftypefn") { - return _java_new ( args ); + return _java_new (args); } - DEFUN_DLD (javaObject, args, , - "-*- texinfo -*-\n\ + "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{obj} =} javaObject (@var{name}, @var{arg1}, ...)\n\ Create a Java object of class @var{name}, by calling the class constructor with the\n\ arguments @var{arg1}, ...\n\ @@ -1323,11 +1444,11 @@ @seealso{java_invoke, java_new, java_get, java_set}\n\ @end deftypefn") { - return _java_new ( args ); + return _java_new (args); } // internally called from java_new and javaObject for backward compatibility -static octave_value _java_new ( const octave_value_list& args ) +static octave_value _java_new (const octave_value_list& args) { octave_value retval; @@ -1340,12 +1461,12 @@ { std::string name = args(0).string_value (); if (! error_state) - { - octave_value_list tmp; - for (int i=1; i<args.length (); i++) - tmp(i-1) = args(i); - retval = octave_java::do_java_create (current_env, name, tmp); - } + { + octave_value_list tmp; + for (int i=1; i<args.length (); i++) + tmp(i-1) = args(i); + retval = octave_java::do_java_create (current_env, name, tmp); + } else error ("java_new: first argument must be a string"); } @@ -1357,7 +1478,7 @@ } DEFUN_DLD (java_invoke, args, , - "-*- texinfo -*-\n\ + "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{ret} =} java_invoke (@var{obj}, @var{name}, @var{arg1}, ...)\n\ Invoke the method @var{name} on the Java object @var{obj} with the arguments\n\ @var{arg1}, ... For static methods, @var{obj} can be a string representing the\n\ @@ -1375,11 +1496,11 @@ @seealso{java_get, java_set, java_new}\n\ @end deftypefn") { - return _java_invoke ( args ); + return _java_invoke (args); } DEFUN_DLD (javaMethod, args, , - "-*- texinfo -*-\n\ + "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{ret} =} javaMethod (@var{name}, @var{obj}, @var{arg1}, ...)\n\ Invoke the method @var{name} on the Java object @var{obj} with the arguments\n\ @var{arg1}, ... For static methods, @var{obj} can be a string representing the\n\ @@ -1399,35 +1520,42 @@ { octave_value retval; - if (args.length() > 1) + if (args.length () > 1) { - // swap first two arguments + // swap first two arguments octave_value_list tmp; tmp(0) = args(1); tmp(1) = args(0); + // copy remaining arguments for (int i=2; i<args.length (); i++) tmp(i) = args(i); - retval = _java_invoke ( tmp ); - } - else - { - print_usage (); - } + + retval = _java_invoke (tmp); + } + else + { + print_usage (); + } + return retval; } -// internally called from java_invoke and javaMethod for backward compatibility -static octave_value _java_invoke ( const octave_value_list& args ) +// internally called from java_invoke and javaMethod for backward +// compatibility. + +static octave_value +_java_invoke (const octave_value_list& args) { octave_value retval; initialize_java (); + if (! error_state) { JNIEnv *current_env = octave_java::thread_jni_env (); - if (args.length() > 1) + if (args.length () > 1) { std::string name = args(1).string_value (); if (! error_state) @@ -1480,6 +1608,7 @@ octave_value retval; initialize_java (); + if (! error_state) { JNIEnv *current_env = octave_java::thread_jni_env (); @@ -1533,6 +1662,7 @@ octave_value retval; initialize_java (); + if (! error_state) { JNIEnv *current_env = octave_java::thread_jni_env (); @@ -1565,11 +1695,16 @@ return retval; } -DEFUN_DLD (java2mat, args, , "") +DEFUN_DLD (java2mat, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} java2mat (@var{obj})\n\ +Undocumented internal function.\n\ +@end deftypefn") { octave_value_list retval; initialize_java (); + if (! error_state) { JNIEnv *current_env = octave_java::thread_jni_env (); @@ -1591,36 +1726,56 @@ return retval; } -DEFUN_DLD (__java__, , , "") +DEFUN_DLD (__java__, , , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {} __java__ ()\n\ +Undocumented internal function.\n\ +@end deftypefn") { return octave_value (); } -DEFUN_DLD (java_convert_matrix, args, nargout, "") +DEFUN_DLD (java_convert_matrix, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} java_convert_matrix ()\n\ +Query or set the internal variable that determines FIXME.\n\ +@end deftypefn") { return SET_INTERNAL_VARIABLE (java_convert_matrix); } -DEFUN_DLD (java_unsigned_conversion, args, nargout, "") +DEFUN_DLD (java_unsigned_conversion, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} java_unsigned_conversion ()\n\ +Query or set the internal variable that determines FIXME.\n\ +@end deftypefn") { return SET_INTERNAL_VARIABLE (java_unsigned_conversion); } -DEFUN_DLD (java_debug, args, nargout, "") +DEFUN_DLD (java_debug, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} java_debug ()\n\ +Query or set the internal variable that determines FIXME.\n\ +@end deftypefn") { return SET_INTERNAL_VARIABLE (java_debug); } -JNIEXPORT jboolean JNICALL Java_org_octave_Octave_call - (JNIEnv *env, jclass, jstring funcName, jobjectArray argin, jobjectArray argout) +JNIEXPORT jboolean JNICALL +Java_org_octave_Octave_call (JNIEnv *env, jclass, jstring funcName, + jobjectArray argin, jobjectArray argout) { std::string fname = jstring_to_string (env, funcName); + int nargout = env->GetArrayLength (argout); int nargin = env->GetArrayLength (argin); + octave_value_list varargin, varargout; - for (int i=0; i<nargin; i++) + for (int i = 0; i < nargin; i++) varargin(i) = box (env, env->GetObjectArrayElement (argin, i), 0); + varargout = feval (fname, varargin, nargout); if (! error_state) @@ -1628,6 +1783,7 @@ jobjectArray_ref out_objs (env, argout), out_clss (env); out_objs.detach (); + if (unbox (env, varargout, out_objs, out_clss)) return true; } @@ -1635,14 +1791,15 @@ return false; } -JNIEXPORT void JNICALL Java_org_octave_OctaveReference_doFinalize - (JNIEnv *, jclass, jint ID) +JNIEXPORT void JNICALL +Java_org_octave_OctaveReference_doFinalize (JNIEnv *, jclass, jint ID) { octave_ref_map.erase (ID); } -JNIEXPORT void JNICALL Java_org_octave_Octave_doInvoke - (JNIEnv *env, jclass, jint ID, jobjectArray args) +JNIEXPORT void JNICALL +Java_org_octave_Octave_doInvoke (JNIEnv *env, jclass, jint ID, + jobjectArray args) { std::map<int,octave_value>::iterator it = octave_ref_map.find (ID); @@ -1652,10 +1809,11 @@ int len = env->GetArrayLength (args); octave_value_list oct_args; - for (int i=0; i<len; i++) + for (int i = 0; i < len; i++) { jobject_ref jobj (env, env->GetObjectArrayElement (args, i)); oct_args(i) = box (env, jobj, 0); + if (error_state) break; } @@ -1669,9 +1827,9 @@ octave_function *fcn = val.function_value (); feval (fcn, oct_args); } - else if (val.is_cell () && val.length () > 0 && - (val.rows () == 1 || val.columns() == 1) && - val.cell_value()(0).is_function_handle ()) + else if (val.is_cell () && val.length () > 0 + && (val.rows () == 1 || val.columns () == 1) + && val.cell_value()(0).is_function_handle ()) { Cell c = val.cell_value (); octave_function *fcn = c(0).function_value (); @@ -1682,7 +1840,7 @@ if (! error_state) feval (fcn, oct_args); } - else + else error ("trying to invoke non-invocable object"); END_INTERRUPT_WITH_EXCEPTIONS; @@ -1690,17 +1848,16 @@ } } -JNIEXPORT void JNICALL Java_org_octave_Octave_doEvalString - (JNIEnv *env, jclass, jstring cmd) +JNIEXPORT void JNICALL +Java_org_octave_Octave_doEvalString (JNIEnv *env, jclass, jstring cmd) { std::string s = jstring_to_string (env, cmd); int pstatus; - eval_string (s, false, pstatus, 0); } -JNIEXPORT jboolean JNICALL Java_org_octave_Octave_needThreadedInvokation - (JNIEnv *env, jclass) +JNIEXPORT jboolean JNICALL +Java_org_octave_Octave_needThreadedInvokation (JNIEnv *env, jclass) { return (get_current_thread_ID (env) != octave_thread_ID); } @@ -1709,11 +1866,10 @@ DEFINE_OCTAVE_ALLOCATOR (octave_java); -DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_java, - "octave_java", - "octave_java"); +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_java, "octave_java", "octave_java"); -dim_vector octave_java::dims(void) const +dim_vector +octave_java::dims (void) const { JNIEnv *current_env = thread_jni_env (); @@ -1723,7 +1879,8 @@ return dim_vector (1, 1); } -JNIEnv* octave_java::thread_jni_env (void) +JNIEnv * +octave_java::thread_jni_env (void) { JNIEnv *env = NULL; @@ -1733,7 +1890,9 @@ return env; } -octave_value_list octave_java::subsref(const std::string& type, const std::list<octave_value_list>& idx, int nargout) +octave_value_list +octave_java::subsref (const std::string& type, + const std::list<octave_value_list>& idx, int nargout) { octave_value_list retval; int skip = 1; @@ -1742,34 +1901,36 @@ switch (type[0]) { - case '.': - if (type.length () > 1 && type[1] == '(') - { - octave_value_list ovl; - count++; - ovl(0) = octave_value (this); - ovl(1) = (idx.front ())(0); - std::list<octave_value_list>::const_iterator it = idx.begin (); - ovl.append (*++it); - retval = feval (std::string ("java_invoke"), ovl, 1); - skip++; - } - else - { - octave_value_list ovl; - count++; - ovl(0) = octave_value (this); - ovl(1) = (idx.front ())(0); - retval = feval (std::string ("java_get"), ovl, 1); - } - break; - case '(': - if (current_env) - retval = get_array_elements (current_env, to_java (), idx.front ()); - break; - default: - error ("subsref: Java object cannot be indexed with %c", type[0]); - break; + case '.': + if (type.length () > 1 && type[1] == '(') + { + octave_value_list ovl; + count++; + ovl(0) = octave_value (this); + ovl(1) = (idx.front ())(0); + std::list<octave_value_list>::const_iterator it = idx.begin (); + ovl.append (*++it); + retval = feval (std::string ("java_invoke"), ovl, 1); + skip++; + } + else + { + octave_value_list ovl; + count++; + ovl(0) = octave_value (this); + ovl(1) = (idx.front ())(0); + retval = feval (std::string ("java_get"), ovl, 1); + } + break; + + case '(': + if (current_env) + retval = get_array_elements (current_env, to_java (), idx.front ()); + break; + + default: + error ("subsref: Java object cannot be indexed with %c", type[0]); + break; } if (idx.size () > 1 && type.length () > 1) @@ -1778,7 +1939,10 @@ return retval; } -octave_value octave_java::subsasgn (const std::string& type, const std::list<octave_value_list>&idx, const octave_value &rhs) +octave_value +octave_java::subsasgn (const std::string& type, + const std::list<octave_value_list>&idx, + const octave_value &rhs) { octave_value retval; @@ -1821,7 +1985,7 @@ retval = octave_value (this); } } - } + } else if (type[1] == '.') { octave_value_list u = subsref (type.substr (0, 1), idx, 1); @@ -1840,6 +2004,7 @@ else error ("invalid indexing/assignment on Java object"); break; + case '(': if (current_env) { @@ -1851,6 +2016,7 @@ } } break; + default: error ("Java object cannot be indexed with %c", type[0]); break; @@ -1859,7 +2025,8 @@ return retval; } -string_vector octave_java::map_keys (void) const +string_vector +octave_java::map_keys (void) const { JNIEnv *current_env = thread_jni_env (); @@ -1869,7 +2036,8 @@ return string_vector (); } -octave_value octave_java::convert_to_str_internal (bool, bool force, char type) const +octave_value +octave_java::convert_to_str_internal (bool, bool force, char type) const { JNIEnv *current_env = thread_jni_env (); @@ -1879,8 +2047,9 @@ return octave_value (""); } -octave_value octave_java::do_java_invoke (JNIEnv* jni_env, const std::string& name, - const octave_value_list& args) +octave_value +octave_java::do_java_invoke (JNIEnv* jni_env, const std::string& name, + const octave_value_list& args) { octave_value retval; @@ -1891,21 +2060,25 @@ { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); jmethodID mID = jni_env->GetStaticMethodID (helperClass, "invokeMethod", - "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;"); + "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;"); jstring_ref methName (jni_env, jni_env->NewStringUTF (name.c_str ())); jobjectArray_ref resObj (jni_env, reinterpret_cast<jobjectArray> (jni_env->CallStaticObjectMethod (helperClass, mID, - to_java (), jstring (methName), jobjectArray (arg_objs), jobjectArray (arg_types)))); + to_java (), jstring (methName), jobjectArray (arg_objs), jobjectArray (arg_types)))); if (resObj) retval = box (jni_env, resObj); else retval = check_exception (jni_env); } } + return retval; } -octave_value octave_java:: do_java_invoke (JNIEnv* jni_env, const std::string& class_name, - const std::string& name, const octave_value_list& args) +octave_value +octave_java:: do_java_invoke (JNIEnv* jni_env, + const std::string& class_name, + const std::string& name, + const octave_value_list& args) { octave_value retval; @@ -1916,45 +2089,52 @@ { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); jmethodID mID = jni_env->GetStaticMethodID (helperClass, "invokeStaticMethod", - "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;"); + "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;"); jstring_ref methName (jni_env, jni_env->NewStringUTF (name.c_str ())); jstring_ref clsName (jni_env, jni_env->NewStringUTF (class_name.c_str ())); jobject_ref resObj (jni_env, jni_env->CallStaticObjectMethod (helperClass, mID, - jstring (clsName), jstring (methName), jobjectArray (arg_objs), jobjectArray (arg_types))); + jstring (clsName), jstring (methName), jobjectArray (arg_objs), jobjectArray (arg_types))); if (resObj) retval = box (jni_env, resObj); else retval = check_exception (jni_env); } } + return retval; } -octave_value octave_java::do_java_create (JNIEnv* jni_env, const std::string& name, const octave_value_list& args) +octave_value +octave_java::do_java_create (JNIEnv* jni_env, const std::string& name, + const octave_value_list& args) { octave_value retval; if (jni_env) { jobjectArray_ref arg_objs (jni_env), arg_types (jni_env); + if (unbox (jni_env, args, arg_objs, arg_types)) { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); jmethodID mID = jni_env->GetStaticMethodID (helperClass, "invokeConstructor", - "(Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;"); + "(Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;"); jstring_ref clsName (jni_env, jni_env->NewStringUTF (name.c_str ())); jobject_ref resObj (jni_env, jni_env->CallStaticObjectMethod (helperClass, mID, - jstring (clsName), jobjectArray (arg_objs), jobjectArray (arg_types))); + jstring (clsName), jobjectArray (arg_objs), jobjectArray (arg_types))); + if (resObj) retval = box (jni_env, resObj); else check_exception (jni_env); } } + return retval; } -octave_value octave_java::do_java_get (JNIEnv* jni_env, const std::string& name) +octave_value +octave_java::do_java_get (JNIEnv* jni_env, const std::string& name) { octave_value retval; @@ -1966,15 +2146,19 @@ jstring_ref fName (jni_env, jni_env->NewStringUTF (name.c_str ())); jobject_ref resObj (jni_env, jni_env->CallStaticObjectMethod (helperClass, mID, to_java (), jstring (fName))); + if (resObj) retval = box (jni_env, resObj); else retval = check_exception (jni_env); } + return retval; } -octave_value octave_java::do_java_get (JNIEnv* jni_env, const std::string& class_name, const std::string& name) +octave_value +octave_java::do_java_get (JNIEnv* jni_env, const std::string& class_name, + const std::string& name) { octave_value retval; @@ -1992,10 +2176,13 @@ else retval = check_exception (jni_env); } + return retval; } -octave_value octave_java::do_java_set (JNIEnv* jni_env, const std::string& name, const octave_value& val) +octave_value +octave_java::do_java_set (JNIEnv* jni_env, const std::string& name, + const octave_value& val) { octave_value retval; @@ -2008,16 +2195,19 @@ { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); jmethodID mID = jni_env->GetStaticMethodID (helperClass, "setField", - "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V"); + "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V"); jstring_ref fName (jni_env, jni_env->NewStringUTF (name.c_str ())); jni_env->CallStaticObjectMethod (helperClass, mID, to_java (), jstring (fName), jobject (jobj)); check_exception (jni_env); } } + return retval; } -octave_value octave_java::do_java_set (JNIEnv* jni_env, const std::string& class_name, const std::string& name, const octave_value& val) +octave_value +octave_java::do_java_set (JNIEnv* jni_env, const std::string& class_name, + const std::string& name, const octave_value& val) { octave_value retval; @@ -2030,13 +2220,14 @@ { jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper")); jmethodID mID = jni_env->GetStaticMethodID (helperClass, "setStaticField", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"); + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"); jstring_ref cName (jni_env, jni_env->NewStringUTF (class_name.c_str ())); jstring_ref fName (jni_env, jni_env->NewStringUTF (name.c_str ())); jni_env->CallStaticObjectMethod (helperClass, mID, jstring (cName), jstring (fName), jobject (jobj)); check_exception (jni_env); } } + return retval; }