提交 ec4514fb 编写于 作者: C chenchong_666

test:Add read and write Ashmem functions and add test cases

Signed-off-by: Nchenchong_666 <chenchong57@huawei.com>
上级 40d8cb6a
......@@ -13,9 +13,13 @@
* limitations under the License.
*/
use crate::{ipc_binding, RawData, Result};
use crate::{
ipc_binding, RawData, Result, BorrowedMsgParcel, result_status,
AsRawPtr
};
use crate::ipc_binding::CAshmem;
use std::ffi::CString;
use crate::parcel::parcelable::{Serialize, Deserialize};
/// Ashmem packed the native CAshmem
#[repr(C)]
......@@ -44,6 +48,16 @@ impl Ashmem {
pub unsafe fn as_inner(&self) -> *mut CAshmem {
self.0
}
/// Create an `Ashmem` wrapper object from a raw `CAshmem` pointer.
/// # Safety
pub unsafe fn from_raw(cashmem: *mut CAshmem) -> Option<Self> {
if cashmem.is_null() {
None
} else {
Some(Self(cashmem))
}
}
}
/// Memory protection for mmap() PROT_NONE
......@@ -174,4 +188,33 @@ impl Drop for Ashmem {
ipc_binding::CAshmemDecStrongRef(self.as_inner());
}
}
}
/// Write a ashmem
impl Serialize for Ashmem {
fn serialize(&self, parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
// SAFETY:
let ret = unsafe {
ipc_binding::CParcelWriteAshmem(parcel.as_mut_raw(), self.as_inner())
};
result_status::<()>(ret, ())
}
}
/// read a ashmem
impl Deserialize for Ashmem {
fn deserialize(parcel: &BorrowedMsgParcel<'_>) -> Result<Self> {
let ptr = unsafe {
ipc_binding::CParcelReadAshmem(parcel.as_raw())
};
if ptr.is_null() {
Err(-1)
} else {
// SAFETY:
unsafe {
let ashmem = Ashmem::from_raw(ptr).unwrap();
Ok(ashmem)
}
}
}
}
\ No newline at end of file
......@@ -216,6 +216,9 @@ extern "C" {
pub fn CParcelGetWritePosition(parcel: *const CParcel) -> u32;
pub fn CParcelRewindRead(parcel: *mut CParcel, new_pos: u32) -> bool;
pub fn CParcelRewindWrite(parcel: *mut CParcel, new_pos: u32) -> bool;
pub fn CParcelWriteAshmem(parcel: *mut CParcel, ashmem: *mut CAshmem) -> bool;
pub fn CParcelReadAshmem(parcel: *const CParcel) -> *mut CAshmem;
}
// C interface for Ashmem
......
......@@ -26,7 +26,6 @@ use std::slice;
use crate::AsRawPtr;
use crate::parcel::parcelable::{Serialize, Deserialize};
/// This trait implements the common function for MsgParcel
/// and BorrowedMsgParcel
pub trait IMsgParcel: AsRawPtr<CParcel> {
......
......@@ -16,6 +16,8 @@
#ifndef IPC_C_PARCEL_H
#define IPC_C_PARCEL_H
#include "c_ashmem.h"
#ifdef __cplusplus
extern "C" {
#endif
......@@ -115,6 +117,9 @@ uint32_t CParcelGetWritePosition(const CParcel *parcel);
bool CParcelRewindRead(CParcel *parcel, uint32_t new_pos);
bool CParcelRewindWrite(CParcel *parcel, uint32_t new_pos);
bool CParcelWriteAshmem(CParcel *parcel, CAshmem *ashmem);
CAshmem *CParcelReadAshmem(const CParcel *parcel);
#ifdef __cplusplus
}
#endif
......
......@@ -17,6 +17,7 @@
#define IPC_C_PARCEL_INTERANL_H
#include "c_parcel.h"
#include "c_ashmem_internal.h"
#include <refbase.h>
#include "message_parcel.h"
......
......@@ -111,7 +111,7 @@ void UnmapCAshmem(CAshmem *ashmem)
if (!IsValidCAshmem(ashmem, __func__)) {
return;
}
ashmem->ashmem_->MapReadOnlyAshmem();
ashmem->ashmem_->UnmapAshmem();
}
bool SetCAshmemProtection(CAshmem *ashmem, int32_t protectionType)
......
......@@ -84,7 +84,7 @@ static bool ReadAndCheckArrayLength(const CParcel *parcel, int32_t &len)
if (static_cast<uint32_t>(len) > parcel->parcel_->GetReadableBytes()) {
printf("%s: readable bytes are too short in parcel: %d\n", __func__, len);
return false;
}
}
return true;
}
......@@ -827,3 +827,30 @@ bool CParcelRewindWrite(CParcel *parcel, uint32_t new_pos)
}
return parcel->parcel_->RewindWrite(new_pos);
}
bool CParcelWriteAshmem(CParcel *parcel, CAshmem *ashmem)
{
if (!IsValidParcel(parcel, __func__)) {
return false;
}
return parcel->parcel_->WriteAshmem(ashmem->ashmem_);
}
CAshmem *CParcelReadAshmem(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
return nullptr;
}
sptr<Ashmem> ashmem = parcel->parcel_->ReadAshmem();
if (ashmem == nullptr) {
printf("%s: read ashmem failed\n", __func__);
return nullptr;
}
CAshmem *cashmem = new (std::nothrow) CAshmem(ashmem);
if (cashmem == nullptr) {
printf("%s: new ashmem failed\n", __func__);
return nullptr;
}
ashmem->IncStrongRef(nullptr);
return cashmem;
}
\ No newline at end of file
......@@ -26,7 +26,7 @@ use ipc_rust::{
RawData,
};
use ipc_rust::{Serialize, Deserialize,BorrowedMsgParcel};
use ipc_rust::{Serialize, Deserialize, BorrowedMsgParcel, Ashmem};
use test_ipc_service::{ITest, TestProxy, IPC_TEST_SERVICE_ID, IFoo, init_access_token};
use std::fs::File;
......@@ -684,4 +684,35 @@ mod parcel_type_test {
assert_eq!(value[0], data[i as usize]);
}
}
#[test]
fn test_ashmem_read_and_write(){
let ashmemName = "AshmemIpc";
let rawData1k = 1024;
let ashmemString = "HelloWorld2023";
for _i in 1..=30000 {
let ashmem = Ashmem::new(&ashmemName, rawData1k).expect("create ashmem failed");
assert_eq!(ashmem.map_read_write(), true);
assert_eq!(ashmem.write(&ashmemString.as_bytes(), 0), true);
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
parcel.write(&ashmem).expect("write MsgParcel failed");
assert_eq!(parcel.rewind_read(0), true);
let ashmem2: Ashmem = parcel.read().expect("read MsgParcel failed");
assert_eq!(ashmem2.map_readonly(), true);
let res: Result<RawData> = ashmem2.read(ashmemString.len() as i32, 0);
let ptr = res.unwrap();
let read_string = ptr.read(0, ashmemString.len() as u32);
let res = std::str::from_utf8(read_string.unwrap()).unwrap();
assert_eq!(&ashmemString, &res);
ashmem.unmap();
ashmem.close();
ashmem2.unmap();
ashmem2.close();
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册