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