ext/rjbexception.c in rjb-1.4.3 vs ext/rjbexception.c in rjb-1.4.5

- old
+ new

@@ -1,167 +1,167 @@ -/* - * Rjb - Ruby <-> Java Bridge - * Copyright(c) 2004,2005,2006,2010 arton - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * $Id: rjbexception.c 174 2011-11-09 13:47:43Z arton $ - */ - -#include "ruby.h" -#include "extconf.h" -#if RJB_RUBY_VERSION_CODE < 190 -#include "st.h" -#else -#include "ruby/st.h" -#endif -#include "jniwrap.h" -#include "riconv.h" -#include "rjb.h" - -static VALUE missing_delegate(int argc, VALUE* argv, VALUE self) -{ - ID rmid = rb_to_id(argv[0]); - return rb_funcall(rb_ivar_get(self, rb_intern("@cause")), rmid, argc - 1, argv + 1); -} - -static VALUE exception_to_s(VALUE self) -{ - return rb_funcall(rb_ivar_get(self, rb_intern("@cause")), - rb_intern("toString"), 0); -} - -/* - * handle Java exception - * At this time, the Java exception is defined without the package name. - * This design may change in future release. - */ -VALUE rjb_get_exception_class(JNIEnv* jenv, jstring str) -{ - VALUE rexp; - char* pcls; - VALUE cname; - const char* p = (*jenv)->GetStringUTFChars(jenv, str, JNI_FALSE); - char* clsname = ALLOCA_N(char, strlen(p) + 1); - strcpy(clsname, p); - rjb_release_string(jenv, str, p); - pcls = strrchr(clsname, '.'); - if (pcls) - { - pcls++; - } - else - { - pcls = clsname; - } - cname = rb_str_new2(pcls); - rexp = rb_hash_aref(rjb_loaded_classes, cname); - if (rexp == Qnil) - { - rexp = rb_define_class(pcls, rb_eStandardError); - rb_define_method(rexp, "method_missing", missing_delegate, -1); - rb_define_method(rexp, "to_str", exception_to_s, 0); -#if defined(HAVE_RB_HASH_ASET) || defined(RUBINIUS) - rb_hash_aset(rjb_loaded_classes, cname, rexp); -#else -#ifdef RHASH_TBL - st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp); -#else - st_insert(RHASH(rjb_loaded_classes)->tbl, cname, rexp); -#endif -#endif - - } - return rexp; -} - -/* - * throw newly created exception with supplied message. - */ -VALUE rjb_s_throw(int argc, VALUE* argv, VALUE self) -{ - VALUE klass; - VALUE message; - JNIEnv* jenv = NULL; - - rjb_load_vm_default(); - - jenv = rjb_attach_current_thread(); - (*jenv)->ExceptionClear(jenv); - - if (rb_scan_args(argc, argv, "11", &klass, &message) == 2) - { - jclass excep = rjb_find_class(jenv, klass); - if (excep == NULL) - { - rb_raise(rb_eRuntimeError, "`%s' not found", StringValueCStr(klass)); - } - (*jenv)->ThrowNew(jenv, excep, StringValueCStr(message)); - } - else - { - struct jvi_data* ptr; - Data_Get_Struct(klass, struct jvi_data, ptr); - if (!(*jenv)->IsInstanceOf(jenv, ptr->obj, rjb_j_throwable)) - { - rb_raise(rb_eRuntimeError, "arg1 must be a throwable"); - } - else - { - (*jenv)->Throw(jenv, ptr->obj); - } - } - return Qnil; -} - -void rjb_check_exception(JNIEnv* jenv, int t) -{ - jthrowable exp = (*jenv)->ExceptionOccurred(jenv); - if (exp) - { - VALUE rexp = Qnil; - if (RTEST(ruby_verbose)) - { - (*jenv)->ExceptionDescribe(jenv); - } - (*jenv)->ExceptionClear(jenv); - if(1) - { - char* msg = "unknown exception"; - jclass cls = (*jenv)->GetObjectClass(jenv, exp); - jstring str = (*jenv)->CallObjectMethod(jenv, exp, rjb_throwable_getMessage); - if (str) - { - const char* p = (*jenv)->GetStringUTFChars(jenv, str, JNI_FALSE); - msg = ALLOCA_N(char, strlen(p) + 1); - strcpy(msg, p); - rjb_release_string(jenv, str, p); - } - str = (*jenv)->CallObjectMethod(jenv, cls, rjb_class_getName); - if (str) - { - rexp = rjb_get_exception_class(jenv, str); - } - if (rexp == Qnil) - { - (*jenv)->DeleteLocalRef(jenv, exp); - rb_raise(rb_eRuntimeError, "%s", msg); - } - else - { - VALUE rexpi = rb_funcall(rexp, rb_intern("new"), 1, rb_str_new2(msg)); - jvalue val; - val.l = exp; - rb_ivar_set(rexpi, rb_intern("@cause"), jv2rv(jenv, val)); - rb_exc_raise(rexpi); - } - } - } -} +/* + * Rjb - Ruby <-> Java Bridge + * Copyright(c) 2004,2005,2006,2010 arton + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * $Id: rjbexception.c 174 2011-11-09 13:47:43Z arton $ + */ + +#include "ruby.h" +#include "extconf.h" +#if RJB_RUBY_VERSION_CODE < 190 +#include "st.h" +#else +#include "ruby/st.h" +#endif +#include "jniwrap.h" +#include "riconv.h" +#include "rjb.h" + +static VALUE missing_delegate(int argc, VALUE* argv, VALUE self) +{ + ID rmid = rb_to_id(argv[0]); + return rb_funcall(rb_ivar_get(self, rb_intern("@cause")), rmid, argc - 1, argv + 1); +} + +static VALUE exception_to_s(VALUE self) +{ + return rb_funcall(rb_ivar_get(self, rb_intern("@cause")), + rb_intern("toString"), 0); +} + +/* + * handle Java exception + * At this time, the Java exception is defined without the package name. + * This design may change in future release. + */ +VALUE rjb_get_exception_class(JNIEnv* jenv, jstring str) +{ + VALUE rexp; + char* pcls; + VALUE cname; + const char* p = (*jenv)->GetStringUTFChars(jenv, str, JNI_FALSE); + char* clsname = ALLOCA_N(char, strlen(p) + 1); + strcpy(clsname, p); + rjb_release_string(jenv, str, p); + pcls = strrchr(clsname, '.'); + if (pcls) + { + pcls++; + } + else + { + pcls = clsname; + } + cname = rb_str_new2(pcls); + rexp = rb_hash_aref(rjb_loaded_classes, cname); + if (rexp == Qnil) + { + rexp = rb_define_class(pcls, rb_eStandardError); + rb_define_method(rexp, "method_missing", missing_delegate, -1); + rb_define_method(rexp, "to_str", exception_to_s, 0); +#if defined(HAVE_RB_HASH_ASET) || defined(RUBINIUS) + rb_hash_aset(rjb_loaded_classes, cname, rexp); +#else +#ifdef RHASH_TBL + st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp); +#else + st_insert(RHASH(rjb_loaded_classes)->tbl, cname, rexp); +#endif +#endif + + } + return rexp; +} + +/* + * throw newly created exception with supplied message. + */ +VALUE rjb_s_throw(int argc, VALUE* argv, VALUE self) +{ + VALUE klass; + VALUE message; + JNIEnv* jenv = NULL; + + rjb_load_vm_default(); + + jenv = rjb_attach_current_thread(); + (*jenv)->ExceptionClear(jenv); + + if (rb_scan_args(argc, argv, "11", &klass, &message) == 2) + { + jclass excep = rjb_find_class(jenv, klass); + if (excep == NULL) + { + rb_raise(rb_eRuntimeError, "`%s' not found", StringValueCStr(klass)); + } + (*jenv)->ThrowNew(jenv, excep, StringValueCStr(message)); + } + else + { + struct jvi_data* ptr; + Data_Get_Struct(klass, struct jvi_data, ptr); + if (!(*jenv)->IsInstanceOf(jenv, ptr->obj, rjb_j_throwable)) + { + rb_raise(rb_eRuntimeError, "arg1 must be a throwable"); + } + else + { + (*jenv)->Throw(jenv, ptr->obj); + } + } + return Qnil; +} + +void rjb_check_exception(JNIEnv* jenv, int t) +{ + jthrowable exp = (*jenv)->ExceptionOccurred(jenv); + if (exp) + { + VALUE rexp = Qnil; + if (RTEST(ruby_verbose)) + { + (*jenv)->ExceptionDescribe(jenv); + } + (*jenv)->ExceptionClear(jenv); + if(1) + { + char* msg = "unknown exception"; + jclass cls = (*jenv)->GetObjectClass(jenv, exp); + jstring str = (*jenv)->CallObjectMethod(jenv, exp, rjb_throwable_getMessage); + if (str) + { + const char* p = (*jenv)->GetStringUTFChars(jenv, str, JNI_FALSE); + msg = ALLOCA_N(char, strlen(p) + 1); + strcpy(msg, p); + rjb_release_string(jenv, str, p); + } + str = (*jenv)->CallObjectMethod(jenv, cls, rjb_class_getName); + if (str) + { + rexp = rjb_get_exception_class(jenv, str); + } + if (rexp == Qnil) + { + (*jenv)->DeleteLocalRef(jenv, exp); + rb_raise(rb_eRuntimeError, "%s", msg); + } + else + { + VALUE rexpi = rb_funcall(rexp, rb_intern("new"), 1, rb_str_new2(msg)); + jvalue val; + val.l = exp; + rb_ivar_set(rexpi, rb_intern("@cause"), jv2rv(jenv, val)); + rb_exc_raise(rexpi); + } + } + } +}