changeset 20123:8261c4a11250

Convert octave integer scalars into closest java type (bug #44882) * libinterp/octave-value/ov-java.cc (unbox): when calling a java method, octave core types should be converted automatically into equivalent java types. In the case of integers, we must pick the closest one but at the moment all were being converted to Integer (int32_t). This fixes it, even if it meas to lose data (as is the case in some of the added tests). Also reduce some code duplication by using macros since the code is similar to the code for float and doubles.
author Carnë Draug <carandraug@octave.org>
date Tue, 21 Apr 2015 00:32:52 +0100
parents 81fcf4aa9e03
children 6ee26f894346
files libinterp/octave-value/ov-java.cc
diffstat 1 files changed, 33 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-java.cc	Mon Apr 20 17:40:39 2015 +0100
+++ b/libinterp/octave-value/ov-java.cc	Tue Apr 21 00:32:52 2015 +0100
@@ -1309,44 +1309,32 @@
 
 #undef IF_UNBOX_PRIMITIVE_ARRAY
     }
-  else if (val.is_real_scalar ())
+  else if (val.is_real_scalar () || val.is_bool_scalar ())
     {
-      if (val.is_double_type ())
-        {
-          double dval = val.double_value ();
-          jclass_ref dcls (jni_env, jni_env->FindClass ("java/lang/Double"));
-          jfieldID fid = jni_env->GetStaticFieldID (dcls, "TYPE", "Ljava/lang/Class;");
-          jmethodID mid = jni_env->GetMethodID (dcls, "<init>", "(D)V");
-          jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (dcls, fid));
-          jobj = jni_env->NewObject (dcls, mid, dval);
-        }
-      else if (val.is_bool_type ())
-        {
-          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
-        {
-          float fval = val.float_scalar_value ();
-          jclass_ref fcls (jni_env, jni_env->FindClass ("java/lang/Float"));
-          jfieldID fid = jni_env->GetStaticFieldID (fcls, "TYPE", "Ljava/lang/Class;");
-          jmethodID mid = jni_env->GetMethodID (fcls, "<init>", "(F)V");
-          jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (fcls, fid));
-          jobj = jni_env->NewObject (fcls, mid, fval);
-        }
-    }
-  else if (val.is_integer_type () && val.is_scalar_type ())
-    {
-      int32_t ival = val.int32_scalar_value ();
-      jclass_ref icls (jni_env, jni_env->FindClass ("java/lang/Integer"));
-      jfieldID fid = jni_env->GetStaticFieldID (icls, "TYPE", "Ljava/lang/Class;");
-      jmethodID mid = jni_env->GetMethodID (icls, "<init>", "(I)V");
-      jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (icls, fid));
-      jobj = jni_env->NewObject (icls, mid, ival);
+#define IF_UNBOX_PRIMITIVE_SCALAR(CHECK_TYPE, OCTAVE_TYPE, METHOD_TYPE, JAVA_TYPE, JAVA_CON) \
+      if (val.is_ ## CHECK_TYPE ## _type ()) \
+        { \
+          const OCTAVE_TYPE ov = val.METHOD_TYPE ## _value (); \
+          jclass_ref dcls (jni_env, jni_env->FindClass (JAVA_TYPE)); \
+          const jfieldID fid = jni_env->GetStaticFieldID (dcls, "TYPE", "Ljava/lang/Class;"); \
+          const jmethodID mid = jni_env->GetMethodID (dcls, "<init>", JAVA_CON); \
+          jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (dcls, fid)); \
+          jobj = jni_env->NewObject (dcls, mid, ov); \
+         }
+
+           IF_UNBOX_PRIMITIVE_SCALAR(double, double,   double,        "java/lang/Double",  "(D)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(float,  float,    float,         "java/lang/Float",   "(F)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(bool,   bool,     bool,          "java/lang/Boolean", "(Z)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(int8,   int8_t,   int8_scalar,   "java/lang/Byte",    "(B)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(uint8,  uint8_t,  uint8_scalar,  "java/lang/Byte",    "(B)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(int16,  int16_t,  int16_scalar,  "java/lang/Short",   "(S)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(uint16, uint16_t, uint16_scalar, "java/lang/Short",   "(S)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(int32,  int32_t,  int32_scalar,  "java/lang/Int",     "(I)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(uint32, uint32_t, uint32_scalar, "java/lang/Int",     "(I)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(int64,  int64_t,  int64_scalar,  "java/lang/Long",    "(L)V")
+      else IF_UNBOX_PRIMITIVE_SCALAR(uint64, uint64_t, uint64_scalar, "java/lang/Long",    "(L)V")
+
+#undef IF_UNBOX_PRIMITIVE_SCALAR
     }
   else if (val.is_empty ())
     {
@@ -2485,4 +2473,12 @@
 ## Check automatic conversion of java primitive arrays into octave types
 %!assert (javaObject ("java.lang.String", "hello").getBytes (),
 %!        int8 ([104 101 108 108 111]'))
+
+## Check automatic conversion of octave types into java primitive arrays
+## Note that uint8 are casted into int8
+%!assert (javaMethod ("binarySearch", "java.util.Arrays", [90 100 255], 255), 2)
+%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8  ([90 100 255]), uint8  (255)) < 0)
+%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8  ([90 100 128]), uint8  (128)) < 0)
+%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8  ([90 100 127]), uint8  (127)), 2)
+%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint16 ([90 100 128]), uint16 (128)), 2)
 */