From d0dbd2dd3f31746dc057a9e5b4a776f906affd59 Mon Sep 17 00:00:00 2001 From: alemi Date: Tue, 24 Sep 2024 21:13:15 +0200 Subject: [PATCH] feat: FromJava impl for primitive arrays --- src/from_java.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/from_java.rs b/src/from_java.rs index ff20c10..79cbda1 100644 --- a/src/from_java.rs +++ b/src/from_java.rs @@ -28,10 +28,10 @@ macro_rules! auto_from_java { }; } -auto_from_java!(i64, jni::sys::jlong); -auto_from_java!(i32, jni::sys::jint); -auto_from_java!(i16, jni::sys::jshort); auto_from_java!(i8, jni::sys::jbyte); +auto_from_java!(i16, jni::sys::jshort); +auto_from_java!(i32, jni::sys::jint); +auto_from_java!(i64, jni::sys::jlong); auto_from_java!(f32, jni::sys::jfloat); auto_from_java!(f64, jni::sys::jdouble); auto_from_java!(JObject<'j>, JObject<'j>); @@ -61,7 +61,7 @@ impl<'j> FromJava<'j> for bool { #[inline] fn from_java(_: &mut jni::JNIEnv, value: Self::From) -> Result { - Ok(value == 1) + Ok(value != 0) } } @@ -100,6 +100,55 @@ impl<'j, T: FromJava<'j, From = JObject<'j>>> FromJava<'j> for Vec { } } +macro_rules! auto_from_java_primitive_array { + ($primitive:ty, $fn:ident) => { + impl<'j> FromJava<'j> for Vec<$primitive> { + type From = JPrimitiveArray<'j, $primitive>; + + fn from_java(env: &mut jni::JNIEnv<'j>, value: Self::From) -> Result { + let len = env.get_array_length(&value)?.max(0) as usize; // should be always safe but TODO + let mut out = vec![<$primitive>::default(); len]; + env.$fn(value, 0, &mut out)?; + Ok(out) + } + } + }; +} + +auto_from_java_primitive_array!(i8, get_byte_array_region); +auto_from_java_primitive_array!(i16, get_short_array_region); +auto_from_java_primitive_array!(i32, get_int_array_region); +auto_from_java_primitive_array!(i64, get_long_array_region); +auto_from_java_primitive_array!(f32, get_float_array_region); +auto_from_java_primitive_array!(f64, get_double_array_region); + +impl<'j> FromJava<'j> for Vec { + type From = JPrimitiveArray<'j, u8>; + + fn from_java(env: &mut jni::JNIEnv<'j>, value: Self::From) -> Result { + let len = env.get_array_length(&value)?.max(0) as usize; // should be always safe but TODO + let mut out = vec![::default(); len]; + env.get_boolean_array_region(value, 0, &mut out)?; + Ok(out.into_iter().map(|x| x != 0).collect()) + } +} + +impl<'j> FromJava<'j> for Vec { + type From = JPrimitiveArray<'j, u16>; + + fn from_java(env: &mut jni::JNIEnv<'j>, value: Self::From) -> Result { + let len = env.get_array_length(&value)?.max(0) as usize; // should be always safe but TODO + let mut out = vec![::default(); len]; + env.get_char_array_region(value, 0, &mut out)?; + Ok( + out + .into_iter() + .map(|x| char::from_u32(x.into()).unwrap_or_default()) + .collect() + ) + } +} + #[cfg(feature = "uuid")] impl<'j> FromJava<'j> for uuid::Uuid { type From = JObject<'j>;