typed_jni/array/
primitive.rs

1use core::ops::{Deref, DerefMut};
2
3use typed_jni_core::{ArrayElementsGuard, JNIEnv, StrongRef};
4
5use crate::{Array, LocalObject, Object, TypedArrayExt, TypedRef, array::primitive_impls, builtin::JavaThrowable};
6
7/// A guard for byte array elements.
8pub struct BytesArrayElementsGuard<'a, R: StrongRef>(ArrayElementsGuard<'a, i8, R>);
9
10impl<'a, R: StrongRef> BytesArrayElementsGuard<'a, R> {
11    /// Commits the changes made to the array elements.
12    pub fn commit(self) {
13        self.0.commit()
14    }
15}
16
17impl<'a, R: StrongRef> Deref for BytesArrayElementsGuard<'a, R> {
18    type Target = [u8];
19
20    fn deref(&self) -> &Self::Target {
21        unsafe { core::slice::from_raw_parts(self.0.as_ptr() as *const u8, self.0.len()) }
22    }
23}
24
25impl<'a, R: StrongRef> DerefMut for BytesArrayElementsGuard<'a, R> {
26    fn deref_mut(&mut self) -> &mut Self::Target {
27        unsafe { core::slice::from_raw_parts_mut(self.0.as_ptr() as *mut u8, self.0.len()) }
28    }
29}
30
31/// Extensions for primitive arrays.
32///
33/// This trait provides methods for working with primitive arrays.
34///
35/// Valid primitive types:
36/// - `i8`: byte (also allow access as `u8`)
37/// - `i16`: short
38/// - `i32`: int
39/// - `i64`: long
40/// - `f32`: float
41/// - `f64`: double
42pub trait TypedPrimitiveArrayExt: TypedArrayExt {
43    /// Creates a new primitive array of the specified type and length.
44    fn typed_new_primitive_array<T: primitive_impls::PrimitiveArrayElement>(
45        &self,
46        len: i32,
47    ) -> Result<LocalObject<'_, Array<T>>, LocalObject<'_, JavaThrowable>>;
48
49    /// Reads a region of the array into the provided slice.
50    fn typed_get_array_region<R: StrongRef, T: primitive_impls::PrimitiveArrayElement>(
51        &self,
52        array: &Object<R, Array<T>>,
53        offset: i32,
54        out: &mut [T],
55    ) -> Result<(), LocalObject<'_, JavaThrowable>>;
56
57    /// Writes a region of the array from the provided slice.
58    fn typed_set_array_region<R: StrongRef, T: primitive_impls::PrimitiveArrayElement>(
59        &self,
60        array: &Object<R, Array<T>>,
61        offset: i32,
62        values: &[T],
63    ) -> Result<(), LocalObject<'_, JavaThrowable>>;
64
65    /// Get array elements.
66    fn typed_get_array_elements<'env, 'a, R: StrongRef, T: primitive_impls::PrimitiveArrayElement>(
67        &'env self,
68        array: &'a Object<R, Array<T>>,
69    ) -> Result<ArrayElementsGuard<'a, T, R>, LocalObject<'env, JavaThrowable>>
70    where
71        'env: 'a;
72
73    /// Reads a region of the byte array into the provided slice.
74    fn typed_get_bytes_array_region<R: StrongRef>(
75        &self,
76        array: &Object<R, Array<i8>>,
77        offset: i32,
78        out: &mut [u8],
79    ) -> Result<(), LocalObject<'_, JavaThrowable>>;
80
81    /// Writes a region of the byte array from the provided slice.
82    fn typed_set_bytes_array_region<R: StrongRef>(
83        &self,
84        array: &Object<R, Array<i8>>,
85        offset: i32,
86        values: &[u8],
87    ) -> Result<(), LocalObject<'_, JavaThrowable>>;
88
89    /// Get byte array elements.
90    fn typed_get_bytes_array_elements<'env, 'a, R: StrongRef>(
91        &'env self,
92        array: &'a Object<R, Array<i8>>,
93    ) -> Result<BytesArrayElementsGuard<'a, R>, LocalObject<'env, JavaThrowable>>
94    where
95        'env: 'a;
96}
97
98impl<'vm> TypedPrimitiveArrayExt for JNIEnv<'vm> {
99    fn typed_new_primitive_array<T: primitive_impls::PrimitiveArrayElement>(
100        &self,
101        len: i32,
102    ) -> Result<LocalObject<'_, Array<T>>, LocalObject<'_, JavaThrowable>> {
103        unsafe {
104            T::new_instance(self, len)
105                .map(|arr| LocalObject::from_ref(arr))
106                .map_err(|err| LocalObject::from_ref(err))
107        }
108    }
109
110    fn typed_get_array_region<R: StrongRef, T: primitive_impls::PrimitiveArrayElement>(
111        &self,
112        array: &Object<R, Array<T>>,
113        offset: i32,
114        out: &mut [T],
115    ) -> Result<(), LocalObject<'_, JavaThrowable>> {
116        unsafe { T::get_region(self, &**array, offset, out).map_err(|err| LocalObject::from_ref(err)) }
117    }
118
119    fn typed_set_array_region<R: StrongRef, T: primitive_impls::PrimitiveArrayElement>(
120        &self,
121        array: &Object<R, Array<T>>,
122        offset: i32,
123        values: &[T],
124    ) -> Result<(), LocalObject<'_, JavaThrowable>> {
125        unsafe { T::set_region(self, &**array, offset, values).map_err(|err| LocalObject::from_ref(err)) }
126    }
127
128    fn typed_get_array_elements<'env, 'a, R: StrongRef, T: primitive_impls::PrimitiveArrayElement>(
129        &'env self,
130        array: &'a Object<R, Array<T>>,
131    ) -> Result<ArrayElementsGuard<'a, T, R>, LocalObject<'env, JavaThrowable>>
132    where
133        'env: 'a,
134    {
135        unsafe { T::get_elements(self, &**array).map_err(|err| LocalObject::from_ref(err)) }
136    }
137
138    fn typed_get_bytes_array_region<R: StrongRef>(
139        &self,
140        array: &Object<R, Array<i8>>,
141        offset: i32,
142        out: &mut [u8],
143    ) -> Result<(), LocalObject<'_, JavaThrowable>> {
144        unsafe {
145            let out = core::slice::from_raw_parts_mut(out.as_mut_ptr() as *mut i8, out.len());
146
147            self.typed_get_array_region(array, offset, out)
148        }
149    }
150
151    fn typed_set_bytes_array_region<R: StrongRef>(
152        &self,
153        array: &Object<R, Array<i8>>,
154        offset: i32,
155        values: &[u8],
156    ) -> Result<(), LocalObject<'_, JavaThrowable>> {
157        unsafe {
158            let values = core::slice::from_raw_parts(values.as_ptr() as *const i8, values.len());
159
160            self.typed_set_array_region(array, offset, values)
161        }
162    }
163
164    fn typed_get_bytes_array_elements<'env, 'a, R: StrongRef>(
165        &'env self,
166        array: &'a Object<R, Array<i8>>,
167    ) -> Result<BytesArrayElementsGuard<'a, R>, LocalObject<'env, JavaThrowable>>
168    where
169        'env: 'a,
170    {
171        self.typed_get_array_elements(array).map(BytesArrayElementsGuard)
172    }
173}