1a34a8711Sopenharmony_ci// Copyright (C) 2024 Huawei Device Co., Ltd. 2a34a8711Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 3a34a8711Sopenharmony_ci// you may not use this file except in compliance with the License. 4a34a8711Sopenharmony_ci// You may obtain a copy of the License at 5a34a8711Sopenharmony_ci// 6a34a8711Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 7a34a8711Sopenharmony_ci// 8a34a8711Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 9a34a8711Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 10a34a8711Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11a34a8711Sopenharmony_ci// See the License for the specific language governing permissions and 12a34a8711Sopenharmony_ci// limitations under the License. 13a34a8711Sopenharmony_ci 14a34a8711Sopenharmony_ciuse std::borrow::Borrow; 15a34a8711Sopenharmony_ciuse std::fs::File; 16a34a8711Sopenharmony_ciuse std::mem; 17a34a8711Sopenharmony_ciuse std::ops::Deref; 18a34a8711Sopenharmony_ciuse std::os::fd::{FromRawFd, IntoRawFd}; 19a34a8711Sopenharmony_ciuse std::pin::Pin; 20a34a8711Sopenharmony_ci 21a34a8711Sopenharmony_ciuse cxx::UniquePtr; 22a34a8711Sopenharmony_ci 23a34a8711Sopenharmony_ciuse super::error::ParcelSetError; 24a34a8711Sopenharmony_ciuse super::wrapper::{ 25a34a8711Sopenharmony_ci AsParcel, AsParcelMut, MessageOption, MessageParcel, NewMessageOption, NewMessageParcel, 26a34a8711Sopenharmony_ci Parcel, ReadBuffer, ReadInterfaceToken, ReadRemoteObject, ReadString16, ReadString16Vector, 27a34a8711Sopenharmony_ci WriteBuffer, WriteInterfaceToken, WriteRemoteObject, WriteString16, WriteString16Vector, 28a34a8711Sopenharmony_ci}; 29a34a8711Sopenharmony_ciuse super::{Deserialize, Serialize}; 30a34a8711Sopenharmony_ciuse crate::parcel::wrapper::IRemoteObjectWrapper; 31a34a8711Sopenharmony_ciuse crate::remote::RemoteObj; 32a34a8711Sopenharmony_ciuse crate::{IpcResult, IpcStatusCode}; 33a34a8711Sopenharmony_ciconst STRING_16_SIZE: usize = 12; 34a34a8711Sopenharmony_ci 35a34a8711Sopenharmony_cipub(crate) enum ParcelMem { 36a34a8711Sopenharmony_ci Unique(UniquePtr<MessageParcel>), 37a34a8711Sopenharmony_ci Borrow(*mut MessageParcel), 38a34a8711Sopenharmony_ci Null, 39a34a8711Sopenharmony_ci} 40a34a8711Sopenharmony_ci 41a34a8711Sopenharmony_ci/// Ipc MsgParcel 42a34a8711Sopenharmony_cipub struct MsgParcel { 43a34a8711Sopenharmony_ci pub(crate) inner: ParcelMem, 44a34a8711Sopenharmony_ci} 45a34a8711Sopenharmony_ci 46a34a8711Sopenharmony_ciunsafe impl Send for MsgParcel {} 47a34a8711Sopenharmony_ciunsafe impl Send for MsgOption {} 48a34a8711Sopenharmony_ci 49a34a8711Sopenharmony_ciimpl MsgParcel { 50a34a8711Sopenharmony_ci /// Creates a new, empty MsgParcel. 51a34a8711Sopenharmony_ci /// 52a34a8711Sopenharmony_ci /// # Panics 53a34a8711Sopenharmony_ci /// Panics if allocate failed. 54a34a8711Sopenharmony_ci /// 55a34a8711Sopenharmony_ci /// # Examples 56a34a8711Sopenharmony_ci /// ```rust 57a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 58a34a8711Sopenharmony_ci /// 59a34a8711Sopenharmony_ci /// let msg = MsgParcel::new(); 60a34a8711Sopenharmony_ci /// ``` 61a34a8711Sopenharmony_ci pub fn new() -> Self { 62a34a8711Sopenharmony_ci let ptr = NewMessageParcel(); 63a34a8711Sopenharmony_ci assert!(!ptr.is_null(), "memory allocation of MessageParcel failed"); 64a34a8711Sopenharmony_ci Self { 65a34a8711Sopenharmony_ci inner: ParcelMem::Unique(ptr), 66a34a8711Sopenharmony_ci } 67a34a8711Sopenharmony_ci } 68a34a8711Sopenharmony_ci 69a34a8711Sopenharmony_ci /// create MsgParcel from raw ptr 70a34a8711Sopenharmony_ci pub fn from_ptr(ptr: *mut MessageParcel) -> Self { 71a34a8711Sopenharmony_ci Self { 72a34a8711Sopenharmony_ci inner: ParcelMem::Borrow(ptr), 73a34a8711Sopenharmony_ci } 74a34a8711Sopenharmony_ci } 75a34a8711Sopenharmony_ci 76a34a8711Sopenharmony_ci /// into raw ptr 77a34a8711Sopenharmony_ci pub fn into_raw(self) -> *mut MessageParcel { 78a34a8711Sopenharmony_ci match self.inner { 79a34a8711Sopenharmony_ci ParcelMem::Unique(p) => p.into_raw(), 80a34a8711Sopenharmony_ci ParcelMem::Borrow(p) => p, 81a34a8711Sopenharmony_ci ParcelMem::Null => unreachable!(), 82a34a8711Sopenharmony_ci } 83a34a8711Sopenharmony_ci } 84a34a8711Sopenharmony_ci 85a34a8711Sopenharmony_ci /// Writes a [`Serialize`] value into this MsgParcel. 86a34a8711Sopenharmony_ci /// 87a34a8711Sopenharmony_ci /// [Serialize]: crate::parcel::Serialize 88a34a8711Sopenharmony_ci /// 89a34a8711Sopenharmony_ci /// # Example 90a34a8711Sopenharmony_ci /// ``` rust 91a34a8711Sopenharmony_ci /// use ipc::parcel::{MsgParcel, Serialize}; 92a34a8711Sopenharmony_ci /// use ipc::IpcResult; 93a34a8711Sopenharmony_ci /// struct Foo { 94a34a8711Sopenharmony_ci /// a: i32, 95a34a8711Sopenharmony_ci /// } 96a34a8711Sopenharmony_ci /// 97a34a8711Sopenharmony_ci /// impl Serialize for Foo { 98a34a8711Sopenharmony_ci /// fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()> { 99a34a8711Sopenharmony_ci /// parcel.write(&self.a) 100a34a8711Sopenharmony_ci /// } 101a34a8711Sopenharmony_ci /// } 102a34a8711Sopenharmony_ci /// 103a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 104a34a8711Sopenharmony_ci /// msg.write(&Foo { a: 1 }).unwrap(); 105a34a8711Sopenharmony_ci /// assert_eq!(1, msg.read::<i32>().unwrap()); 106a34a8711Sopenharmony_ci /// ``` 107a34a8711Sopenharmony_ci pub fn write<T: Serialize + ?Sized>(&mut self, value: &T) -> IpcResult<()> { 108a34a8711Sopenharmony_ci value.serialize(self) 109a34a8711Sopenharmony_ci } 110a34a8711Sopenharmony_ci 111a34a8711Sopenharmony_ci /// Reads a [`Deserialize`] value out of this MsgParcel. 112a34a8711Sopenharmony_ci /// 113a34a8711Sopenharmony_ci /// [Deserialize]: crate::parcel::Deserialize 114a34a8711Sopenharmony_ci /// 115a34a8711Sopenharmony_ci /// # Example 116a34a8711Sopenharmony_ci /// ```rust 117a34a8711Sopenharmony_ci /// use ipc::parcel::{Deserialize, MsgParcel, Serialize}; 118a34a8711Sopenharmony_ci /// use ipc::IpcResult; 119a34a8711Sopenharmony_ci /// 120a34a8711Sopenharmony_ci /// struct Foo { 121a34a8711Sopenharmony_ci /// a: i32, 122a34a8711Sopenharmony_ci /// } 123a34a8711Sopenharmony_ci /// impl Serialize for Foo { 124a34a8711Sopenharmony_ci /// fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()> { 125a34a8711Sopenharmony_ci /// parcel.write(&self.a) 126a34a8711Sopenharmony_ci /// } 127a34a8711Sopenharmony_ci /// } 128a34a8711Sopenharmony_ci /// impl Deserialize for Foo { 129a34a8711Sopenharmony_ci /// fn deserialize(parcel: &mut MsgParcel) -> IpcResult<Self> { 130a34a8711Sopenharmony_ci /// Ok(Foo { a: parcel.read()? }) 131a34a8711Sopenharmony_ci /// } 132a34a8711Sopenharmony_ci /// } 133a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 134a34a8711Sopenharmony_ci /// msg.write(&Foo { a: 1 }).unwrap(); 135a34a8711Sopenharmony_ci /// let foo = msg.read::<Foo>().unwrap(); 136a34a8711Sopenharmony_ci /// assert_eq!(foo.a, 1); 137a34a8711Sopenharmony_ci /// ``` 138a34a8711Sopenharmony_ci pub fn read<T: Deserialize>(&mut self) -> IpcResult<T> { 139a34a8711Sopenharmony_ci T::deserialize(self) 140a34a8711Sopenharmony_ci } 141a34a8711Sopenharmony_ci 142a34a8711Sopenharmony_ci /// Writes a interface token into this MsgParcel. 143a34a8711Sopenharmony_ci /// 144a34a8711Sopenharmony_ci /// # Example 145a34a8711Sopenharmony_ci /// ```rust 146a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 147a34a8711Sopenharmony_ci /// 148a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 149a34a8711Sopenharmony_ci /// msg.write_interface_token("OHOS.Download.RequestServiceInterface"); 150a34a8711Sopenharmony_ci /// ``` 151a34a8711Sopenharmony_ci pub fn write_interface_token(&mut self, name: &str) -> IpcResult<()> { 152a34a8711Sopenharmony_ci self.write_process(name, WriteInterfaceToken) 153a34a8711Sopenharmony_ci } 154a34a8711Sopenharmony_ci 155a34a8711Sopenharmony_ci /// Reads a interface token from this MsgParcel. 156a34a8711Sopenharmony_ci /// 157a34a8711Sopenharmony_ci /// # Example 158a34a8711Sopenharmony_ci /// ```rust 159a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 160a34a8711Sopenharmony_ci /// 161a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 162a34a8711Sopenharmony_ci /// msg.write_interface_token("OHOS.Download.RequestServiceInterface"); 163a34a8711Sopenharmony_ci /// assert_eq!( 164a34a8711Sopenharmony_ci /// "OHOS.Download.RequestServiceInterface", 165a34a8711Sopenharmony_ci /// msg.read_interface_token().unwrap().as_str(), 166a34a8711Sopenharmony_ci /// ); 167a34a8711Sopenharmony_ci /// ``` 168a34a8711Sopenharmony_ci pub fn read_interface_token(&mut self) -> IpcResult<String> { 169a34a8711Sopenharmony_ci fn read_process(parcel: Pin<&mut MessageParcel>) -> IpcResult<String> { 170a34a8711Sopenharmony_ci Ok(ReadInterfaceToken(parcel)) 171a34a8711Sopenharmony_ci } 172a34a8711Sopenharmony_ci 173a34a8711Sopenharmony_ci self.read_process(read_process) 174a34a8711Sopenharmony_ci } 175a34a8711Sopenharmony_ci 176a34a8711Sopenharmony_ci /// Writes a raw fd from a given file into this MsgParcel. 177a34a8711Sopenharmony_ci /// 178a34a8711Sopenharmony_ci /// ```no_run 179a34a8711Sopenharmony_ci /// use std::fs::File; 180a34a8711Sopenharmony_ci /// use std::io::{Read, Seek, Write}; 181a34a8711Sopenharmony_ci /// 182a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 183a34a8711Sopenharmony_ci /// 184a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 185a34a8711Sopenharmony_ci /// let mut file = std::fs::OpenOptions::new() 186a34a8711Sopenharmony_ci /// .read(true) 187a34a8711Sopenharmony_ci /// .write(true) 188a34a8711Sopenharmony_ci /// .truncate(true) 189a34a8711Sopenharmony_ci /// .open("foo") 190a34a8711Sopenharmony_ci /// .unwrap(); 191a34a8711Sopenharmony_ci /// file.write_all(b"hello world").unwrap(); 192a34a8711Sopenharmony_ci /// msg.write_file(file).unwrap(); 193a34a8711Sopenharmony_ci /// 194a34a8711Sopenharmony_ci /// let mut f = msg.read_file().unwrap(); 195a34a8711Sopenharmony_ci /// let mut buf = String::new(); 196a34a8711Sopenharmony_ci /// f.rewind().unwrap(); 197a34a8711Sopenharmony_ci /// f.read_to_string(&mut buf).unwrap(); 198a34a8711Sopenharmony_ci /// assert_eq!("hello world", buf); 199a34a8711Sopenharmony_ci /// ``` 200a34a8711Sopenharmony_ci pub fn write_file(&mut self, file: File) -> IpcResult<()> { 201a34a8711Sopenharmony_ci let fd = file.into_raw_fd(); 202a34a8711Sopenharmony_ci match self.as_msg_parcel_mut().WriteFileDescriptor(fd) { 203a34a8711Sopenharmony_ci true => Ok(()), 204a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 205a34a8711Sopenharmony_ci } 206a34a8711Sopenharmony_ci } 207a34a8711Sopenharmony_ci 208a34a8711Sopenharmony_ci /// Reads a file out of this MsgParcel, that created from the fd written 209a34a8711Sopenharmony_ci /// before. 210a34a8711Sopenharmony_ci /// 211a34a8711Sopenharmony_ci /// # Examples 212a34a8711Sopenharmony_ci /// ```no_run 213a34a8711Sopenharmony_ci /// use std::fs::File; 214a34a8711Sopenharmony_ci /// use std::io::{Read, Seek, Write}; 215a34a8711Sopenharmony_ci /// 216a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 217a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 218a34a8711Sopenharmony_ci /// let mut file = std::fs::OpenOptions::new() 219a34a8711Sopenharmony_ci /// .read(true) 220a34a8711Sopenharmony_ci /// .write(true) 221a34a8711Sopenharmony_ci /// .truncate(true) 222a34a8711Sopenharmony_ci /// .open("foo") 223a34a8711Sopenharmony_ci /// .unwrap(); 224a34a8711Sopenharmony_ci /// file.write_all(b"hello world").unwrap(); 225a34a8711Sopenharmony_ci /// msg.write_file(file).unwrap(); 226a34a8711Sopenharmony_ci /// 227a34a8711Sopenharmony_ci /// let mut f = msg.read_file().unwrap(); 228a34a8711Sopenharmony_ci /// let mut buf = String::new(); 229a34a8711Sopenharmony_ci /// f.rewind().unwrap(); 230a34a8711Sopenharmony_ci /// f.read_to_string(&mut buf).unwrap(); 231a34a8711Sopenharmony_ci /// assert_eq!("hello world", buf); 232a34a8711Sopenharmony_ci /// ``` 233a34a8711Sopenharmony_ci pub fn read_file(&mut self) -> IpcResult<File> { 234a34a8711Sopenharmony_ci let fd = self.as_msg_parcel_mut().ReadFileDescriptor(); 235a34a8711Sopenharmony_ci unsafe { Ok(File::from_raw_fd(fd)) } 236a34a8711Sopenharmony_ci } 237a34a8711Sopenharmony_ci 238a34a8711Sopenharmony_ci /// Writes a data region (buffer) to this parcel 239a34a8711Sopenharmony_ci /// 240a34a8711Sopenharmony_ci /// # Example 241a34a8711Sopenharmony_ci /// ```rust 242a34a8711Sopenharmony_ci /// use crate::parcel::MsgParcel; 243a34a8711Sopenharmony_ci /// 244a34a8711Sopenharmony_ci /// let msg = MsgParcel::new(); 245a34a8711Sopenharmony_ci /// let data = vec![]; 246a34a8711Sopenharmony_ci /// msg.write_buffer(data.as_bytes); 247a34a8711Sopenharmony_ci /// ``` 248a34a8711Sopenharmony_ci pub fn write_buffer(&mut self, buffer: &[u8]) -> IpcResult<()> { 249a34a8711Sopenharmony_ci match WriteBuffer(self.as_msg_parcel_mut(), buffer) { 250a34a8711Sopenharmony_ci true => Ok(()), 251a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 252a34a8711Sopenharmony_ci } 253a34a8711Sopenharmony_ci } 254a34a8711Sopenharmony_ci 255a34a8711Sopenharmony_ci /// Reads a block of data (buffer data) from this parcel 256a34a8711Sopenharmony_ci /// 257a34a8711Sopenharmony_ci /// # Example 258a34a8711Sopenharmony_ci /// ```rust 259a34a8711Sopenharmony_ci /// use crate::parcel::MsgParcel; 260a34a8711Sopenharmony_ci /// 261a34a8711Sopenharmony_ci /// let msg = MsgParcel::new(); 262a34a8711Sopenharmony_ci /// let data = msg.read_buffer().unwrap(); 263a34a8711Sopenharmony_ci /// ``` 264a34a8711Sopenharmony_ci pub fn read_buffer(&mut self, len: usize) -> IpcResult<Vec<u8>> { 265a34a8711Sopenharmony_ci let pad_size = Self::get_pad_size(len); 266a34a8711Sopenharmony_ci let mut vec = Vec::with_capacity(len + pad_size); 267a34a8711Sopenharmony_ci match ReadBuffer(self.as_msg_parcel_mut(), len + pad_size, &mut vec) { 268a34a8711Sopenharmony_ci true => Ok({ 269a34a8711Sopenharmony_ci unsafe { vec.set_len(len) }; 270a34a8711Sopenharmony_ci vec 271a34a8711Sopenharmony_ci }), 272a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 273a34a8711Sopenharmony_ci } 274a34a8711Sopenharmony_ci } 275a34a8711Sopenharmony_ci 276a34a8711Sopenharmony_ci pub fn write_string16(&mut self, s: &str) -> IpcResult<()> { 277a34a8711Sopenharmony_ci match WriteString16(self.as_parcel_mut(), s) { 278a34a8711Sopenharmony_ci true => Ok(()), 279a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 280a34a8711Sopenharmony_ci } 281a34a8711Sopenharmony_ci } 282a34a8711Sopenharmony_ci 283a34a8711Sopenharmony_ci pub fn read_string16(&mut self) -> IpcResult<String> { 284a34a8711Sopenharmony_ci Ok(ReadString16(self.as_parcel_mut())) 285a34a8711Sopenharmony_ci } 286a34a8711Sopenharmony_ci 287a34a8711Sopenharmony_ci pub fn write_string16_vec(&mut self, s: &[String]) -> IpcResult<()> { 288a34a8711Sopenharmony_ci match WriteString16Vector(self.as_parcel_mut(), s) { 289a34a8711Sopenharmony_ci true => Ok(()), 290a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 291a34a8711Sopenharmony_ci } 292a34a8711Sopenharmony_ci } 293a34a8711Sopenharmony_ci 294a34a8711Sopenharmony_ci pub fn read_string16_vec(&mut self) -> IpcResult<Vec<String>> { 295a34a8711Sopenharmony_ci let mut v = vec![]; 296a34a8711Sopenharmony_ci match ReadString16Vector(self.as_parcel_mut(), &mut v) { 297a34a8711Sopenharmony_ci true => Ok(v), 298a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 299a34a8711Sopenharmony_ci } 300a34a8711Sopenharmony_ci } 301a34a8711Sopenharmony_ci 302a34a8711Sopenharmony_ci /// Writes a RemoteObj into this MsgParcel. 303a34a8711Sopenharmony_ci /// 304a34a8711Sopenharmony_ci /// # Example 305a34a8711Sopenharmony_ci /// ```rust 306a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 307a34a8711Sopenharmony_ci /// use ipc::remote::{RemoteObj, RemoteStub}; 308a34a8711Sopenharmony_ci /// 309a34a8711Sopenharmony_ci /// struct TestRemoteStub; 310a34a8711Sopenharmony_ci /// impl RemoteStub for TestRemoteStub { 311a34a8711Sopenharmony_ci /// fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 { 312a34a8711Sopenharmony_ci /// reply.write("nihao"); 313a34a8711Sopenharmony_ci /// println!("hello"); 314a34a8711Sopenharmony_ci /// 0 315a34a8711Sopenharmony_ci /// } 316a34a8711Sopenharmony_ci /// } 317a34a8711Sopenharmony_ci /// 318a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 319a34a8711Sopenharmony_ci /// msg.write_remote(RemoteObj::from_stub(TestRemoteStub).unwrap()) 320a34a8711Sopenharmony_ci /// .unwrap(); 321a34a8711Sopenharmony_ci /// ``` 322a34a8711Sopenharmony_ci pub fn write_remote(&mut self, remote: RemoteObj) -> IpcResult<()> { 323a34a8711Sopenharmony_ci self.write_process(remote.inner, WriteRemoteObject) 324a34a8711Sopenharmony_ci } 325a34a8711Sopenharmony_ci 326a34a8711Sopenharmony_ci /// Reads a RemoteObj from this MsgParcel. 327a34a8711Sopenharmony_ci /// 328a34a8711Sopenharmony_ci /// # Example 329a34a8711Sopenharmony_ci /// ```rust 330a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 331a34a8711Sopenharmony_ci /// use ipc::remote::{RemoteObj, RemoteStub}; 332a34a8711Sopenharmony_ci /// 333a34a8711Sopenharmony_ci /// struct TestRemoteStub; 334a34a8711Sopenharmony_ci /// impl RemoteStub for TestRemoteStub { 335a34a8711Sopenharmony_ci /// fn on_remote_request(&self, code: u32, data: &mut MsgParcel, reply: &mut MsgParcel) -> i32 { 336a34a8711Sopenharmony_ci /// reply.write("nihao"); 337a34a8711Sopenharmony_ci /// println!("hello"); 338a34a8711Sopenharmony_ci /// 0 339a34a8711Sopenharmony_ci /// } 340a34a8711Sopenharmony_ci /// } 341a34a8711Sopenharmony_ci /// 342a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 343a34a8711Sopenharmony_ci /// msg.write_remote(RemoteObj::from_stub(TestRemoteStub).unwrap()) 344a34a8711Sopenharmony_ci /// .unwrap(); 345a34a8711Sopenharmony_ci /// let remote = msg.read_remote().unwrap(); 346a34a8711Sopenharmony_ci /// ``` 347a34a8711Sopenharmony_ci pub fn read_remote(&mut self) -> IpcResult<RemoteObj> { 348a34a8711Sopenharmony_ci fn read_remote_process( 349a34a8711Sopenharmony_ci parcel: Pin<&mut MessageParcel>, 350a34a8711Sopenharmony_ci ) -> IpcResult<UniquePtr<IRemoteObjectWrapper>> { 351a34a8711Sopenharmony_ci let remote = ReadRemoteObject(parcel); 352a34a8711Sopenharmony_ci if remote.is_null() { 353a34a8711Sopenharmony_ci Err(IpcStatusCode::Failed) 354a34a8711Sopenharmony_ci } else { 355a34a8711Sopenharmony_ci Ok(remote) 356a34a8711Sopenharmony_ci } 357a34a8711Sopenharmony_ci } 358a34a8711Sopenharmony_ci 359a34a8711Sopenharmony_ci self.read_process(read_remote_process) 360a34a8711Sopenharmony_ci .map(|remote| unsafe { RemoteObj::new_unchecked(remote) }) 361a34a8711Sopenharmony_ci } 362a34a8711Sopenharmony_ci 363a34a8711Sopenharmony_ci /// Returns the size that this MsgParcel has written in bytes. 364a34a8711Sopenharmony_ci /// 365a34a8711Sopenharmony_ci /// # Example 366a34a8711Sopenharmony_ci /// ```rust 367a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 368a34a8711Sopenharmony_ci /// 369a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 370a34a8711Sopenharmony_ci /// msg.write(&1i32); 371a34a8711Sopenharmony_ci /// assert_eq!(msg.size(), 4); 372a34a8711Sopenharmony_ci /// ``` 373a34a8711Sopenharmony_ci pub fn size(&self) -> usize { 374a34a8711Sopenharmony_ci self.as_parcel().GetDataSize() 375a34a8711Sopenharmony_ci } 376a34a8711Sopenharmony_ci 377a34a8711Sopenharmony_ci /// Returns the remaining writable size in bytes before reallocating. 378a34a8711Sopenharmony_ci /// 379a34a8711Sopenharmony_ci /// # Example 380a34a8711Sopenharmony_ci /// ```rust 381a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 382a34a8711Sopenharmony_ci /// 383a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 384a34a8711Sopenharmony_ci /// assert_eq!(0, msg.writable()); 385a34a8711Sopenharmony_ci /// msg.write(&1i32); 386a34a8711Sopenharmony_ci /// assert_eq!(60, msg.writable()); 387a34a8711Sopenharmony_ci /// ``` 388a34a8711Sopenharmony_ci pub fn writable(&self) -> usize { 389a34a8711Sopenharmony_ci self.as_parcel().GetWritableBytes() 390a34a8711Sopenharmony_ci } 391a34a8711Sopenharmony_ci 392a34a8711Sopenharmony_ci /// Returns the remaining readable size in bytes. 393a34a8711Sopenharmony_ci /// 394a34a8711Sopenharmony_ci /// # Example 395a34a8711Sopenharmony_ci /// ```rust 396a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 397a34a8711Sopenharmony_ci /// 398a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 399a34a8711Sopenharmony_ci /// msg.write(&1i32); 400a34a8711Sopenharmony_ci /// assert_eq!(4, msg.readable() as u32); 401a34a8711Sopenharmony_ci /// ``` 402a34a8711Sopenharmony_ci pub fn readable(&self) -> usize { 403a34a8711Sopenharmony_ci self.as_parcel().GetReadableBytes() 404a34a8711Sopenharmony_ci } 405a34a8711Sopenharmony_ci 406a34a8711Sopenharmony_ci /// Returns the offset size in bytes. 407a34a8711Sopenharmony_ci /// 408a34a8711Sopenharmony_ci /// # Example 409a34a8711Sopenharmony_ci /// ```rust 410a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 411a34a8711Sopenharmony_ci /// let msg = MsgParcel::new(); 412a34a8711Sopenharmony_ci /// ``` 413a34a8711Sopenharmony_ci pub fn offset(&self) -> usize { 414a34a8711Sopenharmony_ci self.as_parcel().GetOffsetsSize() 415a34a8711Sopenharmony_ci } 416a34a8711Sopenharmony_ci 417a34a8711Sopenharmony_ci /// Returns the total bytes the MsgParcel can hold without reallocating. 418a34a8711Sopenharmony_ci /// 419a34a8711Sopenharmony_ci /// # Example 420a34a8711Sopenharmony_ci /// ```rust 421a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 422a34a8711Sopenharmony_ci /// 423a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 424a34a8711Sopenharmony_ci /// assert_eq!(0, msg.capacity()); 425a34a8711Sopenharmony_ci /// msg.write(&1i32); 426a34a8711Sopenharmony_ci /// assert_eq!(64, msg.capacity()); 427a34a8711Sopenharmony_ci /// ``` 428a34a8711Sopenharmony_ci pub fn capacity(&self) -> usize { 429a34a8711Sopenharmony_ci self.as_parcel().GetDataCapacity() 430a34a8711Sopenharmony_ci } 431a34a8711Sopenharmony_ci 432a34a8711Sopenharmony_ci /// Returns the maximum capacity MsgParcel can allocate. 433a34a8711Sopenharmony_ci /// 434a34a8711Sopenharmony_ci /// # Example 435a34a8711Sopenharmony_ci /// ```rust 436a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 437a34a8711Sopenharmony_ci /// 438a34a8711Sopenharmony_ci /// let msg = MsgParcel::new(); 439a34a8711Sopenharmony_ci /// assert_eq!(204800, msg.max_capacity()); 440a34a8711Sopenharmony_ci /// ``` 441a34a8711Sopenharmony_ci pub fn max_capacity(&self) -> usize { 442a34a8711Sopenharmony_ci self.as_parcel().GetMaxCapacity() 443a34a8711Sopenharmony_ci } 444a34a8711Sopenharmony_ci 445a34a8711Sopenharmony_ci /// Returns the write_position of the MsgPacel in bytes. 446a34a8711Sopenharmony_ci /// 447a34a8711Sopenharmony_ci /// # Example 448a34a8711Sopenharmony_ci /// ```rust 449a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 450a34a8711Sopenharmony_ci /// 451a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 452a34a8711Sopenharmony_ci /// assert_eq!(0, msg.write_position()); 453a34a8711Sopenharmony_ci /// msg.write(&1i32).unwrap(); 454a34a8711Sopenharmony_ci /// assert_eq!(4, msg.write_position()); 455a34a8711Sopenharmony_ci /// ``` 456a34a8711Sopenharmony_ci pub fn write_position(&mut self) -> usize { 457a34a8711Sopenharmony_ci self.as_parcel_mut().GetWritePosition() 458a34a8711Sopenharmony_ci } 459a34a8711Sopenharmony_ci 460a34a8711Sopenharmony_ci /// Returns the read_position of the MsgParcel in bytes. 461a34a8711Sopenharmony_ci /// 462a34a8711Sopenharmony_ci /// # Example 463a34a8711Sopenharmony_ci /// ```rust 464a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 465a34a8711Sopenharmony_ci /// 466a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 467a34a8711Sopenharmony_ci /// assert_eq!(0, msg.read_position()); 468a34a8711Sopenharmony_ci /// msg.write(&1i32).unwrap(); 469a34a8711Sopenharmony_ci /// assert_eq!(0, msg.read_position()); 470a34a8711Sopenharmony_ci /// msg.read::<i32>().unwrap(); 471a34a8711Sopenharmony_ci /// assert_eq!(4, msg.read_position()); 472a34a8711Sopenharmony_ci /// ``` 473a34a8711Sopenharmony_ci pub fn read_position(&mut self) -> usize { 474a34a8711Sopenharmony_ci self.as_parcel_mut().GetReadPosition() 475a34a8711Sopenharmony_ci } 476a34a8711Sopenharmony_ci 477a34a8711Sopenharmony_ci /// Changes the size of the MsgParcel. 478a34a8711Sopenharmony_ci /// 479a34a8711Sopenharmony_ci /// # Errors 480a34a8711Sopenharmony_ci /// If new data size > capacity, set will fail. 481a34a8711Sopenharmony_ci /// 482a34a8711Sopenharmony_ci /// # Example 483a34a8711Sopenharmony_ci /// ```rust 484a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 485a34a8711Sopenharmony_ci /// 486a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 487a34a8711Sopenharmony_ci /// msg.write(&1i32); 488a34a8711Sopenharmony_ci /// assert_eq!(4, msg.size()); 489a34a8711Sopenharmony_ci /// msg.set_size(0); 490a34a8711Sopenharmony_ci /// assert_eq!(0, msg.size()); 491a34a8711Sopenharmony_ci /// ``` 492a34a8711Sopenharmony_ci pub fn set_size(&mut self, size: usize) -> Result<(), ParcelSetError> { 493a34a8711Sopenharmony_ci if self.as_parcel_mut().SetDataSize(size) { 494a34a8711Sopenharmony_ci Ok(()) 495a34a8711Sopenharmony_ci } else { 496a34a8711Sopenharmony_ci Err(ParcelSetError) 497a34a8711Sopenharmony_ci } 498a34a8711Sopenharmony_ci } 499a34a8711Sopenharmony_ci 500a34a8711Sopenharmony_ci /// Changes the capacity of the MsgParcel. 501a34a8711Sopenharmony_ci /// 502a34a8711Sopenharmony_ci /// # Errors 503a34a8711Sopenharmony_ci /// If data size > new capacity bytes, set will fail. 504a34a8711Sopenharmony_ci /// 505a34a8711Sopenharmony_ci /// # Example 506a34a8711Sopenharmony_ci /// ```rust 507a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 508a34a8711Sopenharmony_ci /// 509a34a8711Sopenharmony_ci /// let msg = MsgParcel::new(); 510a34a8711Sopenharmony_ci /// msg.set_capacity(64).unwrap(); 511a34a8711Sopenharmony_ci /// assert_eq!(64, msg.capacity()); 512a34a8711Sopenharmony_ci /// ``` 513a34a8711Sopenharmony_ci pub fn set_capacity(&mut self, size: usize) -> Result<(), ParcelSetError> { 514a34a8711Sopenharmony_ci if self.as_parcel_mut().SetDataCapacity(size) { 515a34a8711Sopenharmony_ci Ok(()) 516a34a8711Sopenharmony_ci } else { 517a34a8711Sopenharmony_ci Err(ParcelSetError) 518a34a8711Sopenharmony_ci } 519a34a8711Sopenharmony_ci } 520a34a8711Sopenharmony_ci 521a34a8711Sopenharmony_ci /// Changes the capacity of the MsgParcel. 522a34a8711Sopenharmony_ci /// 523a34a8711Sopenharmony_ci /// # Errors 524a34a8711Sopenharmony_ci /// If new max capacity reach the limit, set will fail. 525a34a8711Sopenharmony_ci /// 526a34a8711Sopenharmony_ci /// # Example 527a34a8711Sopenharmony_ci /// ```rust 528a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 529a34a8711Sopenharmony_ci /// 530a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 531a34a8711Sopenharmony_ci /// msg.set_max_capacity(64).unwrap(); 532a34a8711Sopenharmony_ci /// ``` 533a34a8711Sopenharmony_ci pub fn set_max_capacity(&mut self, size: usize) -> Result<(), ParcelSetError> { 534a34a8711Sopenharmony_ci if self.as_parcel_mut().SetMaxCapacity(size) { 535a34a8711Sopenharmony_ci Ok(()) 536a34a8711Sopenharmony_ci } else { 537a34a8711Sopenharmony_ci Err(ParcelSetError) 538a34a8711Sopenharmony_ci } 539a34a8711Sopenharmony_ci } 540a34a8711Sopenharmony_ci 541a34a8711Sopenharmony_ci /// Changes the read position of the MsgParcel. 542a34a8711Sopenharmony_ci /// 543a34a8711Sopenharmony_ci /// # Errors 544a34a8711Sopenharmony_ci /// If new position > data size, set will fail. 545a34a8711Sopenharmony_ci /// 546a34a8711Sopenharmony_ci /// # Example 547a34a8711Sopenharmony_ci /// ```rust 548a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 549a34a8711Sopenharmony_ci /// 550a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 551a34a8711Sopenharmony_ci /// msg.write(&1i32).unwrap(); 552a34a8711Sopenharmony_ci /// msg.write(&2i32).unwrap(); 553a34a8711Sopenharmony_ci /// msg.set_read_position(4).unwrap(); 554a34a8711Sopenharmony_ci /// assert_eq!(2, msg.read().unwrap()); 555a34a8711Sopenharmony_ci /// ``` 556a34a8711Sopenharmony_ci pub fn set_read_position(&mut self, size: usize) -> Result<(), ParcelSetError> { 557a34a8711Sopenharmony_ci if self.as_parcel_mut().RewindRead(size) { 558a34a8711Sopenharmony_ci Ok(()) 559a34a8711Sopenharmony_ci } else { 560a34a8711Sopenharmony_ci Err(ParcelSetError) 561a34a8711Sopenharmony_ci } 562a34a8711Sopenharmony_ci } 563a34a8711Sopenharmony_ci 564a34a8711Sopenharmony_ci /// Changes the write position of the MsgParcel. 565a34a8711Sopenharmony_ci /// 566a34a8711Sopenharmony_ci /// # Errors 567a34a8711Sopenharmony_ci /// if new position > data size, set will fail 568a34a8711Sopenharmony_ci /// 569a34a8711Sopenharmony_ci /// # Example 570a34a8711Sopenharmony_ci /// ```rust 571a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 572a34a8711Sopenharmony_ci /// 573a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 574a34a8711Sopenharmony_ci /// msg.write(&1i32).unwrap(); 575a34a8711Sopenharmony_ci /// msg.write(&2i32).unwrap(); 576a34a8711Sopenharmony_ci /// msg.set_write_position(0); 577a34a8711Sopenharmony_ci /// msg.write(&2i32).unwrap(); 578a34a8711Sopenharmony_ci /// assert_eq(2, msg.read().unwrap()); 579a34a8711Sopenharmony_ci /// ``` 580a34a8711Sopenharmony_ci pub fn set_write_position(&mut self, size: usize) -> Result<(), ParcelSetError> { 581a34a8711Sopenharmony_ci if self.as_parcel_mut().RewindWrite(size) { 582a34a8711Sopenharmony_ci Ok(()) 583a34a8711Sopenharmony_ci } else { 584a34a8711Sopenharmony_ci Err(ParcelSetError) 585a34a8711Sopenharmony_ci } 586a34a8711Sopenharmony_ci } 587a34a8711Sopenharmony_ci 588a34a8711Sopenharmony_ci /// Skip read data in bytes of the MsgParcel 589a34a8711Sopenharmony_ci /// 590a34a8711Sopenharmony_ci /// # Errors 591a34a8711Sopenharmony_ci /// if skip size > readable data the the read position will be the capacity. 592a34a8711Sopenharmony_ci /// 593a34a8711Sopenharmony_ci /// # Examples 594a34a8711Sopenharmony_ci /// ```rust 595a34a8711Sopenharmony_ci /// use ipc::parcel::MsgParcel; 596a34a8711Sopenharmony_ci /// 597a34a8711Sopenharmony_ci /// let mut msg = MsgParcel::new(); 598a34a8711Sopenharmony_ci /// msg.write(&1i32).unwrap(); 599a34a8711Sopenharmony_ci /// msg.write(&2i32).unwrap(); 600a34a8711Sopenharmony_ci /// msg.skip_read(4); 601a34a8711Sopenharmony_ci /// assert_eq!(2, msg.read().unwrap()); 602a34a8711Sopenharmony_ci /// ``` 603a34a8711Sopenharmony_ci pub fn skip_read(&mut self, size: usize) { 604a34a8711Sopenharmony_ci self.as_parcel_mut().SkipBytes(size) 605a34a8711Sopenharmony_ci } 606a34a8711Sopenharmony_ci 607a34a8711Sopenharmony_ci fn as_msg_parcel_mut(&mut self) -> Pin<&mut MessageParcel> { 608a34a8711Sopenharmony_ci match &mut self.inner { 609a34a8711Sopenharmony_ci ParcelMem::Unique(p) => p.pin_mut(), 610a34a8711Sopenharmony_ci ParcelMem::Borrow(p) => unsafe { Pin::new_unchecked(&mut **p) }, 611a34a8711Sopenharmony_ci _ => unreachable!(), 612a34a8711Sopenharmony_ci } 613a34a8711Sopenharmony_ci } 614a34a8711Sopenharmony_ci 615a34a8711Sopenharmony_ci fn as_parcel(&self) -> &Parcel { 616a34a8711Sopenharmony_ci match &self.inner { 617a34a8711Sopenharmony_ci ParcelMem::Unique(p) => unsafe { 618a34a8711Sopenharmony_ci let parcel = AsParcel(p.as_ref().unwrap()); 619a34a8711Sopenharmony_ci &*parcel 620a34a8711Sopenharmony_ci }, 621a34a8711Sopenharmony_ci ParcelMem::Borrow(p) => unsafe { 622a34a8711Sopenharmony_ci let parcel = AsParcel(&**p); 623a34a8711Sopenharmony_ci &*parcel 624a34a8711Sopenharmony_ci }, 625a34a8711Sopenharmony_ci _ => unreachable!(), 626a34a8711Sopenharmony_ci } 627a34a8711Sopenharmony_ci } 628a34a8711Sopenharmony_ci 629a34a8711Sopenharmony_ci pub(crate) fn as_parcel_mut(&mut self) -> Pin<&mut Parcel> { 630a34a8711Sopenharmony_ci match &mut self.inner { 631a34a8711Sopenharmony_ci ParcelMem::Unique(p) => unsafe { 632a34a8711Sopenharmony_ci let parcel = AsParcelMut(p.pin_mut()); 633a34a8711Sopenharmony_ci Pin::new_unchecked(&mut *parcel) 634a34a8711Sopenharmony_ci }, 635a34a8711Sopenharmony_ci ParcelMem::Borrow(p) => unsafe { 636a34a8711Sopenharmony_ci let parcel = AsParcelMut(Pin::new_unchecked(&mut **p)); 637a34a8711Sopenharmony_ci Pin::new_unchecked(&mut *parcel) 638a34a8711Sopenharmony_ci }, 639a34a8711Sopenharmony_ci _ => unreachable!(), 640a34a8711Sopenharmony_ci } 641a34a8711Sopenharmony_ci } 642a34a8711Sopenharmony_ci 643a34a8711Sopenharmony_ci pub(crate) fn write_process<T>( 644a34a8711Sopenharmony_ci &mut self, 645a34a8711Sopenharmony_ci value: T, 646a34a8711Sopenharmony_ci f: fn(parcel: Pin<&mut MessageParcel>, value: T) -> bool, 647a34a8711Sopenharmony_ci ) -> IpcResult<()> { 648a34a8711Sopenharmony_ci match mem::replace(&mut self.inner, ParcelMem::Null) { 649a34a8711Sopenharmony_ci ParcelMem::Unique(mut p) => { 650a34a8711Sopenharmony_ci let res = f(p.pin_mut(), value); 651a34a8711Sopenharmony_ci self.inner = ParcelMem::Unique(p); 652a34a8711Sopenharmony_ci match res { 653a34a8711Sopenharmony_ci true => Ok(()), 654a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 655a34a8711Sopenharmony_ci } 656a34a8711Sopenharmony_ci } 657a34a8711Sopenharmony_ci ParcelMem::Borrow(p) => { 658a34a8711Sopenharmony_ci let w = unsafe { Pin::new_unchecked(&mut *p) }; 659a34a8711Sopenharmony_ci let res = f(w, value); 660a34a8711Sopenharmony_ci self.inner = ParcelMem::Borrow(p); 661a34a8711Sopenharmony_ci match res { 662a34a8711Sopenharmony_ci true => Ok(()), 663a34a8711Sopenharmony_ci false => Err(IpcStatusCode::Failed), 664a34a8711Sopenharmony_ci } 665a34a8711Sopenharmony_ci } 666a34a8711Sopenharmony_ci ParcelMem::Null => IpcResult::Err(IpcStatusCode::Failed), 667a34a8711Sopenharmony_ci } 668a34a8711Sopenharmony_ci } 669a34a8711Sopenharmony_ci 670a34a8711Sopenharmony_ci pub(crate) fn read_process<T>( 671a34a8711Sopenharmony_ci &mut self, 672a34a8711Sopenharmony_ci f: fn(parcel: Pin<&mut MessageParcel>) -> IpcResult<T>, 673a34a8711Sopenharmony_ci ) -> IpcResult<T> { 674a34a8711Sopenharmony_ci match mem::replace(&mut self.inner, ParcelMem::Null) { 675a34a8711Sopenharmony_ci ParcelMem::Unique(mut p) => { 676a34a8711Sopenharmony_ci let res = f(p.pin_mut()); 677a34a8711Sopenharmony_ci self.inner = ParcelMem::Unique(p); 678a34a8711Sopenharmony_ci res 679a34a8711Sopenharmony_ci } 680a34a8711Sopenharmony_ci ParcelMem::Borrow(p) => { 681a34a8711Sopenharmony_ci let w = unsafe { Pin::new_unchecked(&mut *p) }; 682a34a8711Sopenharmony_ci let res = f(w); 683a34a8711Sopenharmony_ci self.inner = ParcelMem::Borrow(p); 684a34a8711Sopenharmony_ci res 685a34a8711Sopenharmony_ci } 686a34a8711Sopenharmony_ci ParcelMem::Null => IpcResult::Err(IpcStatusCode::Failed), 687a34a8711Sopenharmony_ci } 688a34a8711Sopenharmony_ci } 689a34a8711Sopenharmony_ci 690a34a8711Sopenharmony_ci pub fn pin_mut(&mut self) -> Option<Pin<&mut MessageParcel>> { 691a34a8711Sopenharmony_ci match &mut self.inner { 692a34a8711Sopenharmony_ci ParcelMem::Unique(p) => Some(p.pin_mut()), 693a34a8711Sopenharmony_ci _ => None, 694a34a8711Sopenharmony_ci } 695a34a8711Sopenharmony_ci } 696a34a8711Sopenharmony_ci 697a34a8711Sopenharmony_ci fn get_pad_size(size: usize) -> usize { 698a34a8711Sopenharmony_ci const SIZE_OFFSET: usize = 3; 699a34a8711Sopenharmony_ci ((size + SIZE_OFFSET) & (!SIZE_OFFSET)) - size 700a34a8711Sopenharmony_ci } 701a34a8711Sopenharmony_ci} 702a34a8711Sopenharmony_ci 703a34a8711Sopenharmony_ci/// Ipc MsgOption used when send request, including some settings. 704a34a8711Sopenharmony_cipub struct MsgOption { 705a34a8711Sopenharmony_ci pub(crate) inner: UniquePtr<MessageOption>, 706a34a8711Sopenharmony_ci} 707a34a8711Sopenharmony_ci 708a34a8711Sopenharmony_ciimpl MsgOption { 709a34a8711Sopenharmony_ci const TF_SYNC: i32 = 0x00; 710a34a8711Sopenharmony_ci const TF_ASYNC: i32 = 0x01; 711a34a8711Sopenharmony_ci 712a34a8711Sopenharmony_ci /// Creates a new, empty MsgOption. 713a34a8711Sopenharmony_ci 714a34a8711Sopenharmony_ci /// # Panics 715a34a8711Sopenharmony_ci /// Panics if allocate failed. 716a34a8711Sopenharmony_ci /// 717a34a8711Sopenharmony_ci /// # Examples 718a34a8711Sopenharmony_ci /// ```rust 719a34a8711Sopenharmony_ci /// use ipc::parcel::MsgOption; 720a34a8711Sopenharmony_ci /// 721a34a8711Sopenharmony_ci /// let msg = MsgOption::new(); 722a34a8711Sopenharmony_ci /// ``` 723a34a8711Sopenharmony_ci pub fn new() -> Self { 724a34a8711Sopenharmony_ci let ptr = NewMessageOption(); 725a34a8711Sopenharmony_ci assert!(!ptr.is_null(), "memory allocation of MessageOption failed"); 726a34a8711Sopenharmony_ci 727a34a8711Sopenharmony_ci Self { 728a34a8711Sopenharmony_ci inner: NewMessageOption(), 729a34a8711Sopenharmony_ci } 730a34a8711Sopenharmony_ci } 731a34a8711Sopenharmony_ci 732a34a8711Sopenharmony_ci /// Set send to be async. 733a34a8711Sopenharmony_ci pub fn set_async(&mut self) { 734a34a8711Sopenharmony_ci self.inner.pin_mut().SetFlags(Self::TF_ASYNC); 735a34a8711Sopenharmony_ci } 736a34a8711Sopenharmony_ci 737a34a8711Sopenharmony_ci /// Sets send to be sync. 738a34a8711Sopenharmony_ci pub fn set_sync(&mut self) { 739a34a8711Sopenharmony_ci self.inner.pin_mut().SetFlags(Self::TF_SYNC); 740a34a8711Sopenharmony_ci } 741a34a8711Sopenharmony_ci 742a34a8711Sopenharmony_ci /// Return true if has set to async. 743a34a8711Sopenharmony_ci pub fn is_async(&self) -> bool { 744a34a8711Sopenharmony_ci self.inner.GetFlags() == Self::TF_ASYNC 745a34a8711Sopenharmony_ci } 746a34a8711Sopenharmony_ci} 747a34a8711Sopenharmony_ci 748a34a8711Sopenharmony_ciimpl Default for MsgParcel { 749a34a8711Sopenharmony_ci fn default() -> Self { 750a34a8711Sopenharmony_ci Self::new() 751a34a8711Sopenharmony_ci } 752a34a8711Sopenharmony_ci} 753a34a8711Sopenharmony_ci 754a34a8711Sopenharmony_ciimpl Default for MsgOption { 755a34a8711Sopenharmony_ci fn default() -> Self { 756a34a8711Sopenharmony_ci Self::new() 757a34a8711Sopenharmony_ci } 758a34a8711Sopenharmony_ci} 759a34a8711Sopenharmony_ci 760a34a8711Sopenharmony_ci#[cfg(test)] 761a34a8711Sopenharmony_cimod test { 762a34a8711Sopenharmony_ci use std::mem; 763a34a8711Sopenharmony_ci 764a34a8711Sopenharmony_ci use super::MsgParcel; 765a34a8711Sopenharmony_ci 766a34a8711Sopenharmony_ci /// UT test cases for `GetDataSize` 767a34a8711Sopenharmony_ci /// 768a34a8711Sopenharmony_ci /// # Brief 769a34a8711Sopenharmony_ci /// 1. Creates a MsgParcel 770a34a8711Sopenharmony_ci /// 2. Writes a value to the MsgParcel and then check its data size. 771a34a8711Sopenharmony_ci #[test] 772a34a8711Sopenharmony_ci fn parcel_size() { 773a34a8711Sopenharmony_ci let mut msg = MsgParcel::new(); 774a34a8711Sopenharmony_ci let mut size = 0; 775a34a8711Sopenharmony_ci 776a34a8711Sopenharmony_ci msg.write(&1i8).unwrap(); 777a34a8711Sopenharmony_ci size += mem::size_of::<i32>(); 778a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 779a34a8711Sopenharmony_ci 780a34a8711Sopenharmony_ci msg.write(&1i16).unwrap(); 781a34a8711Sopenharmony_ci size += mem::size_of::<i32>(); 782a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 783a34a8711Sopenharmony_ci 784a34a8711Sopenharmony_ci msg.write(&1i32).unwrap(); 785a34a8711Sopenharmony_ci size += mem::size_of::<i32>(); 786a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 787a34a8711Sopenharmony_ci 788a34a8711Sopenharmony_ci msg.write(&1i64).unwrap(); 789a34a8711Sopenharmony_ci size += mem::size_of::<i64>(); 790a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 791a34a8711Sopenharmony_ci 792a34a8711Sopenharmony_ci msg.write(&1u8).unwrap(); 793a34a8711Sopenharmony_ci size += mem::size_of::<u32>(); 794a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 795a34a8711Sopenharmony_ci 796a34a8711Sopenharmony_ci msg.write(&1u16).unwrap(); 797a34a8711Sopenharmony_ci size += mem::size_of::<u32>(); 798a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 799a34a8711Sopenharmony_ci 800a34a8711Sopenharmony_ci msg.write(&1u32).unwrap(); 801a34a8711Sopenharmony_ci size += mem::size_of::<u32>(); 802a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 803a34a8711Sopenharmony_ci 804a34a8711Sopenharmony_ci msg.write(&1u64).unwrap(); 805a34a8711Sopenharmony_ci size += mem::size_of::<u64>(); 806a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 807a34a8711Sopenharmony_ci 808a34a8711Sopenharmony_ci msg.write(&true).unwrap(); 809a34a8711Sopenharmony_ci size += mem::size_of::<i32>(); 810a34a8711Sopenharmony_ci assert_eq!(size, msg.size()); 811a34a8711Sopenharmony_ci } 812a34a8711Sopenharmony_ci 813a34a8711Sopenharmony_ci /// UT test cases for read_to_end 814a34a8711Sopenharmony_ci /// 815a34a8711Sopenharmony_ci /// # Brief 816a34a8711Sopenharmony_ci /// 1. Creates a new MsgParcel. 817a34a8711Sopenharmony_ci /// 3. Write a bool and read it out. 818a34a8711Sopenharmony_ci /// 2. write a vector into this MsgParcel, and read_to_end check the 819a34a8711Sopenharmony_ci /// correctness. 820a34a8711Sopenharmony_ci #[test] 821a34a8711Sopenharmony_ci fn read_to_end() { 822a34a8711Sopenharmony_ci let mut msg = MsgParcel::new(); 823a34a8711Sopenharmony_ci msg.write(&true).unwrap(); 824a34a8711Sopenharmony_ci msg.read::<bool>().unwrap(); 825a34a8711Sopenharmony_ci 826a34a8711Sopenharmony_ci msg.write(&vec![1, 2, 3]).unwrap(); 827a34a8711Sopenharmony_ci assert_eq!( 828a34a8711Sopenharmony_ci vec![3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 829a34a8711Sopenharmony_ci msg.read_buffer(msg.readable()).unwrap() 830a34a8711Sopenharmony_ci ); 831a34a8711Sopenharmony_ci } 832a34a8711Sopenharmony_ci} 833