@@ -23,10 +23,14 @@ use crate::{
2323use binder_ndk_sys:: {
2424 APersistableBundle , APersistableBundle_delete , APersistableBundle_dup ,
2525 APersistableBundle_erase , APersistableBundle_getBoolean , APersistableBundle_getDouble ,
26- 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 ,
26+ APersistableBundle_getInt , APersistableBundle_getLong , APersistableBundle_getPersistableBundle ,
27+ APersistableBundle_isEqual , APersistableBundle_new , APersistableBundle_putBoolean ,
28+ APersistableBundle_putBooleanVector , APersistableBundle_putDouble ,
29+ APersistableBundle_putDoubleVector , APersistableBundle_putInt , APersistableBundle_putIntVector ,
30+ APersistableBundle_putLong , APersistableBundle_putLongVector ,
31+ APersistableBundle_putPersistableBundle , APersistableBundle_putString ,
32+ APersistableBundle_putStringVector , APersistableBundle_readFromParcel , APersistableBundle_size ,
33+ APersistableBundle_writeToParcel ,
3034} ;
3135use std:: ffi:: { CString , NulError } ;
3236use std:: ptr:: { null_mut, NonNull } ;
@@ -60,7 +64,7 @@ impl PersistableBundle {
6064 let key = CString :: new ( key) ?;
6165 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
6266 // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
63- // to be valid for the lifetime of `key` .
67+ // to be valid for the duration of this call .
6468 Ok ( unsafe { APersistableBundle_erase ( self . 0 . as_ptr ( ) , key. as_ptr ( ) ) != 0 } )
6569 }
6670
@@ -73,7 +77,7 @@ impl PersistableBundle {
7377 let key = CString :: new ( key) ?;
7478 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
7579 // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
76- // to be valid for the lifetime of `key` .
80+ // to be valid for the duration of this call .
7781 unsafe {
7882 APersistableBundle_putBoolean ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , value) ;
7983 }
@@ -89,7 +93,7 @@ impl PersistableBundle {
8993 let key = CString :: new ( key) ?;
9094 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
9195 // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
92- // to be valid for the lifetime of `key` .
96+ // to be valid for the duration of this call .
9397 unsafe {
9498 APersistableBundle_putInt ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , value) ;
9599 }
@@ -105,7 +109,7 @@ impl PersistableBundle {
105109 let key = CString :: new ( key) ?;
106110 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
107111 // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
108- // to be valid for the lifetime of `key` .
112+ // to be valid for the duration of this call .
109113 unsafe {
110114 APersistableBundle_putLong ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , value) ;
111115 }
@@ -121,13 +125,182 @@ impl PersistableBundle {
121125 let key = CString :: new ( key) ?;
122126 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
123127 // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
124- // to be valid for the lifetime of `key` .
128+ // to be valid for the duration of this call .
125129 unsafe {
126130 APersistableBundle_putDouble ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , value) ;
127131 }
128132 Ok ( ( ) )
129133 }
130134
135+ /// Inserts a key-value pair into the bundle.
136+ ///
137+ /// If the key is already present then its value will be overwritten by the given value.
138+ ///
139+ /// Returns an error if the key or value contains a NUL character.
140+ pub fn insert_string ( & mut self , key : & str , value : & str ) -> Result < ( ) , NulError > {
141+ let key = CString :: new ( key) ?;
142+ let value = CString :: new ( value) ?;
143+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
144+ // lifetime of the `PersistableBundle`. The pointer returned by `CStr::as_ptr` is guaranteed
145+ // to be valid for the duration of this call.
146+ unsafe {
147+ APersistableBundle_putString ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , value. as_ptr ( ) ) ;
148+ }
149+ Ok ( ( ) )
150+ }
151+
152+ /// Inserts a key-value pair into the bundle.
153+ ///
154+ /// If the key is already present then its value will be overwritten by the given value.
155+ ///
156+ /// Returns an error if the key contains a NUL character.
157+ pub fn insert_bool_vec ( & mut self , key : & str , value : & [ bool ] ) -> Result < ( ) , NulError > {
158+ let key = CString :: new ( key) ?;
159+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
160+ // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
161+ // to be valid for the duration of this call, and likewise the pointer returned by
162+ // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
163+ // duration of the call.
164+ unsafe {
165+ APersistableBundle_putBooleanVector (
166+ self . 0 . as_ptr ( ) ,
167+ key. as_ptr ( ) ,
168+ value. as_ptr ( ) ,
169+ value. len ( ) . try_into ( ) . unwrap ( ) ,
170+ ) ;
171+ }
172+ Ok ( ( ) )
173+ }
174+
175+ /// Inserts a key-value pair into the bundle.
176+ ///
177+ /// If the key is already present then its value will be overwritten by the given value.
178+ ///
179+ /// Returns an error if the key contains a NUL character.
180+ pub fn insert_int_vec ( & mut self , key : & str , value : & [ i32 ] ) -> Result < ( ) , NulError > {
181+ let key = CString :: new ( key) ?;
182+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
183+ // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
184+ // to be valid for the duration of this call, and likewise the pointer returned by
185+ // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
186+ // duration of the call.
187+ unsafe {
188+ APersistableBundle_putIntVector (
189+ self . 0 . as_ptr ( ) ,
190+ key. as_ptr ( ) ,
191+ value. as_ptr ( ) ,
192+ value. len ( ) . try_into ( ) . unwrap ( ) ,
193+ ) ;
194+ }
195+ Ok ( ( ) )
196+ }
197+
198+ /// Inserts a key-value pair into the bundle.
199+ ///
200+ /// If the key is already present then its value will be overwritten by the given value.
201+ ///
202+ /// Returns an error if the key contains a NUL character.
203+ pub fn insert_long_vec ( & mut self , key : & str , value : & [ i64 ] ) -> Result < ( ) , NulError > {
204+ let key = CString :: new ( key) ?;
205+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
206+ // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
207+ // to be valid for the duration of this call, and likewise the pointer returned by
208+ // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
209+ // duration of the call.
210+ unsafe {
211+ APersistableBundle_putLongVector (
212+ self . 0 . as_ptr ( ) ,
213+ key. as_ptr ( ) ,
214+ value. as_ptr ( ) ,
215+ value. len ( ) . try_into ( ) . unwrap ( ) ,
216+ ) ;
217+ }
218+ Ok ( ( ) )
219+ }
220+
221+ /// Inserts a key-value pair into the bundle.
222+ ///
223+ /// If the key is already present then its value will be overwritten by the given value.
224+ ///
225+ /// Returns an error if the key contains a NUL character.
226+ pub fn insert_double_vec ( & mut self , key : & str , value : & [ f64 ] ) -> Result < ( ) , NulError > {
227+ let key = CString :: new ( key) ?;
228+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
229+ // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
230+ // to be valid for the duration of this call, and likewise the pointer returned by
231+ // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
232+ // duration of the call.
233+ unsafe {
234+ APersistableBundle_putDoubleVector (
235+ self . 0 . as_ptr ( ) ,
236+ key. as_ptr ( ) ,
237+ value. as_ptr ( ) ,
238+ value. len ( ) . try_into ( ) . unwrap ( ) ,
239+ ) ;
240+ }
241+ Ok ( ( ) )
242+ }
243+
244+ /// Inserts a key-value pair into the bundle.
245+ ///
246+ /// If the key is already present then its value will be overwritten by the given value.
247+ ///
248+ /// Returns an error if the key contains a NUL character.
249+ pub fn insert_string_vec < ' a , T : ToString + ' a > (
250+ & mut self ,
251+ key : & str ,
252+ value : impl IntoIterator < Item = & ' a T > ,
253+ ) -> Result < ( ) , NulError > {
254+ let key = CString :: new ( key) ?;
255+ // We need to collect the new `CString`s into something first so that they live long enough
256+ // for their pointers to be valid for the `APersistableBundle_putStringVector` call below.
257+ let c_strings = value
258+ . into_iter ( )
259+ . map ( |s| CString :: new ( s. to_string ( ) ) )
260+ . collect :: < Result < Vec < _ > , NulError > > ( ) ?;
261+ let char_pointers = c_strings. iter ( ) . map ( |s| s. as_ptr ( ) ) . collect :: < Vec < _ > > ( ) ;
262+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
263+ // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
264+ // to be valid for the duration of this call, and likewise the pointer returned by
265+ // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
266+ // duration of the call.
267+ unsafe {
268+ APersistableBundle_putStringVector (
269+ self . 0 . as_ptr ( ) ,
270+ key. as_ptr ( ) ,
271+ char_pointers. as_ptr ( ) ,
272+ char_pointers. len ( ) . try_into ( ) . unwrap ( ) ,
273+ ) ;
274+ }
275+ Ok ( ( ) )
276+ }
277+
278+ /// Inserts a key-value pair into the bundle.
279+ ///
280+ /// If the key is already present then its value will be overwritten by the given value.
281+ ///
282+ /// Returns an error if the key contains a NUL character.
283+ pub fn insert_persistable_bundle (
284+ & mut self ,
285+ key : & str ,
286+ value : & PersistableBundle ,
287+ ) -> Result < ( ) , NulError > {
288+ let key = CString :: new ( key) ?;
289+ // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the
290+ // lifetime of the `PersistableBundle`s. The pointer returned by `CStr::as_ptr` is
291+ // guaranteed to be valid for the duration of this call, and
292+ // `APersistableBundle_putPersistableBundle` does a deep copy so that is all that is
293+ // required.
294+ unsafe {
295+ APersistableBundle_putPersistableBundle (
296+ self . 0 . as_ptr ( ) ,
297+ key. as_ptr ( ) ,
298+ value. 0 . as_ptr ( ) ,
299+ ) ;
300+ }
301+ Ok ( ( ) )
302+ }
303+
131304 /// Gets the boolean value associated with the given key.
132305 ///
133306 /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
@@ -137,8 +310,8 @@ impl PersistableBundle {
137310 let mut value = false ;
138311 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
139312 // 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.
313+ // to be valid for the duration of this call . The value pointer must be valid because it
314+ // comes from a reference.
142315 if unsafe { APersistableBundle_getBoolean ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , & mut value) } {
143316 Ok ( Some ( value) )
144317 } else {
@@ -155,8 +328,8 @@ impl PersistableBundle {
155328 let mut value = 0 ;
156329 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
157330 // 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.
331+ // to be valid for the duration of this call . The value pointer must be valid because it
332+ // comes from a reference.
160333 if unsafe { APersistableBundle_getInt ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , & mut value) } {
161334 Ok ( Some ( value) )
162335 } else {
@@ -173,8 +346,8 @@ impl PersistableBundle {
173346 let mut value = 0 ;
174347 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
175348 // 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.
349+ // to be valid for the duration of this call . The value pointer must be valid because it
350+ // comes from a reference.
178351 if unsafe { APersistableBundle_getLong ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , & mut value) } {
179352 Ok ( Some ( value) )
180353 } else {
@@ -191,14 +364,36 @@ impl PersistableBundle {
191364 let mut value = 0.0 ;
192365 // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
193366 // 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.
367+ // to be valid for the duration of this call . The value pointer must be valid because it
368+ // comes from a reference.
196369 if unsafe { APersistableBundle_getDouble ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , & mut value) } {
197370 Ok ( Some ( value) )
198371 } else {
199372 Ok ( None )
200373 }
201374 }
375+
376+ /// Gets the `PersistableBundle` value associated with the given key.
377+ ///
378+ /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
379+ /// in the bundle.
380+ pub fn get_persistable_bundle ( & self , key : & str ) -> Result < Option < Self > , NulError > {
381+ let key = CString :: new ( key) ?;
382+ let mut value = null_mut ( ) ;
383+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
384+ // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
385+ // to be valid for the lifetime of `key`. The value pointer must be valid because it comes
386+ // from a reference.
387+ if unsafe {
388+ APersistableBundle_getPersistableBundle ( self . 0 . as_ptr ( ) , key. as_ptr ( ) , & mut value)
389+ } {
390+ Ok ( Some ( Self ( NonNull :: new ( value) . expect (
391+ "APersistableBundle_getPersistableBundle returned true but didn't set outBundle" ,
392+ ) ) ) )
393+ } else {
394+ Ok ( None )
395+ }
396+ }
202397}
203398
204399// SAFETY: The underlying *APersistableBundle can be moved between threads.
@@ -339,4 +534,50 @@ mod test {
339534 assert_eq ! ( bundle. get_double( "double" ) , Ok ( None ) ) ;
340535 assert_eq ! ( bundle. size( ) , 0 ) ;
341536 }
537+
538+ #[ test]
539+ fn insert_string ( ) {
540+ let mut bundle = PersistableBundle :: new ( ) ;
541+ assert_eq ! ( bundle. insert_string( "string" , "foo" ) , Ok ( ( ) ) ) ;
542+ assert_eq ! ( bundle. size( ) , 1 ) ;
543+ }
544+
545+ #[ test]
546+ fn insert_vec ( ) {
547+ let mut bundle = PersistableBundle :: new ( ) ;
548+
549+ assert_eq ! ( bundle. insert_bool_vec( "bool" , & [ ] ) , Ok ( ( ) ) ) ;
550+ assert_eq ! ( bundle. insert_int_vec( "int" , & [ 42 ] ) , Ok ( ( ) ) ) ;
551+ assert_eq ! ( bundle. insert_long_vec( "long" , & [ 66 , 67 , 68 ] ) , Ok ( ( ) ) ) ;
552+ assert_eq ! ( bundle. insert_double_vec( "double" , & [ 123.4 ] ) , Ok ( ( ) ) ) ;
553+ assert_eq ! ( bundle. insert_string_vec( "string" , & [ "foo" , "bar" , "baz" ] ) , Ok ( ( ) ) ) ;
554+ assert_eq ! (
555+ bundle. insert_string_vec(
556+ "string" ,
557+ & [ & "foo" . to_string( ) , & "bar" . to_string( ) , & "baz" . to_string( ) ]
558+ ) ,
559+ Ok ( ( ) )
560+ ) ;
561+ assert_eq ! (
562+ bundle. insert_string_vec(
563+ "string" ,
564+ & [ "foo" . to_string( ) , "bar" . to_string( ) , "baz" . to_string( ) ]
565+ ) ,
566+ Ok ( ( ) )
567+ ) ;
568+
569+ assert_eq ! ( bundle. size( ) , 5 ) ;
570+ }
571+
572+ #[ test]
573+ fn insert_get_bundle ( ) {
574+ let mut bundle = PersistableBundle :: new ( ) ;
575+
576+ let mut sub_bundle = PersistableBundle :: new ( ) ;
577+ assert_eq ! ( sub_bundle. insert_int( "int" , 42 ) , Ok ( ( ) ) ) ;
578+ assert_eq ! ( sub_bundle. size( ) , 1 ) ;
579+ assert_eq ! ( bundle. insert_persistable_bundle( "bundle" , & sub_bundle) , Ok ( ( ) ) ) ;
580+
581+ assert_eq ! ( bundle. get_persistable_bundle( "bundle" ) , Ok ( Some ( sub_bundle) ) ) ;
582+ }
342583}
0 commit comments