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
7pub struct BytesArrayElementsGuard<'a, R: StrongRef>(ArrayElementsGuard<'a, i8, R>);
9
10impl<'a, R: StrongRef> BytesArrayElementsGuard<'a, R> {
11 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
31pub trait TypedPrimitiveArrayExt: TypedArrayExt {
43 fn typed_new_primitive_array<T: primitive_impls::PrimitiveArrayElement>(
45 &self,
46 len: i32,
47 ) -> Result<LocalObject<'_, Array<T>>, LocalObject<'_, JavaThrowable>>;
48
49 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 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 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 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 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 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}