Skip to content

Commit

Permalink
Merge pull request #10 from ohos-rs/feat-asset
Browse files Browse the repository at this point in the history
feat: add asset module
  • Loading branch information
richerfu authored Jun 26, 2024
2 parents f2894b2 + e9f2f06 commit 2b6df91
Show file tree
Hide file tree
Showing 11 changed files with 1,290 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ resolver = "2"
ohos-bundle-binding = { version = "0.0.1", path = "crates/bundle" }
ohos-init-binding = { version = "0.0.3", path = "crates/init" }
ohos-hilog-binding = { version = "0.0.3", path = "crates/hilog" }
ohos-asset-binding = { version = "0.0.1", path = "crates/asset" }

ohos-bundle-sys = { version = "0.0.2", path = "sys/ohos-bundle-sys" }
ohos-init-sys = { version = "0.0.2", path = "sys/ohos-init-sys" }
ohos-hilogs-sys = { version = "0.0.2", path = "sys/ohos-hilogs-sys" }
ohos-asset-sys = { version = "0.0.1", path = "sys/ohos-asset-sys" }

napi-ohos = { version = "1.0.0-beta.2" }
napi-derive-ohos = { version = "1.0.0-beta.2" }
Expand Down
9 changes: 9 additions & 0 deletions crates/asset/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "ohos-asset-binding"
version = "0.0.1"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "OpenHarmony's asset binding for rust"

[dependencies]
ohos-asset-sys = { workspace = true }
140 changes: 140 additions & 0 deletions crates/asset/src/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::mem::ManuallyDrop;

use crate::AssetTag;

pub type AssetBlob = Vec<u8>;

pub enum AssetValue {
Boolean(bool),
U32IntT(u32),
Blob(ManuallyDrop<AssetBlob>),
}

pub struct AssetAttr {
pub tag: AssetTag,
pub value: AssetValue,
}

impl From<&AssetAttr> for ohos_asset_sys::Asset_Attr {
fn from(value: &AssetAttr) -> Self {
match &value.value {
AssetValue::Blob(blob) => {
let b = ohos_asset_sys::Asset_Blob {
size: blob.len() as u32,
data: blob.as_ptr() as *mut u8,
};
ohos_asset_sys::Asset_Attr {
tag: value.tag.into(),
value: ohos_asset_sys::Asset_Value { blob: b },
}
}
AssetValue::Boolean(boolean) => ohos_asset_sys::Asset_Attr {
tag: value.tag.into(),
value: ohos_asset_sys::Asset_Value {
boolean: boolean.to_owned(),
},
},
AssetValue::U32IntT(uint32_t) => ohos_asset_sys::Asset_Attr {
tag: value.tag.into(),
value: ohos_asset_sys::Asset_Value {
u32_: uint32_t.to_owned(),
},
},
}
}
}

pub struct AssetResult {
pub count: u32,
pub attrs: Vec<AssetAttr>,
}

impl From<*mut ohos_asset_sys::Asset_Result> for AssetResult {
fn from(value: *mut ohos_asset_sys::Asset_Result) -> Self {
unsafe {
let raw_result = &*value;
let mut attrs = Vec::with_capacity(raw_result.count as usize);
for i in 0..raw_result.count as isize {
let raw_attr = &*raw_result.attrs.offset(i);
attrs.push(AssetAttr {
tag: raw_attr.tag.into(),
value: match raw_attr.tag & ohos_asset_sys::ASSET_TAG_TYPE_MASK {
ohos_asset_sys::Asset_TagType_ASSET_TYPE_BOOL => {
AssetValue::Boolean(raw_attr.value.boolean)
}
ohos_asset_sys::Asset_TagType_ASSET_TYPE_NUMBER => {
AssetValue::U32IntT(raw_attr.value.u32_)
}
ohos_asset_sys::Asset_TagType_ASSET_TYPE_BYTES => {
let blob = raw_attr.value.blob;
let data_slice =
std::slice::from_raw_parts(blob.data, blob.size as usize);
AssetValue::Blob(ManuallyDrop::new(data_slice.to_vec()))
}
_ => unimplemented!(),
},
});
}
AssetResult {
count: raw_result.count,
attrs,
}
}
}
}

pub struct AssetResultSet {
pub count: u32,
pub result: Vec<AssetResult>,
}

impl From<*mut ohos_asset_sys::Asset_ResultSet> for AssetResultSet {
fn from(raw: *mut ohos_asset_sys::Asset_ResultSet) -> Self {
unsafe {
let mut results = Vec::new();
if raw.is_null() {
return AssetResultSet {
count: 0,
result: results,
};
}

let raw_result_set = &*raw;
for i in 0..raw_result_set.count as isize {
let raw_result = &*raw_result_set.results.offset(i);
let mut attrs = Vec::new();
for j in 0..raw_result.count as isize {
let raw_attr = &*raw_result.attrs.offset(j);
let value = match raw_attr.tag & ohos_asset_sys::ASSET_TAG_TYPE_MASK {
ohos_asset_sys::Asset_TagType_ASSET_TYPE_BOOL => {
AssetValue::Boolean(raw_attr.value.boolean)
}
ohos_asset_sys::Asset_TagType_ASSET_TYPE_NUMBER => {
AssetValue::U32IntT(raw_attr.value.u32_)
}
ohos_asset_sys::Asset_TagType_ASSET_TYPE_BYTES => {
let blob = raw_attr.value.blob;
let data_slice =
std::slice::from_raw_parts(blob.data, blob.size as usize);
AssetValue::Blob(ManuallyDrop::new(data_slice.to_vec()))
}
_ => unimplemented!(),
};
attrs.push(AssetAttr {
tag: raw_attr.tag.into(),
value,
});
}
results.push(AssetResult {
count: raw_result.count,
attrs,
});
}

AssetResultSet {
count: raw_result_set.count,
result: results,
}
}
}
}
141 changes: 141 additions & 0 deletions crates/asset/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use core::fmt;
use std::fmt::{Debug, Display};

#[derive(Debug, PartialEq)]
pub enum AssetResultCode {
Success,
PermissionDenied,
InvalidArgument,
ServiceUnavailable,
NotFound,
Duplicated,
AccessDenied,
StatusMismatch,
OutOfMemory,
DataCorrupted,
DatabaseError,
CryptoError,
IpcError,
BmsError,
AccountError,
AccessTokenError,
FileOperationError,
GetSystemTimeError,
LimitExceeded,
Unsupported,
UnknownError(u32),
}

impl From<ohos_asset_sys::Asset_ResultCode> for AssetResultCode {
fn from(code: ohos_asset_sys::Asset_ResultCode) -> Self {
match code {
ohos_asset_sys::Asset_ResultCode_ASSET_SUCCESS => AssetResultCode::Success,
ohos_asset_sys::Asset_ResultCode_ASSET_PERMISSION_DENIED => {
AssetResultCode::PermissionDenied
}
ohos_asset_sys::Asset_ResultCode_ASSET_INVALID_ARGUMENT => {
AssetResultCode::InvalidArgument
}
ohos_asset_sys::Asset_ResultCode_ASSET_SERVICE_UNAVAILABLE => {
AssetResultCode::ServiceUnavailable
}
ohos_asset_sys::Asset_ResultCode_ASSET_NOT_FOUND => AssetResultCode::NotFound,
ohos_asset_sys::Asset_ResultCode_ASSET_DUPLICATED => AssetResultCode::Duplicated,
ohos_asset_sys::Asset_ResultCode_ASSET_ACCESS_DENIED => AssetResultCode::AccessDenied,
ohos_asset_sys::Asset_ResultCode_ASSET_STATUS_MISMATCH => {
AssetResultCode::StatusMismatch
}
ohos_asset_sys::Asset_ResultCode_ASSET_OUT_OF_MEMORY => AssetResultCode::OutOfMemory,
ohos_asset_sys::Asset_ResultCode_ASSET_DATA_CORRUPTED => AssetResultCode::DataCorrupted,
ohos_asset_sys::Asset_ResultCode_ASSET_DATABASE_ERROR => AssetResultCode::DatabaseError,
ohos_asset_sys::Asset_ResultCode_ASSET_CRYPTO_ERROR => AssetResultCode::CryptoError,
ohos_asset_sys::Asset_ResultCode_ASSET_IPC_ERROR => AssetResultCode::IpcError,
ohos_asset_sys::Asset_ResultCode_ASSET_BMS_ERROR => AssetResultCode::BmsError,
ohos_asset_sys::Asset_ResultCode_ASSET_ACCOUNT_ERROR => AssetResultCode::AccountError,
ohos_asset_sys::Asset_ResultCode_ASSET_ACCESS_TOKEN_ERROR => {
AssetResultCode::AccessTokenError
}
ohos_asset_sys::Asset_ResultCode_ASSET_FILE_OPERATION_ERROR => {
AssetResultCode::FileOperationError
}
ohos_asset_sys::Asset_ResultCode_ASSET_GET_SYSTEM_TIME_ERROR => {
AssetResultCode::GetSystemTimeError
}
ohos_asset_sys::Asset_ResultCode_ASSET_LIMIT_EXCEEDED => AssetResultCode::LimitExceeded,
ohos_asset_sys::Asset_ResultCode_ASSET_UNSUPPORTED => AssetResultCode::Unsupported,
c => AssetResultCode::UnknownError(c),
}
}
}

impl AssetResultCode {
pub fn to_result_code(self) -> ohos_asset_sys::Asset_ResultCode {
match self {
AssetResultCode::Success => ohos_asset_sys::Asset_ResultCode_ASSET_SUCCESS,
AssetResultCode::PermissionDenied => {
ohos_asset_sys::Asset_ResultCode_ASSET_PERMISSION_DENIED
}
AssetResultCode::InvalidArgument => {
ohos_asset_sys::Asset_ResultCode_ASSET_INVALID_ARGUMENT
}
AssetResultCode::ServiceUnavailable => {
ohos_asset_sys::Asset_ResultCode_ASSET_SERVICE_UNAVAILABLE
}
AssetResultCode::NotFound => ohos_asset_sys::Asset_ResultCode_ASSET_NOT_FOUND,
AssetResultCode::Duplicated => ohos_asset_sys::Asset_ResultCode_ASSET_DUPLICATED,
AssetResultCode::AccessDenied => ohos_asset_sys::Asset_ResultCode_ASSET_ACCESS_DENIED,
AssetResultCode::StatusMismatch => {
ohos_asset_sys::Asset_ResultCode_ASSET_STATUS_MISMATCH
}
AssetResultCode::OutOfMemory => ohos_asset_sys::Asset_ResultCode_ASSET_OUT_OF_MEMORY,
AssetResultCode::DataCorrupted => ohos_asset_sys::Asset_ResultCode_ASSET_DATA_CORRUPTED,
AssetResultCode::DatabaseError => ohos_asset_sys::Asset_ResultCode_ASSET_DATABASE_ERROR,
AssetResultCode::CryptoError => ohos_asset_sys::Asset_ResultCode_ASSET_CRYPTO_ERROR,
AssetResultCode::IpcError => ohos_asset_sys::Asset_ResultCode_ASSET_IPC_ERROR,
AssetResultCode::BmsError => ohos_asset_sys::Asset_ResultCode_ASSET_BMS_ERROR,
AssetResultCode::AccountError => ohos_asset_sys::Asset_ResultCode_ASSET_ACCOUNT_ERROR,
AssetResultCode::AccessTokenError => {
ohos_asset_sys::Asset_ResultCode_ASSET_ACCESS_TOKEN_ERROR
}
AssetResultCode::FileOperationError => {
ohos_asset_sys::Asset_ResultCode_ASSET_FILE_OPERATION_ERROR
}
AssetResultCode::GetSystemTimeError => {
ohos_asset_sys::Asset_ResultCode_ASSET_GET_SYSTEM_TIME_ERROR
}
AssetResultCode::LimitExceeded => ohos_asset_sys::Asset_ResultCode_ASSET_LIMIT_EXCEEDED,
AssetResultCode::Unsupported => ohos_asset_sys::Asset_ResultCode_ASSET_UNSUPPORTED,
AssetResultCode::UnknownError(_code) => unimplemented!(),
}
}
}

impl Display for AssetResultCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
match self {
AssetResultCode::Success => write!(f, "Success"),
AssetResultCode::PermissionDenied => write!(f, "Permission denied"),
AssetResultCode::InvalidArgument => write!(f, "Invalid argument"),
AssetResultCode::ServiceUnavailable => write!(f, "The ASSET service is unavailable."),
AssetResultCode::NotFound => write!(f, "The asset is not found."),
AssetResultCode::Duplicated => write!(f, "The asset already exists."),
AssetResultCode::AccessDenied => write!(f, "Access to the asset is denied."),
AssetResultCode::StatusMismatch => write!(f, "The screen lock status does not match."),
AssetResultCode::OutOfMemory => write!(f, "Insufficient memory."),
AssetResultCode::DataCorrupted => write!(f, "The asset is corrupted."),
AssetResultCode::DatabaseError => write!(f, "The database operation failed."),
AssetResultCode::CryptoError => write!(f, "The cryptography operation failed."),
AssetResultCode::IpcError => write!(f, "IPC failed."),
AssetResultCode::BmsError => write!(f, "Calling the Bundle Manager service failed."),
AssetResultCode::AccountError => write!(f, "Calling the OS Account service failed."),
AssetResultCode::AccessTokenError => {
write!(f, "Calling the Access Token service failed.")
}
AssetResultCode::FileOperationError => write!(f, "The file operation failed."),
AssetResultCode::GetSystemTimeError => write!(f, "Getting the system time failed."),
AssetResultCode::LimitExceeded => write!(f, "The cache exceeds the limit."),
AssetResultCode::Unsupported => write!(f, "The capability is not supported."),
AssetResultCode::UnknownError(code) => write!(f, "Unknown error code: {}", code),
}
}
}
64 changes: 64 additions & 0 deletions crates/asset/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
mod data;
mod r#error;
mod r#type;

use std::ptr;

pub use data::*;
pub use r#error::*;
pub use r#type::*;

/// add
pub fn asset_add(attrs: Vec<AssetAttr>) -> AssetResultCode {
let count = attrs.len() as u32;
let real_attrs = attrs.iter().map(|a| a.into()).collect::<Vec<_>>();
let ret_status = unsafe { ohos_asset_sys::OH_Asset_Add(real_attrs.as_ptr(), count) };
AssetResultCode::from(ret_status as u32)
}

/// query
/// note: If you're trying to access key assets that require user authentication, make sure to run the function asset_pre_query first.
pub fn asset_query(attrs: Vec<AssetAttr>) -> Result<AssetResultSet, AssetResultCode> {
let count = attrs.len() as u32;
let real_attrs = attrs.iter().map(|a| a.into()).collect::<Vec<_>>();
let mut ret_set = ohos_asset_sys::Asset_ResultSet {
count: 0,
results: ptr::null_mut(),
};
let query_status =
unsafe { ohos_asset_sys::OH_Asset_Query(real_attrs.as_ptr(), count, &mut ret_set) };
let query_code = AssetResultCode::from(query_status as u32);
if query_code != AssetResultCode::Success {
return Err(query_code);
}
let ret = AssetResultSet::from((&mut ret_set) as *mut ohos_asset_sys::Asset_ResultSet);

// free origin data
unsafe { ohos_asset_sys::OH_Asset_FreeResultSet(&mut ret_set) };
Ok(ret)
}

/// remove
pub fn asset_remove(attrs: Vec<AssetAttr>) -> AssetResultCode {
let count = attrs.len() as u32;
let real_attrs = attrs.iter().map(|a| a.into()).collect::<Vec<_>>();
let ret_status = unsafe { ohos_asset_sys::OH_Asset_Remove(real_attrs.as_ptr(), count) };
AssetResultCode::from(ret_status as u32)
}

/// update
pub fn asset_update(query_attrs: Vec<AssetAttr>, update_attrs: Vec<AssetAttr>) -> AssetResultCode {
let query_count = query_attrs.len() as u32;
let query_real_attrs = query_attrs.iter().map(|a| a.into()).collect::<Vec<_>>();
let update_count = update_attrs.len() as u32;
let update_real_attrs = update_attrs.iter().map(|a| a.into()).collect::<Vec<_>>();
let ret_status = unsafe {
ohos_asset_sys::OH_Asset_Update(
query_real_attrs.as_ptr(),
query_count,
update_real_attrs.as_ptr(),
update_count,
)
};
AssetResultCode::from(ret_status as u32)
}
Loading

0 comments on commit 2b6df91

Please sign in to comment.