Skip to content

Commit d62d565

Browse files
committed
Add methods to insert string, vectors and bundles.
Bug: 389074518 Test: atest libbinder_rs-internal_test Change-Id: Ie147ab0027b96dee7f1d96e90fd80163e6e68ca3
1 parent 713a276 commit d62d565

1 file changed

Lines changed: 230 additions & 16 deletions

File tree

libs/binder/rust/src/persistable_bundle.rs

Lines changed: 230 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ use binder_ndk_sys::{
2424
APersistableBundle, APersistableBundle_delete, APersistableBundle_dup,
2525
APersistableBundle_erase, APersistableBundle_getBoolean, APersistableBundle_getDouble,
2626
APersistableBundle_getInt, APersistableBundle_getLong, APersistableBundle_isEqual,
27-
APersistableBundle_new, APersistableBundle_putBoolean, APersistableBundle_putDouble,
28-
APersistableBundle_putInt, APersistableBundle_putLong, APersistableBundle_readFromParcel,
29-
APersistableBundle_size, APersistableBundle_writeToParcel,
27+
APersistableBundle_new, APersistableBundle_putBoolean, APersistableBundle_putBooleanVector,
28+
APersistableBundle_putDouble, APersistableBundle_putDoubleVector, APersistableBundle_putInt,
29+
APersistableBundle_putIntVector, APersistableBundle_putLong, APersistableBundle_putLongVector,
30+
APersistableBundle_putPersistableBundle, APersistableBundle_putString,
31+
APersistableBundle_putStringVector, APersistableBundle_readFromParcel, APersistableBundle_size,
32+
APersistableBundle_writeToParcel,
3033
};
3134
use std::ffi::{CString, NulError};
3235
use std::ptr::{null_mut, NonNull};
@@ -60,7 +63,7 @@ impl PersistableBundle {
6063
let key = CString::new(key)?;
6164
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
6265
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
63-
// to be valid for the lifetime of `key`.
66+
// to be valid for the duration of this call.
6467
Ok(unsafe { APersistableBundle_erase(self.0.as_ptr(), key.as_ptr()) != 0 })
6568
}
6669

@@ -73,7 +76,7 @@ impl PersistableBundle {
7376
let key = CString::new(key)?;
7477
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
7578
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
76-
// to be valid for the lifetime of `key`.
79+
// to be valid for the duration of this call.
7780
unsafe {
7881
APersistableBundle_putBoolean(self.0.as_ptr(), key.as_ptr(), value);
7982
}
@@ -89,7 +92,7 @@ impl PersistableBundle {
8992
let key = CString::new(key)?;
9093
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
9194
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
92-
// to be valid for the lifetime of `key`.
95+
// to be valid for the duration of this call.
9396
unsafe {
9497
APersistableBundle_putInt(self.0.as_ptr(), key.as_ptr(), value);
9598
}
@@ -105,7 +108,7 @@ impl PersistableBundle {
105108
let key = CString::new(key)?;
106109
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
107110
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
108-
// to be valid for the lifetime of `key`.
111+
// to be valid for the duration of this call.
109112
unsafe {
110113
APersistableBundle_putLong(self.0.as_ptr(), key.as_ptr(), value);
111114
}
@@ -121,13 +124,182 @@ impl PersistableBundle {
121124
let key = CString::new(key)?;
122125
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
123126
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
124-
// to be valid for the lifetime of `key`.
127+
// to be valid for the duration of this call.
125128
unsafe {
126129
APersistableBundle_putDouble(self.0.as_ptr(), key.as_ptr(), value);
127130
}
128131
Ok(())
129132
}
130133

134+
/// Inserts a key-value pair into the bundle.
135+
///
136+
/// If the key is already present then its value will be overwritten by the given value.
137+
///
138+
/// Returns an error if the key or value contains a NUL character.
139+
pub fn insert_string(&mut self, key: &str, value: &str) -> Result<(), NulError> {
140+
let key = CString::new(key)?;
141+
let value = CString::new(value)?;
142+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
143+
// lifetime of the `PersistableBundle`. The pointer returned by `CStr::as_ptr` is guaranteed
144+
// to be valid for the duration of this call.
145+
unsafe {
146+
APersistableBundle_putString(self.0.as_ptr(), key.as_ptr(), value.as_ptr());
147+
}
148+
Ok(())
149+
}
150+
151+
/// Inserts a key-value pair into the bundle.
152+
///
153+
/// If the key is already present then its value will be overwritten by the given value.
154+
///
155+
/// Returns an error if the key contains a NUL character.
156+
pub fn insert_bool_vec(&mut self, key: &str, value: &[bool]) -> Result<(), NulError> {
157+
let key = CString::new(key)?;
158+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
159+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
160+
// to be valid for the duration of this call, and likewise the pointer returned by
161+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
162+
// duration of the call.
163+
unsafe {
164+
APersistableBundle_putBooleanVector(
165+
self.0.as_ptr(),
166+
key.as_ptr(),
167+
value.as_ptr(),
168+
value.len().try_into().unwrap(),
169+
);
170+
}
171+
Ok(())
172+
}
173+
174+
/// Inserts a key-value pair into the bundle.
175+
///
176+
/// If the key is already present then its value will be overwritten by the given value.
177+
///
178+
/// Returns an error if the key contains a NUL character.
179+
pub fn insert_int_vec(&mut self, key: &str, value: &[i32]) -> Result<(), NulError> {
180+
let key = CString::new(key)?;
181+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
182+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
183+
// to be valid for the duration of this call, and likewise the pointer returned by
184+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
185+
// duration of the call.
186+
unsafe {
187+
APersistableBundle_putIntVector(
188+
self.0.as_ptr(),
189+
key.as_ptr(),
190+
value.as_ptr(),
191+
value.len().try_into().unwrap(),
192+
);
193+
}
194+
Ok(())
195+
}
196+
197+
/// Inserts a key-value pair into the bundle.
198+
///
199+
/// If the key is already present then its value will be overwritten by the given value.
200+
///
201+
/// Returns an error if the key contains a NUL character.
202+
pub fn insert_long_vec(&mut self, key: &str, value: &[i64]) -> Result<(), NulError> {
203+
let key = CString::new(key)?;
204+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
205+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
206+
// to be valid for the duration of this call, and likewise the pointer returned by
207+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
208+
// duration of the call.
209+
unsafe {
210+
APersistableBundle_putLongVector(
211+
self.0.as_ptr(),
212+
key.as_ptr(),
213+
value.as_ptr(),
214+
value.len().try_into().unwrap(),
215+
);
216+
}
217+
Ok(())
218+
}
219+
220+
/// Inserts a key-value pair into the bundle.
221+
///
222+
/// If the key is already present then its value will be overwritten by the given value.
223+
///
224+
/// Returns an error if the key contains a NUL character.
225+
pub fn insert_double_vec(&mut self, key: &str, value: &[f64]) -> Result<(), NulError> {
226+
let key = CString::new(key)?;
227+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
228+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
229+
// to be valid for the duration of this call, and likewise the pointer returned by
230+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
231+
// duration of the call.
232+
unsafe {
233+
APersistableBundle_putDoubleVector(
234+
self.0.as_ptr(),
235+
key.as_ptr(),
236+
value.as_ptr(),
237+
value.len().try_into().unwrap(),
238+
);
239+
}
240+
Ok(())
241+
}
242+
243+
/// Inserts a key-value pair into the bundle.
244+
///
245+
/// If the key is already present then its value will be overwritten by the given value.
246+
///
247+
/// Returns an error if the key contains a NUL character.
248+
pub fn insert_string_vec<'a, T: ToString + 'a>(
249+
&mut self,
250+
key: &str,
251+
value: impl IntoIterator<Item = &'a T>,
252+
) -> Result<(), NulError> {
253+
let key = CString::new(key)?;
254+
// We need to collect the new `CString`s into something first so that they live long enough
255+
// for their pointers to be valid for the `APersistableBundle_putStringVector` call below.
256+
let c_strings = value
257+
.into_iter()
258+
.map(|s| CString::new(s.to_string()))
259+
.collect::<Result<Vec<_>, NulError>>()?;
260+
let char_pointers = c_strings.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
261+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
262+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
263+
// to be valid for the duration of this call, and likewise the pointer returned by
264+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
265+
// duration of the call.
266+
unsafe {
267+
APersistableBundle_putStringVector(
268+
self.0.as_ptr(),
269+
key.as_ptr(),
270+
char_pointers.as_ptr(),
271+
char_pointers.len().try_into().unwrap(),
272+
);
273+
}
274+
Ok(())
275+
}
276+
277+
/// Inserts a key-value pair into the bundle.
278+
///
279+
/// If the key is already present then its value will be overwritten by the given value.
280+
///
281+
/// Returns an error if the key contains a NUL character.
282+
pub fn insert_persistable_bundle(
283+
&mut self,
284+
key: &str,
285+
value: &PersistableBundle,
286+
) -> Result<(), NulError> {
287+
let key = CString::new(key)?;
288+
// SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the
289+
// lifetime of the `PersistableBundle`s. The pointer returned by `CStr::as_ptr` is
290+
// guaranteed to be valid for the duration of this call, and
291+
// `APersistableBundle_putPersistableBundle` does a deep copy so that is all that is
292+
// required.
293+
unsafe {
294+
APersistableBundle_putPersistableBundle(
295+
self.0.as_ptr(),
296+
key.as_ptr(),
297+
value.0.as_ptr(),
298+
);
299+
}
300+
Ok(())
301+
}
302+
131303
/// Gets the boolean value associated with the given key.
132304
///
133305
/// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
@@ -137,8 +309,8 @@ impl PersistableBundle {
137309
let mut value = false;
138310
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
139311
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
140-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
141-
// from a reference.
312+
// to be valid for the duration of this call. The value pointer must be valid because it
313+
// comes from a reference.
142314
if unsafe { APersistableBundle_getBoolean(self.0.as_ptr(), key.as_ptr(), &mut value) } {
143315
Ok(Some(value))
144316
} else {
@@ -155,8 +327,8 @@ impl PersistableBundle {
155327
let mut value = 0;
156328
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
157329
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
158-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
159-
// from a reference.
330+
// to be valid for the duration of this call. The value pointer must be valid because it
331+
// comes from a reference.
160332
if unsafe { APersistableBundle_getInt(self.0.as_ptr(), key.as_ptr(), &mut value) } {
161333
Ok(Some(value))
162334
} else {
@@ -173,8 +345,8 @@ impl PersistableBundle {
173345
let mut value = 0;
174346
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
175347
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
176-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
177-
// from a reference.
348+
// to be valid for the duration of this call. The value pointer must be valid because it
349+
// comes from a reference.
178350
if unsafe { APersistableBundle_getLong(self.0.as_ptr(), key.as_ptr(), &mut value) } {
179351
Ok(Some(value))
180352
} else {
@@ -191,8 +363,8 @@ impl PersistableBundle {
191363
let mut value = 0.0;
192364
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
193365
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
194-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
195-
// from a reference.
366+
// to be valid for the duration of this call. The value pointer must be valid because it
367+
// comes from a reference.
196368
if unsafe { APersistableBundle_getDouble(self.0.as_ptr(), key.as_ptr(), &mut value) } {
197369
Ok(Some(value))
198370
} else {
@@ -339,4 +511,46 @@ mod test {
339511
assert_eq!(bundle.get_double("double"), Ok(None));
340512
assert_eq!(bundle.size(), 0);
341513
}
514+
515+
#[test]
516+
fn insert_string() {
517+
let mut bundle = PersistableBundle::new();
518+
assert_eq!(bundle.insert_string("string", "foo"), Ok(()));
519+
assert_eq!(bundle.size(), 1);
520+
}
521+
522+
#[test]
523+
fn insert_vec() {
524+
let mut bundle = PersistableBundle::new();
525+
526+
assert_eq!(bundle.insert_bool_vec("bool", &[]), Ok(()));
527+
assert_eq!(bundle.insert_int_vec("int", &[42]), Ok(()));
528+
assert_eq!(bundle.insert_long_vec("long", &[66, 67, 68]), Ok(()));
529+
assert_eq!(bundle.insert_double_vec("double", &[123.4]), Ok(()));
530+
assert_eq!(bundle.insert_string_vec("string", &["foo", "bar", "baz"]), Ok(()));
531+
assert_eq!(
532+
bundle.insert_string_vec(
533+
"string",
534+
&[&"foo".to_string(), &"bar".to_string(), &"baz".to_string()]
535+
),
536+
Ok(())
537+
);
538+
assert_eq!(
539+
bundle.insert_string_vec(
540+
"string",
541+
&["foo".to_string(), "bar".to_string(), "baz".to_string()]
542+
),
543+
Ok(())
544+
);
545+
546+
assert_eq!(bundle.size(), 5);
547+
}
548+
549+
#[test]
550+
fn insert_bundle() {
551+
let mut bundle = PersistableBundle::new();
552+
553+
let sub_bundle = PersistableBundle::new();
554+
assert_eq!(bundle.insert_persistable_bundle("bundle", &sub_bundle), Ok(()));
555+
}
342556
}

0 commit comments

Comments
 (0)