comparison libinterp/octave-value/ov-java.cc @ 20158: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
comparison
equal deleted inserted replaced
20157:81fcf4aa9e03 20158:8261c4a11250
1307 else IF_UNBOX_PRIMITIVE_ARRAY(int64, int64_, int64, jlong, Long) 1307 else IF_UNBOX_PRIMITIVE_ARRAY(int64, int64_, int64, jlong, Long)
1308 else IF_UNBOX_PRIMITIVE_ARRAY(uint64, uint64_, uint64, jlong, Long) 1308 else IF_UNBOX_PRIMITIVE_ARRAY(uint64, uint64_, uint64, jlong, Long)
1309 1309
1310 #undef IF_UNBOX_PRIMITIVE_ARRAY 1310 #undef IF_UNBOX_PRIMITIVE_ARRAY
1311 } 1311 }
1312 else if (val.is_real_scalar ()) 1312 else if (val.is_real_scalar () || val.is_bool_scalar ())
1313 { 1313 {
1314 if (val.is_double_type ()) 1314 #define IF_UNBOX_PRIMITIVE_SCALAR(CHECK_TYPE, OCTAVE_TYPE, METHOD_TYPE, JAVA_TYPE, JAVA_CON) \
1315 { 1315 if (val.is_ ## CHECK_TYPE ## _type ()) \
1316 double dval = val.double_value (); 1316 { \
1317 jclass_ref dcls (jni_env, jni_env->FindClass ("java/lang/Double")); 1317 const OCTAVE_TYPE ov = val.METHOD_TYPE ## _value (); \
1318 jfieldID fid = jni_env->GetStaticFieldID (dcls, "TYPE", "Ljava/lang/Class;"); 1318 jclass_ref dcls (jni_env, jni_env->FindClass (JAVA_TYPE)); \
1319 jmethodID mid = jni_env->GetMethodID (dcls, "<init>", "(D)V"); 1319 const jfieldID fid = jni_env->GetStaticFieldID (dcls, "TYPE", "Ljava/lang/Class;"); \
1320 jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (dcls, fid)); 1320 const jmethodID mid = jni_env->GetMethodID (dcls, "<init>", JAVA_CON); \
1321 jobj = jni_env->NewObject (dcls, mid, dval); 1321 jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (dcls, fid)); \
1322 } 1322 jobj = jni_env->NewObject (dcls, mid, ov); \
1323 else if (val.is_bool_type ()) 1323 }
1324 { 1324
1325 bool bval = val.bool_value (); 1325 IF_UNBOX_PRIMITIVE_SCALAR(double, double, double, "java/lang/Double", "(D)V")
1326 jclass_ref bcls (jni_env, jni_env->FindClass ("java/lang/Boolean")); 1326 else IF_UNBOX_PRIMITIVE_SCALAR(float, float, float, "java/lang/Float", "(F)V")
1327 jfieldID fid = jni_env->GetStaticFieldID (bcls, "TYPE", "Ljava/lang/Class;"); 1327 else IF_UNBOX_PRIMITIVE_SCALAR(bool, bool, bool, "java/lang/Boolean", "(Z)V")
1328 jmethodID mid = jni_env->GetMethodID (bcls, "<init>", "(Z)V"); 1328 else IF_UNBOX_PRIMITIVE_SCALAR(int8, int8_t, int8_scalar, "java/lang/Byte", "(B)V")
1329 jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (bcls, fid)); 1329 else IF_UNBOX_PRIMITIVE_SCALAR(uint8, uint8_t, uint8_scalar, "java/lang/Byte", "(B)V")
1330 jobj = jni_env->NewObject (bcls, mid, bval); 1330 else IF_UNBOX_PRIMITIVE_SCALAR(int16, int16_t, int16_scalar, "java/lang/Short", "(S)V")
1331 } 1331 else IF_UNBOX_PRIMITIVE_SCALAR(uint16, uint16_t, uint16_scalar, "java/lang/Short", "(S)V")
1332 else 1332 else IF_UNBOX_PRIMITIVE_SCALAR(int32, int32_t, int32_scalar, "java/lang/Int", "(I)V")
1333 { 1333 else IF_UNBOX_PRIMITIVE_SCALAR(uint32, uint32_t, uint32_scalar, "java/lang/Int", "(I)V")
1334 float fval = val.float_scalar_value (); 1334 else IF_UNBOX_PRIMITIVE_SCALAR(int64, int64_t, int64_scalar, "java/lang/Long", "(L)V")
1335 jclass_ref fcls (jni_env, jni_env->FindClass ("java/lang/Float")); 1335 else IF_UNBOX_PRIMITIVE_SCALAR(uint64, uint64_t, uint64_scalar, "java/lang/Long", "(L)V")
1336 jfieldID fid = jni_env->GetStaticFieldID (fcls, "TYPE", "Ljava/lang/Class;"); 1336
1337 jmethodID mid = jni_env->GetMethodID (fcls, "<init>", "(F)V"); 1337 #undef IF_UNBOX_PRIMITIVE_SCALAR
1338 jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (fcls, fid));
1339 jobj = jni_env->NewObject (fcls, mid, fval);
1340 }
1341 }
1342 else if (val.is_integer_type () && val.is_scalar_type ())
1343 {
1344 int32_t ival = val.int32_scalar_value ();
1345 jclass_ref icls (jni_env, jni_env->FindClass ("java/lang/Integer"));
1346 jfieldID fid = jni_env->GetStaticFieldID (icls, "TYPE", "Ljava/lang/Class;");
1347 jmethodID mid = jni_env->GetMethodID (icls, "<init>", "(I)V");
1348 jcls = reinterpret_cast<jclass> (jni_env->GetStaticObjectField (icls, fid));
1349 jobj = jni_env->NewObject (icls, mid, ival);
1350 } 1338 }
1351 else if (val.is_empty ()) 1339 else if (val.is_empty ())
1352 { 1340 {
1353 jobj = 0; 1341 jobj = 0;
1354 jcls = 0; 1342 jcls = 0;
2483 2471
2484 /* 2472 /*
2485 ## Check automatic conversion of java primitive arrays into octave types 2473 ## Check automatic conversion of java primitive arrays into octave types
2486 %!assert (javaObject ("java.lang.String", "hello").getBytes (), 2474 %!assert (javaObject ("java.lang.String", "hello").getBytes (),
2487 %! int8 ([104 101 108 108 111]')) 2475 %! int8 ([104 101 108 108 111]'))
2476
2477 ## Check automatic conversion of octave types into java primitive arrays
2478 ## Note that uint8 are casted into int8
2479 %!assert (javaMethod ("binarySearch", "java.util.Arrays", [90 100 255], 255), 2)
2480 %!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 255]), uint8 (255)) < 0)
2481 %!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 128]), uint8 (128)) < 0)
2482 %!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 127]), uint8 (127)), 2)
2483 %!assert (javaMethod ("binarySearch", "java.util.Arrays", uint16 ([90 100 128]), uint16 (128)), 2)
2488 */ 2484 */