1 use std::marker::PhantomData; 2 3 use crate::{ 4 objects::JObject, 5 sys::{jarray, jobject}, 6 }; 7 8 use super::TypeArray; 9 10 #[cfg(doc)] 11 use crate::JNIEnv; 12 13 /// Lifetime'd representation of a [`jarray`] which wraps a [`JObject`] reference 14 /// 15 /// This is a wrapper type for a [`JObject`] local reference that's used to 16 /// differentiate JVM array types. 17 #[repr(transparent)] 18 #[derive(Debug)] 19 pub struct JPrimitiveArray<'local, T: TypeArray> { 20 obj: JObject<'local>, 21 lifetime: PhantomData<&'local T>, 22 } 23 24 impl<'local, T: TypeArray> AsRef<JPrimitiveArray<'local, T>> for JPrimitiveArray<'local, T> { as_ref(&self) -> &JPrimitiveArray<'local, T>25 fn as_ref(&self) -> &JPrimitiveArray<'local, T> { 26 self 27 } 28 } 29 30 impl<'local, T: TypeArray> AsMut<JPrimitiveArray<'local, T>> for JPrimitiveArray<'local, T> { as_mut(&mut self) -> &mut JPrimitiveArray<'local, T>31 fn as_mut(&mut self) -> &mut JPrimitiveArray<'local, T> { 32 self 33 } 34 } 35 36 impl<'local, T: TypeArray> AsRef<JObject<'local>> for JPrimitiveArray<'local, T> { as_ref(&self) -> &JObject<'local>37 fn as_ref(&self) -> &JObject<'local> { 38 &self.obj 39 } 40 } 41 42 impl<'local, T: TypeArray> ::std::ops::Deref for JPrimitiveArray<'local, T> { 43 type Target = JObject<'local>; 44 deref(&self) -> &Self::Target45 fn deref(&self) -> &Self::Target { 46 &self.obj 47 } 48 } 49 50 impl<'local, T: TypeArray> From<JPrimitiveArray<'local, T>> for JObject<'local> { from(other: JPrimitiveArray<'local, T>) -> JObject51 fn from(other: JPrimitiveArray<'local, T>) -> JObject { 52 other.obj 53 } 54 } 55 56 /// This conversion assumes that the `JObject` is a pointer to a class object. 57 impl<'local, T: TypeArray> From<JObject<'local>> for JPrimitiveArray<'local, T> { from(other: JObject) -> Self58 fn from(other: JObject) -> Self { 59 unsafe { Self::from_raw(other.into_raw()) } 60 } 61 } 62 63 /// This conversion assumes that the `JObject` is a pointer to a class object. 64 impl<'local, 'obj_ref, T: TypeArray> From<&'obj_ref JObject<'local>> 65 for &'obj_ref JPrimitiveArray<'local, T> 66 { from(other: &'obj_ref JObject<'local>) -> Self67 fn from(other: &'obj_ref JObject<'local>) -> Self { 68 // Safety: `JPrimitiveArray` is `repr(transparent)` around `JObject`. 69 unsafe { &*(other as *const JObject<'local> as *const JPrimitiveArray<'local, T>) } 70 } 71 } 72 73 impl<'local, T: TypeArray> std::default::Default for JPrimitiveArray<'local, T> { default() -> Self74 fn default() -> Self { 75 Self { 76 obj: JObject::null(), 77 lifetime: PhantomData, 78 } 79 } 80 } 81 82 impl<'local, T: TypeArray> JPrimitiveArray<'local, T> { 83 /// Creates a [`JPrimitiveArray`] that wraps the given `raw` [`jarray`] 84 /// 85 /// # Safety 86 /// 87 /// `raw` may be a null pointer. If `raw` is not a null pointer, then: 88 /// 89 /// * `raw` must be a valid raw JNI local reference. 90 /// * There must not be any other `JObject` representing the same local reference. 91 /// * The lifetime `'local` must not outlive the local reference frame that the local reference 92 /// was created in. from_raw(raw: jarray) -> Self93 pub unsafe fn from_raw(raw: jarray) -> Self { 94 Self { 95 obj: JObject::from_raw(raw as jobject), 96 lifetime: PhantomData, 97 } 98 } 99 100 /// Unwrap to the raw jni type. into_raw(self) -> jarray101 pub fn into_raw(self) -> jarray { 102 self.obj.into_raw() as jarray 103 } 104 } 105 106 /// Lifetime'd representation of a [`crate::sys::jbooleanArray`] which wraps a [`JObject`] reference 107 pub type JBooleanArray<'local> = JPrimitiveArray<'local, crate::sys::jboolean>; 108 109 /// Lifetime'd representation of a [`crate::sys::jbyteArray`] which wraps a [`JObject`] reference 110 pub type JByteArray<'local> = JPrimitiveArray<'local, crate::sys::jbyte>; 111 112 /// Lifetime'd representation of a [`crate::sys::jcharArray`] which wraps a [`JObject`] reference 113 pub type JCharArray<'local> = JPrimitiveArray<'local, crate::sys::jchar>; 114 115 /// Lifetime'd representation of a [`crate::sys::jshortArray`] which wraps a [`JObject`] reference 116 pub type JShortArray<'local> = JPrimitiveArray<'local, crate::sys::jshort>; 117 118 /// Lifetime'd representation of a [`crate::sys::jintArray`] which wraps a [`JObject`] reference 119 pub type JIntArray<'local> = JPrimitiveArray<'local, crate::sys::jint>; 120 121 /// Lifetime'd representation of a [`crate::sys::jlongArray`] which wraps a [`JObject`] reference 122 pub type JLongArray<'local> = JPrimitiveArray<'local, crate::sys::jlong>; 123 124 /// Lifetime'd representation of a [`crate::sys::jfloatArray`] which wraps a [`JObject`] reference 125 pub type JFloatArray<'local> = JPrimitiveArray<'local, crate::sys::jfloat>; 126 127 /// Lifetime'd representation of a [`crate::sys::jdoubleArray`] which wraps a [`JObject`] reference 128 pub type JDoubleArray<'local> = JPrimitiveArray<'local, crate::sys::jdouble>; 129 130 /// Trait to access the raw `jarray` pointer for types that wrap an array reference 131 /// 132 /// # Safety 133 /// 134 /// Implementing this trait will allow a type to be passed to [`JNIEnv::get_array_length()`] 135 /// or other JNI APIs that only work with a valid reference to an array (or `null`) 136 /// 137 pub unsafe trait AsJArrayRaw<'local>: AsRef<JObject<'local>> { 138 /// Returns the raw JNI pointer as a `jarray` as_jarray_raw(&self) -> jarray139 fn as_jarray_raw(&self) -> jarray { 140 self.as_ref().as_raw() as jarray 141 } 142 } 143 144 unsafe impl<'local, T: TypeArray> AsJArrayRaw<'local> for JPrimitiveArray<'local, T> {} 145