Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add asset module #10

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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