@@ -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} ;
3134use std:: ffi:: { CString , NulError } ;
3235use 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