提交 35a7f840 编写于 作者: T tanyanying

Add rust interface for Ashmem.

Signed-off-by: Ntanyanying <tanyanying@huawei.com>
上级 138ec9ff
/*
* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use crate::{ipc_binding, RawData, Result};
use crate::ipc_binding::CAshmem;
use std::ffi::CString;
/// Ashmem packed the native CAshmem
#[repr(C)]
pub struct Ashmem(*mut CAshmem);
impl Ashmem {
/// Create a Ashmem object
pub fn new(name: &str, size: i32) -> Option<Self> {
if size <= 0 {
return None;
}
let c_name = CString::new(name).expect("ashmem name is invalid!");
// SAFETY:
let native = unsafe {
ipc_binding::CreateCAshmem(c_name.as_ptr(), size)
};
if native.is_null() {
None
} else {
Some(Self(native))
}
}
/// Extract a raw `CAshmem` pointer from this wrapper.
/// # Safety
pub unsafe fn as_inner(&self) -> *mut CAshmem {
self.0
}
}
/// Memory protection for mmap() PROT_NONE
pub const PROT_NONE: i32 = 0;
/// Memory protection for mmap() PROT_READ
pub const PROT_READ: i32 = 1;
/// Memory protection for mmap() PROT_WRITE
pub const PROT_WRITE: i32 = 2;
/// Memory protection for mmap() PROT_EXEC
pub const PROT_EXEC: i32 = 4;
impl Ashmem {
/// Close Ashmem, the ashmem becomes invalid after closing.
pub fn close(&self) {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::CloseCAshmem(self.as_inner());
}
}
/// Set ashmem map type with above PROT_XXX by mmap()
pub fn map(&self, map_type: i32) -> bool {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::MapCAshmem(self.as_inner(), map_type)
}
}
/// Set ashmem map type with `PROT_READ | PROT_WRITE` by mmap()
pub fn map_read_write(&self) -> bool {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::MapReadAndWriteCAshmem(self.as_inner())
}
}
/// Set ashmem map type with `PROT_READ` by mmap()
pub fn map_readonly(&self) -> bool {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::MapReadOnlyCAshmem(self.as_inner())
}
}
/// unmap ashmem
pub fn unmap(&self) {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::UnmapCAshmem(self.as_inner());
}
}
/// Set ashmem map type with above PROT_XXX by ioctl()
pub fn set_protection(&self, protection: i32) -> bool {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::SetCAshmemProtection(self.as_inner(), protection)
}
}
/// Get ashmem map type
pub fn get_protection(&self) -> i32 {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::GetCAshmemProtection(self.as_inner())
}
}
/// Get ashmem size
pub fn get_size(&self) -> i32 {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::GetCAshmemSize(self.as_inner())
}
}
/// Write data to ashmem
pub fn write(&self, data: &[u8], offset: i32) -> bool {
let len = data.len() as i32;
if offset < 0 || offset >= len {
println!("invalid offset: {}, len: {}", offset, len);
return false;
}
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::WriteToCAshmem(self.as_inner(),
data.as_ptr(), len, offset)
}
}
/// Read ashmem
pub fn read(&self, size: i32, offset: i32) -> Result<RawData> {
let raw_ptr = unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::ReadFromCAshmem(self.as_inner(), size, offset)
};
if raw_ptr.is_null() {
Err(-1)
} else {
Ok(RawData::new(raw_ptr, size as u32))
}
}
/// Get ashmem inner file descriptor
pub fn get_fd(&self) -> i32 {
unsafe {
// SAFETY: Rust Ashmem always hold a valid native CAshmem.
ipc_binding::GetCAshmemFd(self.as_inner())
}
}
}
impl Clone for Ashmem {
fn clone(&self) -> Self {
// SAFETY:
unsafe {
ipc_binding::CAshmemIncStrongRef(self.as_inner());
}
// SAFETY: no `None` here, cause `self` is valid
Self(self.0)
}
}
impl Drop for Ashmem {
fn drop(&mut self) {
// SAFETY:
unsafe {
ipc_binding::CAshmemDecStrongRef(self.as_inner());
}
}
}
\ No newline at end of file
......@@ -32,6 +32,11 @@ pub struct CParcel {
_private: [u8; 0],
}
#[repr(C)]
pub struct CAshmem {
_private: [u8; 0],
}
// Callback function type for OnRemoteRequest() from native, this
// callback will be called when native recive client IPC request.
pub type OnRemoteRequest = unsafe extern "C" fn (
......@@ -213,6 +218,26 @@ extern "C" {
pub fn CParcelRewindWrite(parcel: *mut CParcel, new_pos: u32) -> bool;
}
// C interface for Ashmem
extern "C" {
pub fn CreateCAshmem(name: *const c_char, size: i32) -> *mut CAshmem;
pub fn CAshmemIncStrongRef(ashmem: *mut CAshmem);
pub fn CAshmemDecStrongRef(ashmem: *mut CAshmem);
pub fn CloseCAshmem(ashmem: *mut CAshmem);
pub fn MapCAshmem(ashmem: *mut CAshmem, mapType: i32) -> bool;
pub fn MapReadAndWriteCAshmem(ashmem: *mut CAshmem) -> bool;
pub fn MapReadOnlyCAshmem(ashmem: *mut CAshmem) -> bool;
pub fn UnmapCAshmem(ashmem: *mut CAshmem);
pub fn SetCAshmemProtection(ashmem: *mut CAshmem, protectionType: i32) -> bool;
pub fn GetCAshmemProtection(ashmem: *const CAshmem) -> i32;
pub fn GetCAshmemSize(ashmem: *const CAshmem) -> i32;
pub fn WriteToCAshmem(ashmem: *mut CAshmem, data: *const u8,
size: i32, offset: i32) -> bool;
pub fn ReadFromCAshmem(ashmem: *const CAshmem, size: i32, offset: i32) -> *const u8;
pub fn GetCAshmemFd(ashmem: *const CAshmem) -> i32;
}
// C interface for IPC miscellaneous
extern "C" {
pub fn GetContextManager() -> *mut CRemoteObject;
......
......@@ -20,6 +20,7 @@ mod errors;
mod ipc;
mod parcel;
mod process;
mod ashmem;
// Export types of this crate
pub use crate::errors::{Result, result_status};
......@@ -32,14 +33,14 @@ pub use crate::parcel::{
MsgParcel, BorrowedMsgParcel, IMsgParcel, RawData,
parcelable::{Serialize, Deserialize, SerOption, DeOption},
};
// pub use crate::parcel::{SerArray, DeArray};
pub use crate::parcel::parcelable::{SerArray, DeArray};
pub use crate::parcel::types::{
interface_token::InterfaceToken, file_desc::FileDesc,
string16::String16
};
pub use crate::ashmem::{
Ashmem, PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC,
};
pub use crate::process::{
get_context_object, add_service, get_service, join_work_thread, stop_work_thread,
get_calling_uid, get_calling_token_id, get_first_token_id, get_self_token_id,
......
......@@ -164,10 +164,7 @@ pub trait IMsgParcel: AsRawPtr<CParcel> {
if raw_data_ptr.is_null() {
Err(-1)
} else {
Ok(RawData {
raw_ptr: raw_data_ptr,
len,
})
Ok(RawData::new(raw_data_ptr, len))
}
}
}
......@@ -180,6 +177,14 @@ pub struct RawData{
}
impl RawData{
/// Create RawData object
pub fn new(raw_ptr: *const u8, len: u32) -> Self {
RawData {
raw_ptr,
len,
}
}
/// The caller should ensure that the u8 slice can be
/// correctly converted to other rust types
pub fn read(&self, start: u32, len: u32) -> Result<&[u8]> {
......
......@@ -105,7 +105,6 @@ pub unsafe extern "C" fn allocate_vec_with_buffer<T>(
res
}
/// Callback to allocate a vector for parcel array read functions.
///
/// # Safety
......@@ -131,6 +130,7 @@ unsafe extern "C" fn allocate_vec<T>(
// We want the default implementation for most types, but an override for
// a few special ones like `readByteArray` for `u8`.
pub trait SerArray: Serialize + Sized {
/// Default array serialize implement.
fn ser_array(slice: &[Self], parcel: &mut BorrowedMsgParcel<'_>) -> Result<()> {
let ret = unsafe {
// SAFETY: Safe FFI, slice will always be a safe pointer to pass.
......
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IPC_C_ASHMEM_H
#define IPC_C_ASHMEM_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
struct CAshmem;
typedef struct CAshmem CAshmem;
CAshmem *CreateCAshmem(const char *name, int32_t size);
void CAshmemIncStrongRef(CAshmem *ashmem);
void CAshmemDecStrongRef(CAshmem *ashmem);
void CloseCAshmem(CAshmem *ashmem);
bool MapCAshmem(CAshmem *ashmem, int32_t mapType);
bool MapReadAndWriteCAshmem(CAshmem *ashmem);
bool MapReadOnlyCAshmem(CAshmem *ashmem);
void UnmapCAshmem(CAshmem *ashmem);
bool SetCAshmemProtection(CAshmem *ashmem, int32_t protectionType);
int32_t GetCAshmemProtection(const CAshmem *ashmem);
int32_t GetCAshmemSize(const CAshmem *ashmem);
bool WriteToCAshmem(CAshmem *ashmem, const uint8_t *data, int32_t size, int32_t offset);
const uint8_t *ReadFromCAshmem(const CAshmem *ashmem, int32_t size, int32_t offset);
int32_t GetCAshmemFd(const CAshmem *ashmem);
#ifdef __cplusplus
}
#endif
#endif /* IPC_C_ASHMEM_H */
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IPC_C_ASHMEM_INTERNAL_H
#define IPC_C_ASHMEM_INTERNAL_H
#include <ashmem.h>
#include <refbase.h>
#include <stdint.h>
struct CAshmem: public OHOS::RefBase {
CAshmem(OHOS::sptr<OHOS::Ashmem> &ashmem): ashmem_(ashmem) {}
virtual ~CAshmem();
OHOS::sptr<OHOS::Ashmem> ashmem_;
};
#endif /* IPC_C_ASHMEM_INTERNAL_H */
......@@ -30,6 +30,18 @@ struct CRemoteObjectHolder;
typedef struct CRemoteObjectHolder CRemoteObject;
typedef bool (*OnCParcelBytesAllocator)(void *stringData, char **buffer, int32_t len);
typedef bool (*OnCParcelBoolAllocator)(void *value, bool **buffer, int32_t len);
typedef bool (*OnCParcelInt8Allocator)(void *value, int8_t **buffer, int32_t len);
typedef bool (*OnCParcelInt16Allocator)(void *value, int16_t **buffer, int32_t len);
typedef bool (*OnCParcelInt32Allocator)(void *value, int32_t **buffer, int32_t len);
typedef bool (*OnCParcelInt64Allocator)(void *value, int64_t **buffer, int32_t len);
typedef bool (*OnCParcelFloatAllocator)(void *value, float **buffer, int32_t len);
typedef bool (*OnCParcelDoubleAllocator)(void *value, double **buffer, int32_t len);
typedef bool (*OnCParcelAllocator)(void *value, int32_t len);
typedef bool (*OnStringArrayWrite)(const void *array, const void *value, uint32_t len);
typedef bool (*OnStringArrayRead)(const void *array, const void *value, uint32_t len);
typedef bool (*OnCParcelWriteElement)(CParcel *value, const void *arr, unsigned long index);
typedef bool (*OnCParcelReadElement)(const CParcel *value, void *arr, unsigned long index);
CParcel *CParcelObtain(void);
void CParcelIncStrongRef(CParcel *parcel);
......@@ -61,6 +73,34 @@ bool CParcelWriteFileDescriptor(CParcel *parcel, int32_t fd);
bool CParcelReadFileDescriptor(const CParcel *parcel, int32_t *fd);
bool CParcelWriteBuffer(CParcel *parcel, const uint8_t *buffer, uint32_t len);
bool CParcelReadBuffer(const CParcel *parcel, uint8_t *value, uint32_t len);
bool CParcelWriteRawData(CParcel *parcel, const uint8_t *buffer, uint32_t len);
const uint8_t *CParcelReadRawData(const CParcel *parcel, uint32_t len);
bool CParcelWriteBoolArray(CParcel *parcel, const bool *array, int32_t len);
bool CParcelReadBoolArray(const CParcel *parcel, void *value, OnCParcelBoolAllocator allocator);
bool CParcelWriteInt8Array(CParcel *parcel, const int8_t *array, int32_t len);
bool CParcelReadInt8Array(const CParcel *parcel, void *value, OnCParcelInt8Allocator allocator);
bool CParcelWriteInt16Array(CParcel *parcel, const int16_t *array, int32_t len);
bool CParcelReadInt16Array(const CParcel *parcel, void *value, OnCParcelInt16Allocator allocator);
bool CParcelWriteInt32Array(CParcel *parcel, const int32_t *array, int32_t len);
bool CParcelReadInt32Array(const CParcel *parcel, void *value, OnCParcelInt32Allocator allocator);
bool CParcelWriteInt64Array(CParcel *parcel, const int64_t *array, int32_t len);
bool CParcelReadInt64Array(const CParcel *parcel, void *value, OnCParcelInt64Allocator allocator);
bool CParcelWriteFloatArray(CParcel *parcel, const float *array, int32_t len);
bool CParcelReadFloatArray(const CParcel *parcel, void *value, OnCParcelFloatAllocator allocator);
bool CParcelWriteDoubleArray(CParcel *parcel, const double *array, int32_t len);
bool CParcelReadDoubleArray(const CParcel *parcel, void *value, OnCParcelDoubleAllocator allocator);
bool CParcelWriteStringArray(CParcel *parcel, const void *value,
int32_t len, OnStringArrayWrite writer);
bool CParcelWriteStringElement(void *data, const char *value, int32_t len);
bool CParcelReadStringArray(const CParcel *parcel, void *value, OnStringArrayRead reader);
bool CParcelReadStringElement(uint32_t index, const void *data, void *value,
OnCParcelBytesAllocator allocator);
bool CParcelWriteParcelableArray(CParcel *parcel, const void *value, int32_t len,
OnCParcelWriteElement elementWriter);
bool CParcelReadParcelableArray(const CParcel *parcel, void *value,
OnCParcelAllocator allocator, OnCParcelReadElement elementReader);
uint32_t CParcelGetDataSize(const CParcel *parcel);
bool CParcelSetDataSize(CParcel *parcel, uint32_t new_size);
......
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "c_ashmem.h"
#include "c_ashmem_internal.h"
using namespace OHOS;
static bool IsValidCAshmem(const CAshmem *ashmem, const char *promot)
{
if (ashmem == nullptr) {
printf("%s: cashmem is null\n", promot);
return false;
}
if (ashmem->ashmem_ == nullptr) {
printf("%s: wrapper ashmem is null\n", promot);
return false;
}
return true;
}
CAshmem::~CAshmem()
{
if (ashmem_ != nullptr) {
ashmem_->CloseAshmem();
ashmem_ = nullptr;
}
}
CAshmem *CreateCAshmem(const char *name, int32_t size)
{
sptr<Ashmem> ashmem = Ashmem::CreateAshmem(name, size);
if (ashmem == nullptr) {
printf("%s: create native ashmem failed\n", __func__);
return nullptr;
}
CAshmem *cashmem = new (std::nothrow) CAshmem(ashmem);
if (cashmem == nullptr) {
printf("%s: create cashmem failed\n", __func__);
ashmem->CloseAshmem();
return nullptr;
}
cashmem->IncStrongRef(nullptr);
return cashmem;
}
void CAshmemIncStrongRef(CAshmem *ashmem)
{
if (ashmem == nullptr) {
printf("%s: ashmem is nullptr\n", __func__);
return;
}
ashmem->IncStrongRef(nullptr);
}
void CAshmemDecStrongRef(CAshmem *ashmem)
{
if (ashmem == nullptr) {
printf("%s: ashmem is nullptr\n", __func__);
return;
}
ashmem->DecStrongRef(nullptr);
}
void CloseCAshmem(CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return;
}
ashmem->ashmem_->CloseAshmem();
}
bool MapCAshmem(CAshmem *ashmem, int32_t mapType)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return false;
}
return ashmem->ashmem_->MapAshmem(mapType);
}
bool MapReadAndWriteCAshmem(CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return false;
}
return ashmem->ashmem_->MapReadAndWriteAshmem();
}
bool MapReadOnlyCAshmem(CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return false;
}
return ashmem->ashmem_->MapReadOnlyAshmem();
}
void UnmapCAshmem(CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return;
}
ashmem->ashmem_->MapReadOnlyAshmem();
}
bool SetCAshmemProtection(CAshmem *ashmem, int32_t protectionType)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return false;
}
return ashmem->ashmem_->SetProtection(protectionType);
}
int32_t GetCAshmemProtection(const CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return -1;
}
return ashmem->ashmem_->GetProtection();
}
int32_t GetCAshmemSize(const CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return 0;
}
return ashmem->ashmem_->GetAshmemSize();
}
bool WriteToCAshmem(CAshmem *ashmem, const uint8_t *data, int32_t size, int32_t offset)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return false;
}
return ashmem->ashmem_->WriteToAshmem(reinterpret_cast<const uint8_t *>(data), size, offset);
}
const uint8_t *ReadFromCAshmem(const CAshmem *ashmem, int32_t size, int32_t offset)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return nullptr;
}
return reinterpret_cast<const uint8_t *>(ashmem->ashmem_->ReadFromAshmem(size, offset));
}
int32_t GetCAshmemFd(const CAshmem *ashmem)
{
if (!IsValidCAshmem(ashmem, __func__)) {
return -1;
}
return ashmem->ashmem_->GetAshmemFd();
}
......@@ -52,6 +52,42 @@ static bool IsValidParcel(const CParcel *parcel, const char *promot)
return true;
}
static bool WriteAndCheckArrayLength(CParcel *parcel, bool isNull, int32_t len)
{
if (len < -1) {
return false;
}
if (!isNull && len < 0) {
printf("%s: not null array has invalid length: %d\n", __func__, len);
return false;
}
if (isNull && len > 0) {
printf("%s: null array has invalid length: %d\n", __func__, len);
return false;
}
return parcel->parcel_->WriteInt32(len);
}
static bool ReadAndCheckArrayLength(const CParcel *parcel, int32_t &len)
{
if (!parcel->parcel_->ReadInt32(len)) {
printf("%s: read array length from native parcel failed\n", __func__);
return false;
}
if (len < -1) {
printf("%s: length is invalid: %d\n", __func__, len);
return false;
}
if (len <= 0) { // null array
return true;
}
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;
}
CParcel *CParcelObtain(void)
{
CParcel *holder = new (std::nothrow) MessageParcelHolder();
......@@ -274,7 +310,8 @@ bool CParcelReadString16(const CParcel *parcel, void *stringData, OnCParcelBytes
}
std::string value = Str16ToStr8(u16string);
if (u16string.length() != 0 && value.length() == 0) {
printf("%s: u16string len: %lu, string len: %lu\n", __func__, u16string.length(), value.length());
printf("%s: u16string len: %u, string len: %u\n", __func__,
static_cast<uint32_t>(u16string.length()), static_cast<uint32_t>(value.length()));
return false;
}
char *buffer = nullptr;
......@@ -315,10 +352,10 @@ bool CParcelReadInterfaceToken(const CParcel *parcel, void *token, OnCParcelByte
std::u16string u16string = parcel->parcel_->ReadInterfaceToken();
std::string value = Str16ToStr8(u16string);
if (u16string.length() != 0 && value.length() == 0) {
printf("%s: u16string len: %lu, string len: %lu\n", __func__, u16string.length(), value.length());
printf("%s: u16string len: %u, string len: %u\n", __func__,
static_cast<uint32_t>(u16string.length()), static_cast<uint32_t>(value.length()));
return false;
}
printf("%s: c read interface token: %s\n", __func__, value.c_str());
char *buffer = nullptr;
bool isSuccess = allocator(token, &buffer, value.length());
if (!isSuccess) {
......@@ -415,6 +452,286 @@ bool CParcelReadBuffer(const CParcel *parcel, uint8_t *value, uint32_t len)
return true;
}
bool CParcelWriteRawData(CParcel *parcel, const uint8_t *buffer, uint32_t len)
{
if (!IsValidParcel(parcel, __func__)) {
return false;
}
return parcel->parcel_->WriteRawData(buffer, len);
}
const uint8_t *CParcelReadRawData(const CParcel *parcel, uint32_t len)
{
if (!IsValidParcel(parcel, __func__)) {
return nullptr;
}
const void *data = parcel->parcel_->ReadRawData(len);
if (data == nullptr) {
printf("%s: read raw data from native failed\n", __func__);
return nullptr;
}
return reinterpret_cast<const uint8_t *>(data);
}
template <typename T>
static bool WriteVector(CParcel *parcel, const char *func, const T *array, int32_t len,
bool (Parcel::*Write)(const std::vector<T> &val))
{
if (!IsValidParcel(parcel, func) || (array == nullptr && len > 0)) {
return false;
}
std::vector<T> value(array, array + len);
return (parcel->parcel_->*Write)(value);
}
template <typename T>
static bool ReadVector(const CParcel *parcel, const char *func, void *value,
bool (*OnCParcelTypeAllocator)(void *value, T **buffer, int32_t len),
bool (Parcel::*Read)(std::vector<T> *val))
{
if (!IsValidParcel(parcel, func) || OnCParcelTypeAllocator == nullptr) {
return false;
}
std::vector<T> array;
if (!(parcel->parcel_->*Read)(&array)) {
printf("%s: read type vector from native failed\n", func);
return false;
}
T *buffer = nullptr;
bool isSuccess = OnCParcelTypeAllocator(value, &buffer, array.size());
if (!isSuccess) {
printf("%s: allocate type array buffer failed\n", func);
return false;
}
int32_t len = array.size() * sizeof(T);
if (array.size() > 0 && memcpy_s(buffer, len, array.data(), len) != EOK) {
printf("%s: memcpy type buffer failed\n", func);
return false;
}
return true;
}
bool CParcelWriteBoolArray(CParcel *parcel, const bool *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteBoolVector);
}
bool CParcelReadBoolArray(const CParcel *parcel, void *value, OnCParcelBoolAllocator allocator)
{
if (!IsValidParcel(parcel, __func__) || allocator == nullptr) {
return false;
}
std::vector<bool> array;
if (!parcel->parcel_->ReadBoolVector(&array)) {
printf("%s: read bool vector from native failed\n", __func__);
return false;
}
bool *buffer = nullptr;
bool isSuccess = allocator(value, &buffer, array.size());
if (!isSuccess) {
printf("%s: allocate bool array buffer failed\n", __func__);
return false;
}
if (array.size() > 0) {
for (size_t i = 0; i < array.size(); ++i) {
buffer[i] = array[i];
}
}
return true;
}
bool CParcelWriteInt8Array(CParcel *parcel, const int8_t *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteInt8Vector);
}
bool CParcelReadInt8Array(const CParcel *parcel, void *value, OnCParcelInt8Allocator allocator)
{
return ReadVector(parcel, __func__, value, allocator, &Parcel::ReadInt8Vector);
}
bool CParcelWriteInt16Array(CParcel *parcel, const int16_t *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteInt16Vector);
}
bool CParcelReadInt16Array(const CParcel *parcel, void *value, OnCParcelInt16Allocator allocator)
{
return ReadVector(parcel, __func__, value, allocator, &Parcel::ReadInt16Vector);
}
bool CParcelWriteInt32Array(CParcel *parcel, const int32_t *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteInt32Vector);
}
bool CParcelReadInt32Array(const CParcel *parcel, void *value, OnCParcelInt32Allocator allocator)
{
return ReadVector(parcel, __func__, value, allocator, &Parcel::ReadInt32Vector);
}
bool CParcelWriteInt64Array(CParcel *parcel, const int64_t *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteInt64Vector);
}
bool CParcelReadInt64Array(const CParcel *parcel, void *value, OnCParcelInt64Allocator allocator)
{
return ReadVector(parcel, __func__, value, allocator, &Parcel::ReadInt64Vector);
}
bool CParcelWriteFloatArray(CParcel *parcel, const float *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteFloatVector);
}
bool CParcelReadFloatArray(const CParcel *parcel, void *value, OnCParcelFloatAllocator allocator)
{
return ReadVector(parcel, __func__, value, allocator, &Parcel::ReadFloatVector);
}
bool CParcelWriteDoubleArray(CParcel *parcel, const double *array, int32_t len)
{
return WriteVector(parcel, __func__, array, len, &Parcel::WriteDoubleVector);
}
bool CParcelReadDoubleArray(const CParcel *parcel, void *value, OnCParcelDoubleAllocator allocator)
{
return ReadVector(parcel, __func__, value, allocator, &Parcel::ReadDoubleVector);
}
bool CParcelWriteStringArray(CParcel *parcel, const void *value,
int32_t len, OnStringArrayWrite writer)
{
if (!IsValidParcel(parcel, __func__) || writer == nullptr) {
return false;
}
std::vector<std::string> stringVector;
if (len > 0 && !writer(reinterpret_cast<void *>(&stringVector),
value, static_cast<uint32_t>(len))) {
printf("%s: write string array to vector failed\n", __func__);
return false;
}
if (!parcel->parcel_->WriteStringVector(stringVector)) {
printf("%s: write string array to parcel failed\n", __func__);
return false;
}
return true;
}
bool CParcelWriteStringElement(void *data, const char *value, int32_t len)
{
std::vector<std::string> *stringVector = reinterpret_cast<std::vector<std::string> *>(data);
if (stringVector == nullptr) {
printf("%s: stringVector is null\n", __func__);
return false;
}
if (len < 0) {
printf("%s: string len is invalid: %d\n", __func__, len);
return false;
}
stringVector->push_back(std::string(value, len));
return true;
}
bool CParcelReadStringArray(const CParcel *parcel, void *value, OnStringArrayRead reader)
{
if (!IsValidParcel(parcel, __func__) || reader == nullptr) {
return false;
}
std::vector<std::string> stringVector;
if (!parcel->parcel_->ReadStringVector(&stringVector)) {
printf("%s: read string array from parcel failed\n", __func__);
return false;
}
printf("%s: read string array len: %u\n", __func__,
static_cast<uint32_t>(stringVector.size()));
if (!reader(reinterpret_cast<void *>(&stringVector), value, stringVector.size())) {
printf("%s: read string to vector failed\n", __func__);
return false;
}
printf("%s: read string array success\n", __func__);
return true;
}
bool CParcelReadStringElement(uint32_t index, const void *data, void *value,
OnCParcelBytesAllocator allocator)
{
printf("%s: enter\n", __func__);
if (data == nullptr || allocator == nullptr) {
printf("%s: invalid data and allocator\n", __func__);
return false;
}
const std::vector<std::string> *stringVector =
reinterpret_cast<const std::vector<std::string> *>(data);
if (index >= stringVector->size()) {
printf("%s: invalid index: %u, size: %u\n", __func__,
index, static_cast<uint32_t>(stringVector->size()));
return false;
}
printf("%s: index: %u\n", __func__, index);
const std::string &stringValue = (*stringVector)[index];
char *buffer = nullptr;
bool isSuccess = allocator(value, &buffer, stringValue.length());
if (!isSuccess) {
printf("%s: allocate string buffer failed\n", __func__);
return false;
}
printf("%s: read string element: %s\n", __func__, stringValue.c_str());
if (stringValue.length() > 0 &&
memcpy_s(buffer, stringValue.length(), stringValue.data(), stringValue.length()) != EOK) {
printf("%s: memcpy string failed\n", __func__);
return false;
}
return true;
}
bool CParcelWriteParcelableArray(CParcel *parcel, const void *value, int32_t len,
OnCParcelWriteElement elementWriter)
{
if (!IsValidParcel(parcel, __func__) || elementWriter == nullptr) {
return false;
}
size_t pos = parcel->parcel_->GetWritePosition();
if (!WriteAndCheckArrayLength(parcel, len < 0, len)) {
return false;
}
for (int32_t i = 0; i < len; ++i) {
if (!elementWriter(parcel, value, static_cast<unsigned long>(i))) {
printf("%s: write parcelable for index: %d failed\n", __func__, i);
parcel->parcel_->RewindWrite(pos);
return false;
}
}
return true;
}
bool CParcelReadParcelableArray(const CParcel *parcel, void *value,
OnCParcelAllocator allocator, OnCParcelReadElement elementReader)
{
if (!IsValidParcel(parcel, __func__) || elementReader == nullptr) {
return false;
}
size_t pos = parcel->parcel_->GetReadPosition();
int32_t length;
if (!ReadAndCheckArrayLength(parcel, length)) {
return false;
}
if (!allocator(value, length)) {
printf("%s: allocator failed\n", __func__);
return false;
}
// length == -1 means null array, and will return true
for (int32_t i = 0; i < length; ++i) {
if (!elementReader(parcel, value, static_cast<unsigned long>(i))) {
printf("%s: read parcelable for index: %d failed\n", __func__, i);
parcel->parcel_->RewindRead(pos);
return false;
}
}
return true;
}
uint32_t CParcelGetDataSize(const CParcel *parcel)
{
if (!IsValidParcel(parcel, __func__)) {
......
......@@ -34,7 +34,6 @@ int RemoteServiceHolderStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel
OHOS::MessageParcel &reply, OHOS::MessageOption &option)
{
(void)option;
printf("%s: OnRemoteRequest code: %u\n", __func__, code);
if (callback_ == nullptr || holder_ == nullptr) {
printf("%s: callback is null for code: %u\n", __func__, code);
return -1;
......
......@@ -41,7 +41,7 @@ fn get_test_service() -> RemoteObjRef<dyn ITest>
panic!();
}
};
return remote;
remote
}
#[test]
......@@ -55,10 +55,10 @@ fn test_death_recipient_001() {
let mut death_recipient = DeathRecipient::new(|| {
println!("recv death recipient in rust");
}).expect("new death recipient failed");
assert_eq!(object.add_death_recipient(&mut death_recipient), true);
assert_eq!(object.add_death_recipient(&mut death_recipient), true);
assert_eq!(object.remove_death_recipient(&mut death_recipient), true);
assert_eq!(object.remove_death_recipient(&mut death_recipient), true);
assert!(object.add_death_recipient(&mut death_recipient));
assert!(object.add_death_recipient(&mut death_recipient));
assert!(object.remove_death_recipient(&mut death_recipient));
assert!(object.remove_death_recipient(&mut death_recipient));
}
#[test]
......@@ -67,7 +67,7 @@ fn test_death_recipient_002() {
let mut death_recipient = DeathRecipient::new(|| {
println!("recv death recipient in rust");
}).expect("new death recipient failed");
assert_eq!(object.add_death_recipient(&mut death_recipient), true);
assert!(object.add_death_recipient(&mut death_recipient));
println!("please kill remote ITest service");
thread::sleep(Duration::from_secs(10));
}
......@@ -166,7 +166,7 @@ fn test_fd() {
let fd: FileDesc = remote.test_transact_fd().expect("get server fd failed");
let mut info = String::new();
let mut file = File::from(fd);
file.seek(SeekFrom::Start(0));
file.seek(SeekFrom::Start(0)).expect("seek failed");
file.read_to_string(&mut info).expect("read string from fd failed");
println!("file content: {}", info);
assert_eq!(info, "Sever write!\n");
......@@ -194,7 +194,7 @@ fn test_remote_obj() {
}
#[cfg(test)]
mod ParcelTypeTest {
mod parcel_type_test {
use super::*;
#[test]
......@@ -214,9 +214,9 @@ mod ParcelTypeTest {
parcel.write(&2.2_f64).expect("write f64 failed");
let value: bool = parcel.read().expect("read false failed");
assert_eq!(value, false);
assert!(!value);
let value: bool = parcel.read().expect("read true failed");
assert_eq!(value, true);
assert!(value);
let value: u8 = parcel.read().expect("read u8 failed");
assert_eq!(value, 1_u8);
let value: i8 = parcel.read().expect("read i8 failed");
......@@ -601,7 +601,7 @@ mod ParcelTypeTest {
let u8_slice = &u8_slice[..];
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
let res = parcel.write_buffer(u8_slice);
assert_eq!(res, true);
assert!(res);
let u8_vec: Vec<u8> = parcel.read_buffer(100).expect("read buffer failed");
assert_eq!(u8_vec, u8_slice);
}
......@@ -612,7 +612,7 @@ mod ParcelTypeTest {
let u8_slice = &u8_slice[..];
let mut parcel = MsgParcel::new().expect("create MsgParcel failed");
let res = parcel.write_buffer(u8_slice);
assert_eq!(res, true);
assert!(res);
let u8_vec = parcel.read_buffer(0).expect("read zero length buffer failed");
assert_eq!(u8_vec.len() as i32, 0);
}
......@@ -639,7 +639,11 @@ mod ParcelTypeTest {
impl Deserialize for Year {
fn deserialize(parcel: &BorrowedMsgParcel<'_>) -> Result<Self> {
parcel.read::<i64>().map(|i| Year(i) )
let ret = parcel.read::<i64>();
match ret {
Ok(year) => Ok(Year(year)),
Err(_) => Err(-1),
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册