blob: a0e147860d3c6537b8978d92bf7e9bd9a6dbf2df [file] [log] [blame]
Stephen Crane2a3c2502020-06-16 17:48:35 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Container for messages that are sent via binder.
18
19use crate::binder::AsNative;
20use crate::error::{status_result, Result, StatusCode};
21use crate::proxy::SpIBinder;
22use crate::sys;
23
Stephen Craneaae76382020-08-03 14:12:15 -070024use std::cell::RefCell;
Stephen Crane2a3c2502020-06-16 17:48:35 -070025use std::convert::TryInto;
Alice Ryhl268458c2021-09-15 12:56:10 +000026use std::marker::PhantomData;
Stephen Crane2a3c2502020-06-16 17:48:35 -070027use std::mem::ManuallyDrop;
28use std::ptr;
Alice Ryhlfeba6ca2021-08-19 10:47:04 +000029use std::fmt;
Stephen Crane2a3c2502020-06-16 17:48:35 -070030
31mod file_descriptor;
32mod parcelable;
Andrei Homescuea406212021-09-03 02:55:00 +000033mod parcelable_holder;
Stephen Crane2a3c2502020-06-16 17:48:35 -070034
35pub use self::file_descriptor::ParcelFileDescriptor;
36pub use self::parcelable::{
37 Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
Andrei Homescu083e3532021-09-08 00:36:18 +000038 Parcelable, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
Stephen Crane2a3c2502020-06-16 17:48:35 -070039};
Andrei Homescuea406212021-09-03 02:55:00 +000040pub use self::parcelable_holder::{ParcelableHolder, ParcelableMetadata};
Stephen Crane2a3c2502020-06-16 17:48:35 -070041
42/// Container for a message (data and object references) that can be sent
43/// through Binder.
44///
45/// A Parcel can contain both serialized data that will be deserialized on the
46/// other side of the IPC, and references to live Binder objects that will
47/// result in the other side receiving a proxy Binder connected with the
48/// original Binder in the Parcel.
49pub enum Parcel {
50 /// Owned parcel pointer
51 Owned(*mut sys::AParcel),
52 /// Borrowed parcel pointer (will not be destroyed on drop)
53 Borrowed(*mut sys::AParcel),
54}
55
Alice Ryhl268458c2021-09-15 12:56:10 +000056/// A variant of Parcel that is known to be owned.
57pub struct OwnedParcel {
58 ptr: *mut sys::AParcel,
59}
60
61/// # Safety
62///
63/// This type guarantees that it owns the AParcel and that all access to
64/// the AParcel happens through the OwnedParcel, so it is ok to send across
65/// threads.
66unsafe impl Send for OwnedParcel {}
67
68/// A variant of Parcel that is known to be borrowed.
69pub struct BorrowedParcel<'a> {
70 inner: Parcel,
71 _lifetime: PhantomData<&'a mut Parcel>,
72}
73
74impl OwnedParcel {
75 /// Create a new empty `OwnedParcel`.
76 pub fn new() -> OwnedParcel {
77 let ptr = unsafe {
78 // Safety: If `AParcel_create` succeeds, it always returns
79 // a valid pointer. If it fails, the process will crash.
80 sys::AParcel_create()
81 };
82 assert!(!ptr.is_null());
83 Self { ptr }
84 }
85
Alice Ryhl05f5a2c2021-09-15 12:56:10 +000086 /// Convert the provided parcel to an owned parcel, or return `None` if it
87 /// is borrowed.
88 pub fn try_from(parcel: Parcel) -> Option<OwnedParcel> {
89 match &parcel {
90 Parcel::Owned(ptr) => {
91 let ptr = *ptr;
92 std::mem::forget(parcel);
93 Some(OwnedParcel { ptr })
94 }
95 Parcel::Borrowed(_) => None,
96 }
97 }
98
Alice Ryhl268458c2021-09-15 12:56:10 +000099 /// Create an owned reference to a parcel object from a raw pointer.
100 ///
101 /// # Safety
102 ///
103 /// This constructor is safe if the raw pointer parameter is either null
104 /// (resulting in `None`), or a valid pointer to an `AParcel` object. The
105 /// parcel object must be owned by the caller prior to this call, as this
106 /// constructor takes ownership of the parcel and will destroy it on drop.
107 ///
108 /// Additionally, the caller must guarantee that it is valid to take
109 /// ownership of the AParcel object. All future access to the AParcel
110 /// must happen through this `OwnedParcel`.
111 ///
112 /// Because `OwnedParcel` implements `Send`, the pointer must never point
113 /// to any thread-local data, e.g., a variable on the stack, either directly
114 /// or indirectly.
115 pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<OwnedParcel> {
116 ptr.as_mut().map(|ptr| Self { ptr })
117 }
118
119 /// Consume the parcel, transferring ownership to the caller.
120 pub(crate) fn into_raw(self) -> *mut sys::AParcel {
121 let ptr = self.ptr;
122 let _ = ManuallyDrop::new(self);
123 ptr
124 }
125
126 /// Convert this `OwnedParcel` into an owned `Parcel`.
127 pub fn into_parcel(self) -> Parcel {
128 Parcel::Owned(self.into_raw())
129 }
130
131 /// Get a borrowed view into the contents of this `Parcel`.
132 pub fn borrowed(&mut self) -> BorrowedParcel<'_> {
133 BorrowedParcel {
134 inner: Parcel::Borrowed(self.ptr),
135 _lifetime: PhantomData,
136 }
137 }
138}
139
140impl Default for OwnedParcel {
141 fn default() -> Self {
142 Self::new()
143 }
144}
145
146impl Clone for OwnedParcel {
147 fn clone(&self) -> Self {
148 let mut new_parcel = Self::new();
149 new_parcel
150 .borrowed()
151 .append_all_from(&Parcel::Borrowed(self.ptr))
152 .expect("Failed to append from Parcel");
153 new_parcel
154 }
155}
156
157impl<'a> std::ops::Deref for BorrowedParcel<'a> {
158 type Target = Parcel;
159 fn deref(&self) -> &Parcel {
160 &self.inner
161 }
162}
163impl<'a> std::ops::DerefMut for BorrowedParcel<'a> {
164 fn deref_mut(&mut self) -> &mut Parcel {
165 &mut self.inner
166 }
167}
168
Stephen Crane2a3c2502020-06-16 17:48:35 -0700169/// # Safety
170///
171/// The `Parcel` constructors guarantee that a `Parcel` object will always
172/// contain a valid pointer to an `AParcel`.
173unsafe impl AsNative<sys::AParcel> for Parcel {
174 fn as_native(&self) -> *const sys::AParcel {
175 match *self {
176 Self::Owned(x) | Self::Borrowed(x) => x,
177 }
178 }
179
180 fn as_native_mut(&mut self) -> *mut sys::AParcel {
181 match *self {
182 Self::Owned(x) | Self::Borrowed(x) => x,
183 }
184 }
185}
186
187impl Parcel {
Andrei Homescu72b799d2021-09-04 01:39:23 +0000188 /// Create a new empty `Parcel`.
189 ///
190 /// Creates a new owned empty parcel that can be written to
191 /// using the serialization methods and appended to and
192 /// from using `append_from` and `append_from_all`.
193 pub fn new() -> Parcel {
194 let parcel = unsafe {
195 // Safety: If `AParcel_create` succeeds, it always returns
196 // a valid pointer. If it fails, the process will crash.
197 sys::AParcel_create()
198 };
199 assert!(!parcel.is_null());
200 Self::Owned(parcel)
201 }
202
Stephen Crane2a3c2502020-06-16 17:48:35 -0700203 /// Create a borrowed reference to a parcel object from a raw pointer.
204 ///
205 /// # Safety
206 ///
207 /// This constructor is safe if the raw pointer parameter is either null
208 /// (resulting in `None`), or a valid pointer to an `AParcel` object.
209 pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> {
210 ptr.as_mut().map(|ptr| Self::Borrowed(ptr))
211 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700212}
213
Andrei Homescu72b799d2021-09-04 01:39:23 +0000214impl Default for Parcel {
215 fn default() -> Self {
216 Self::new()
217 }
218}
219
220impl Clone for Parcel {
221 fn clone(&self) -> Self {
222 let mut new_parcel = Self::new();
223 new_parcel
224 .append_all_from(self)
225 .expect("Failed to append from Parcel");
226 new_parcel
227 }
228}
229
Stephen Crane2a3c2502020-06-16 17:48:35 -0700230// Data serialization methods
231impl Parcel {
Steven Morelandf183fdd2020-10-27 00:12:12 +0000232 /// Data written to parcelable is zero'd before being deleted or reallocated.
233 pub fn mark_sensitive(&mut self) {
234 unsafe {
235 // Safety: guaranteed to have a parcel object, and this method never fails
236 sys::AParcel_markSensitive(self.as_native())
237 }
238 }
239
Stephen Crane2a3c2502020-06-16 17:48:35 -0700240 /// Write a type that implements [`Serialize`] to the `Parcel`.
241 pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
242 parcelable.serialize(self)
243 }
244
245 /// Writes the length of a slice to the `Parcel`.
246 ///
247 /// This is used in AIDL-generated client side code to indicate the
248 /// allocated space for an output array parameter.
249 pub fn write_slice_size<T>(&mut self, slice: Option<&[T]>) -> Result<()> {
250 if let Some(slice) = slice {
251 let len: i32 = slice.len().try_into().or(Err(StatusCode::BAD_VALUE))?;
252 self.write(&len)
253 } else {
254 self.write(&-1i32)
255 }
256 }
257
Stephen Craneaae76382020-08-03 14:12:15 -0700258 /// Perform a series of writes to the `Parcel`, prepended with the length
259 /// (in bytes) of the written data.
260 ///
261 /// The length `0i32` will be written to the parcel first, followed by the
262 /// writes performed by the callback. The initial length will then be
263 /// updated to the length of all data written by the callback, plus the
264 /// size of the length elemement itself (4 bytes).
265 ///
266 /// # Examples
267 ///
268 /// After the following call:
269 ///
270 /// ```
271 /// # use binder::{Binder, Interface, Parcel};
272 /// # let mut parcel = Parcel::Owned(std::ptr::null_mut());
273 /// parcel.sized_write(|subparcel| {
274 /// subparcel.write(&1u32)?;
275 /// subparcel.write(&2u32)?;
276 /// subparcel.write(&3u32)
277 /// });
278 /// ```
279 ///
280 /// `parcel` will contain the following:
281 ///
282 /// ```ignore
283 /// [16i32, 1u32, 2u32, 3u32]
284 /// ```
285 pub fn sized_write<F>(&mut self, f: F) -> Result<()>
286 where for<'a>
287 F: Fn(&'a WritableSubParcel<'a>) -> Result<()>
288 {
289 let start = self.get_data_position();
290 self.write(&0i32)?;
291 {
292 let subparcel = WritableSubParcel(RefCell::new(self));
293 f(&subparcel)?;
294 }
295 let end = self.get_data_position();
296 unsafe {
297 self.set_data_position(start)?;
298 }
299 assert!(end >= start);
300 self.write(&(end - start))?;
301 unsafe {
302 self.set_data_position(end)?;
303 }
304 Ok(())
305 }
306
Stephen Crane2a3c2502020-06-16 17:48:35 -0700307 /// Returns the current position in the parcel data.
308 pub fn get_data_position(&self) -> i32 {
309 unsafe {
310 // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
311 // and this call is otherwise safe.
312 sys::AParcel_getDataPosition(self.as_native())
313 }
314 }
315
Andrei Homescub0487442021-05-12 07:16:16 +0000316 /// Returns the total size of the parcel.
317 pub fn get_data_size(&self) -> i32 {
318 unsafe {
319 // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
320 // and this call is otherwise safe.
321 sys::AParcel_getDataSize(self.as_native())
322 }
323 }
324
Stephen Crane2a3c2502020-06-16 17:48:35 -0700325 /// Move the current read/write position in the parcel.
326 ///
Stephen Crane2a3c2502020-06-16 17:48:35 -0700327 /// # Safety
328 ///
329 /// This method is safe if `pos` is less than the current size of the parcel
330 /// data buffer. Otherwise, we are relying on correct bounds checking in the
331 /// Parcel C++ code on every subsequent read or write to this parcel. If all
332 /// accesses are bounds checked, this call is still safe, but we can't rely
333 /// on that.
334 pub unsafe fn set_data_position(&self, pos: i32) -> Result<()> {
335 status_result(sys::AParcel_setDataPosition(self.as_native(), pos))
336 }
Andrei Homescu72b799d2021-09-04 01:39:23 +0000337
338 /// Append a subset of another `Parcel`.
339 ///
340 /// This appends `size` bytes of data from `other` starting at offset
341 /// `start` to the current `Parcel`, or returns an error if not possible.
342 pub fn append_from(&mut self, other: &Self, start: i32, size: i32) -> Result<()> {
343 let status = unsafe {
344 // Safety: `Parcel::appendFrom` from C++ checks that `start`
345 // and `size` are in bounds, and returns an error otherwise.
346 // Both `self` and `other` always contain valid pointers.
347 sys::AParcel_appendFrom(
348 other.as_native(),
349 self.as_native_mut(),
350 start,
351 size,
352 )
353 };
354 status_result(status)
355 }
356
357 /// Append the contents of another `Parcel`.
358 pub fn append_all_from(&mut self, other: &Self) -> Result<()> {
359 self.append_from(other, 0, other.get_data_size())
360 }
Stephen Crane2a3c2502020-06-16 17:48:35 -0700361}
362
Stephen Craneaae76382020-08-03 14:12:15 -0700363/// A segment of a writable parcel, used for [`Parcel::sized_write`].
364pub struct WritableSubParcel<'a>(RefCell<&'a mut Parcel>);
365
366impl<'a> WritableSubParcel<'a> {
367 /// Write a type that implements [`Serialize`] to the sub-parcel.
368 pub fn write<S: Serialize + ?Sized>(&self, parcelable: &S) -> Result<()> {
369 parcelable.serialize(&mut *self.0.borrow_mut())
370 }
371}
372
Stephen Crane2a3c2502020-06-16 17:48:35 -0700373// Data deserialization methods
374impl Parcel {
375 /// Attempt to read a type that implements [`Deserialize`] from this
376 /// `Parcel`.
377 pub fn read<D: Deserialize>(&self) -> Result<D> {
378 D::deserialize(self)
379 }
380
Andrei Homescu50006152021-05-01 07:34:51 +0000381 /// Attempt to read a type that implements [`Deserialize`] from this
382 /// `Parcel` onto an existing value. This operation will overwrite the old
383 /// value partially or completely, depending on how much data is available.
384 pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
385 x.deserialize_from(self)
386 }
387
Andrei Homescub0487442021-05-12 07:16:16 +0000388 /// Safely read a sized parcelable.
389 ///
390 /// Read the size of a parcelable, compute the end position
391 /// of that parcelable, then build a sized readable sub-parcel
392 /// and call a closure with the sub-parcel as its parameter.
393 /// The closure can keep reading data from the sub-parcel
394 /// until it runs out of input data. The closure is responsible
395 /// for calling [`ReadableSubParcel::has_more_data`] to check for
396 /// more data before every read, at least until Rust generators
397 /// are stabilized.
398 /// After the closure returns, skip to the end of the current
399 /// parcelable regardless of how much the closure has read.
400 ///
401 /// # Examples
402 ///
403 /// ```no_run
404 /// let mut parcelable = Default::default();
405 /// parcel.sized_read(|subparcel| {
406 /// if subparcel.has_more_data() {
407 /// parcelable.a = subparcel.read()?;
408 /// }
409 /// if subparcel.has_more_data() {
410 /// parcelable.b = subparcel.read()?;
411 /// }
412 /// Ok(())
413 /// });
414 /// ```
415 ///
416 pub fn sized_read<F>(&self, mut f: F) -> Result<()>
417 where
418 for<'a> F: FnMut(ReadableSubParcel<'a>) -> Result<()>
419 {
420 let start = self.get_data_position();
421 let parcelable_size: i32 = self.read()?;
422 if parcelable_size < 0 {
423 return Err(StatusCode::BAD_VALUE);
424 }
425
426 let end = start.checked_add(parcelable_size)
427 .ok_or(StatusCode::BAD_VALUE)?;
428 if end > self.get_data_size() {
429 return Err(StatusCode::NOT_ENOUGH_DATA);
430 }
431
432 let subparcel = ReadableSubParcel {
433 parcel: self,
434 end_position: end,
435 };
436 f(subparcel)?;
437
438 // Advance the data position to the actual end,
439 // in case the closure read less data than was available
440 unsafe {
441 self.set_data_position(end)?;
442 }
443
444 Ok(())
445 }
446
Stephen Crane2a3c2502020-06-16 17:48:35 -0700447 /// Read a vector size from the `Parcel` and resize the given output vector
448 /// to be correctly sized for that amount of data.
449 ///
450 /// This method is used in AIDL-generated server side code for methods that
451 /// take a mutable slice reference parameter.
452 pub fn resize_out_vec<D: Default + Deserialize>(&self, out_vec: &mut Vec<D>) -> Result<()> {
453 let len: i32 = self.read()?;
454
455 if len < 0 {
456 return Err(StatusCode::UNEXPECTED_NULL);
457 }
458
459 // usize in Rust may be 16-bit, so i32 may not fit
460 let len = len.try_into().unwrap();
461 out_vec.resize_with(len, Default::default);
462
463 Ok(())
464 }
465
466 /// Read a vector size from the `Parcel` and either create a correctly sized
467 /// vector for that amount of data or set the output parameter to None if
468 /// the vector should be null.
469 ///
470 /// This method is used in AIDL-generated server side code for methods that
471 /// take a mutable slice reference parameter.
472 pub fn resize_nullable_out_vec<D: Default + Deserialize>(
473 &self,
474 out_vec: &mut Option<Vec<D>>,
475 ) -> Result<()> {
476 let len: i32 = self.read()?;
477
478 if len < 0 {
479 *out_vec = None;
480 } else {
481 // usize in Rust may be 16-bit, so i32 may not fit
482 let len = len.try_into().unwrap();
483 let mut vec = Vec::with_capacity(len);
484 vec.resize_with(len, Default::default);
485 *out_vec = Some(vec);
486 }
487
488 Ok(())
489 }
490}
491
Andrei Homescub0487442021-05-12 07:16:16 +0000492/// A segment of a readable parcel, used for [`Parcel::sized_read`].
493pub struct ReadableSubParcel<'a> {
494 parcel: &'a Parcel,
495 end_position: i32,
496}
497
498impl<'a> ReadableSubParcel<'a> {
499 /// Read a type that implements [`Deserialize`] from the sub-parcel.
500 pub fn read<D: Deserialize>(&self) -> Result<D> {
501 // The caller should have checked this,
502 // but it can't hurt to double-check
503 assert!(self.has_more_data());
504 D::deserialize(self.parcel)
505 }
506
507 /// Check if the sub-parcel has more data to read
508 pub fn has_more_data(&self) -> bool {
509 self.parcel.get_data_position() < self.end_position
510 }
511}
512
Stephen Crane2a3c2502020-06-16 17:48:35 -0700513// Internal APIs
514impl Parcel {
515 pub(crate) fn write_binder(&mut self, binder: Option<&SpIBinder>) -> Result<()> {
516 unsafe {
517 // Safety: `Parcel` always contains a valid pointer to an
518 // `AParcel`. `AsNative` for `Option<SpIBinder`> will either return
519 // null or a valid pointer to an `AIBinder`, both of which are
520 // valid, safe inputs to `AParcel_writeStrongBinder`.
521 //
522 // This call does not take ownership of the binder. However, it does
523 // require a mutable pointer, which we cannot extract from an
524 // immutable reference, so we clone the binder, incrementing the
525 // refcount before the call. The refcount will be immediately
526 // decremented when this temporary is dropped.
527 status_result(sys::AParcel_writeStrongBinder(
528 self.as_native_mut(),
529 binder.cloned().as_native_mut(),
530 ))
531 }
532 }
533
534 pub(crate) fn read_binder(&self) -> Result<Option<SpIBinder>> {
535 let mut binder = ptr::null_mut();
536 let status = unsafe {
537 // Safety: `Parcel` always contains a valid pointer to an
538 // `AParcel`. We pass a valid, mutable out pointer to the `binder`
539 // parameter. After this call, `binder` will be either null or a
540 // valid pointer to an `AIBinder` owned by the caller.
541 sys::AParcel_readStrongBinder(self.as_native(), &mut binder)
542 };
543
544 status_result(status)?;
545
546 Ok(unsafe {
547 // Safety: `binder` is either null or a valid, owned pointer at this
548 // point, so can be safely passed to `SpIBinder::from_raw`.
549 SpIBinder::from_raw(binder)
550 })
551 }
552}
553
554impl Drop for Parcel {
555 fn drop(&mut self) {
556 // Run the C++ Parcel complete object destructor
557 if let Self::Owned(ptr) = *self {
558 unsafe {
559 // Safety: `Parcel` always contains a valid pointer to an
560 // `AParcel`. If we own the parcel, we can safely delete it
561 // here.
562 sys::AParcel_delete(ptr)
563 }
564 }
565 }
566}
567
Alice Ryhl268458c2021-09-15 12:56:10 +0000568impl Drop for OwnedParcel {
569 fn drop(&mut self) {
570 // Run the C++ Parcel complete object destructor
571 unsafe {
572 // Safety: `OwnedParcel` always contains a valid pointer to an
573 // `AParcel`. Since we own the parcel, we can safely delete it
574 // here.
575 sys::AParcel_delete(self.ptr)
576 }
577 }
578}
579
Alice Ryhlfeba6ca2021-08-19 10:47:04 +0000580impl fmt::Debug for Parcel {
581 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
582 f.debug_struct("Parcel")
583 .finish()
584 }
585}
586
Alice Ryhl268458c2021-09-15 12:56:10 +0000587impl fmt::Debug for OwnedParcel {
588 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
589 f.debug_struct("OwnedParcel")
590 .finish()
591 }
592}
593
Stephen Crane2a3c2502020-06-16 17:48:35 -0700594#[test]
595fn test_read_write() {
Andrei Homescu72b799d2021-09-04 01:39:23 +0000596 let mut parcel = Parcel::new();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700597 let start = parcel.get_data_position();
598
599 assert_eq!(parcel.read::<bool>(), Err(StatusCode::NOT_ENOUGH_DATA));
600 assert_eq!(parcel.read::<i8>(), Err(StatusCode::NOT_ENOUGH_DATA));
601 assert_eq!(parcel.read::<u16>(), Err(StatusCode::NOT_ENOUGH_DATA));
602 assert_eq!(parcel.read::<i32>(), Err(StatusCode::NOT_ENOUGH_DATA));
603 assert_eq!(parcel.read::<u32>(), Err(StatusCode::NOT_ENOUGH_DATA));
604 assert_eq!(parcel.read::<i64>(), Err(StatusCode::NOT_ENOUGH_DATA));
605 assert_eq!(parcel.read::<u64>(), Err(StatusCode::NOT_ENOUGH_DATA));
606 assert_eq!(parcel.read::<f32>(), Err(StatusCode::NOT_ENOUGH_DATA));
607 assert_eq!(parcel.read::<f64>(), Err(StatusCode::NOT_ENOUGH_DATA));
Stephen Crane76072e82020-08-03 13:09:36 -0700608 assert_eq!(parcel.read::<Option<String>>(), Ok(None));
Stephen Crane2a3c2502020-06-16 17:48:35 -0700609 assert_eq!(parcel.read::<String>(), Err(StatusCode::UNEXPECTED_NULL));
610
611 assert_eq!(parcel.read_binder().err(), Some(StatusCode::BAD_TYPE));
612
613 parcel.write(&1i32).unwrap();
614
615 unsafe {
616 parcel.set_data_position(start).unwrap();
617 }
618
619 let i: i32 = parcel.read().unwrap();
620 assert_eq!(i, 1i32);
621}
622
623#[test]
624#[allow(clippy::float_cmp)]
625fn test_read_data() {
Andrei Homescu72b799d2021-09-04 01:39:23 +0000626 let mut parcel = Parcel::new();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700627 let str_start = parcel.get_data_position();
628
629 parcel.write(&b"Hello, Binder!\0"[..]).unwrap();
630 // Skip over string length
631 unsafe {
632 assert!(parcel.set_data_position(str_start).is_ok());
633 }
634 assert_eq!(parcel.read::<i32>().unwrap(), 15);
635 let start = parcel.get_data_position();
636
Chris Wailes45fd2942021-07-26 19:18:41 -0700637 assert!(parcel.read::<bool>().unwrap());
Stephen Crane2a3c2502020-06-16 17:48:35 -0700638
639 unsafe {
640 assert!(parcel.set_data_position(start).is_ok());
641 }
642
643 assert_eq!(parcel.read::<i8>().unwrap(), 72i8);
644
645 unsafe {
646 assert!(parcel.set_data_position(start).is_ok());
647 }
648
649 assert_eq!(parcel.read::<u16>().unwrap(), 25928);
650
651 unsafe {
652 assert!(parcel.set_data_position(start).is_ok());
653 }
654
655 assert_eq!(parcel.read::<i32>().unwrap(), 1819043144);
656
657 unsafe {
658 assert!(parcel.set_data_position(start).is_ok());
659 }
660
661 assert_eq!(parcel.read::<u32>().unwrap(), 1819043144);
662
663 unsafe {
664 assert!(parcel.set_data_position(start).is_ok());
665 }
666
667 assert_eq!(parcel.read::<i64>().unwrap(), 4764857262830019912);
668
669 unsafe {
670 assert!(parcel.set_data_position(start).is_ok());
671 }
672
673 assert_eq!(parcel.read::<u64>().unwrap(), 4764857262830019912);
674
675 unsafe {
676 assert!(parcel.set_data_position(start).is_ok());
677 }
678
679 assert_eq!(
680 parcel.read::<f32>().unwrap(),
681 1143139100000000000000000000.0
682 );
683 assert_eq!(parcel.read::<f32>().unwrap(), 40.043392);
684
685 unsafe {
686 assert!(parcel.set_data_position(start).is_ok());
687 }
688
689 assert_eq!(parcel.read::<f64>().unwrap(), 34732488246.197815);
690
691 // Skip back to before the string length
692 unsafe {
693 assert!(parcel.set_data_position(str_start).is_ok());
694 }
695
696 assert_eq!(parcel.read::<Vec<u8>>().unwrap(), b"Hello, Binder!\0");
697}
698
699#[test]
700fn test_utf8_utf16_conversions() {
Andrei Homescu72b799d2021-09-04 01:39:23 +0000701 let mut parcel = Parcel::new();
Stephen Crane2a3c2502020-06-16 17:48:35 -0700702 let start = parcel.get_data_position();
703
704 assert!(parcel.write("Hello, Binder!").is_ok());
705 unsafe {
706 assert!(parcel.set_data_position(start).is_ok());
707 }
708 assert_eq!(
709 parcel.read::<Option<String>>().unwrap().unwrap(),
Stephen Crane76072e82020-08-03 13:09:36 -0700710 "Hello, Binder!",
Stephen Crane2a3c2502020-06-16 17:48:35 -0700711 );
712 unsafe {
713 assert!(parcel.set_data_position(start).is_ok());
714 }
Stephen Crane76072e82020-08-03 13:09:36 -0700715
716 assert!(parcel.write("Embedded null \0 inside a string").is_ok());
717 unsafe {
718 assert!(parcel.set_data_position(start).is_ok());
719 }
720 assert_eq!(
721 parcel.read::<Option<String>>().unwrap().unwrap(),
722 "Embedded null \0 inside a string",
723 );
724 unsafe {
725 assert!(parcel.set_data_position(start).is_ok());
726 }
727
Stephen Crane2a3c2502020-06-16 17:48:35 -0700728 assert!(parcel.write(&["str1", "str2", "str3"][..]).is_ok());
729 assert!(parcel
730 .write(
731 &[
732 String::from("str4"),
733 String::from("str5"),
734 String::from("str6"),
735 ][..]
736 )
737 .is_ok());
738
739 let s1 = "Hello, Binder!";
740 let s2 = "This is a utf8 string.";
741 let s3 = "Some more text here.";
742
743 assert!(parcel.write(&[s1, s2, s3][..]).is_ok());
744 unsafe {
745 assert!(parcel.set_data_position(start).is_ok());
746 }
747
748 assert_eq!(
749 parcel.read::<Vec<String>>().unwrap(),
750 ["str1", "str2", "str3"]
751 );
752 assert_eq!(
753 parcel.read::<Vec<String>>().unwrap(),
754 ["str4", "str5", "str6"]
755 );
756 assert_eq!(parcel.read::<Vec<String>>().unwrap(), [s1, s2, s3]);
757}
Stephen Craneaae76382020-08-03 14:12:15 -0700758
759#[test]
760fn test_sized_write() {
Andrei Homescu72b799d2021-09-04 01:39:23 +0000761 let mut parcel = Parcel::new();
Stephen Craneaae76382020-08-03 14:12:15 -0700762 let start = parcel.get_data_position();
763
764 let arr = [1i32, 2i32, 3i32];
765
766 parcel.sized_write(|subparcel| {
767 subparcel.write(&arr[..])
768 }).expect("Could not perform sized write");
769
770 // i32 sub-parcel length + i32 array length + 3 i32 elements
771 let expected_len = 20i32;
772
773 assert_eq!(parcel.get_data_position(), start + expected_len);
774
775 unsafe {
776 parcel.set_data_position(start).unwrap();
777 }
778
779 assert_eq!(
780 expected_len,
781 parcel.read().unwrap(),
782 );
783
784 assert_eq!(
785 parcel.read::<Vec<i32>>().unwrap(),
786 &arr,
787 );
788}
Andrei Homescu72b799d2021-09-04 01:39:23 +0000789
790#[test]
791fn test_append_from() {
792 let mut parcel1 = Parcel::new();
793 parcel1.write(&42i32).expect("Could not perform write");
794
795 let mut parcel2 = Parcel::new();
796 assert_eq!(Ok(()), parcel2.append_all_from(&parcel1));
797 assert_eq!(4, parcel2.get_data_size());
798 assert_eq!(Ok(()), parcel2.append_all_from(&parcel1));
799 assert_eq!(8, parcel2.get_data_size());
800 unsafe {
801 parcel2.set_data_position(0).unwrap();
802 }
803 assert_eq!(Ok(42), parcel2.read::<i32>());
804 assert_eq!(Ok(42), parcel2.read::<i32>());
805
806 let mut parcel2 = Parcel::new();
807 assert_eq!(Ok(()), parcel2.append_from(&parcel1, 0, 2));
808 assert_eq!(Ok(()), parcel2.append_from(&parcel1, 2, 2));
809 assert_eq!(4, parcel2.get_data_size());
810 unsafe {
811 parcel2.set_data_position(0).unwrap();
812 }
813 assert_eq!(Ok(42), parcel2.read::<i32>());
814
815 let mut parcel2 = Parcel::new();
816 assert_eq!(Ok(()), parcel2.append_from(&parcel1, 0, 2));
817 assert_eq!(2, parcel2.get_data_size());
818 unsafe {
819 parcel2.set_data_position(0).unwrap();
820 }
821 assert_eq!(Err(StatusCode::NOT_ENOUGH_DATA), parcel2.read::<i32>());
822
823 let mut parcel2 = Parcel::new();
824 assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, 4, 2));
825 assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, 2, 4));
826 assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, -1, 4));
827 assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, 2, -1));
828}