diff --git a/wfassoc-cdylib/src/ffi_types.rs b/wfassoc-cdylib/src/ffi_types.rs index e62b482..df2ebef 100644 --- a/wfassoc-cdylib/src/ffi_types.rs +++ b/wfassoc-cdylib/src/ffi_types.rs @@ -1,8 +1,15 @@ -//! The module including all FFI types used by this crate. +//! The module including all FFI types used by this crate, except string type. +//! For string type, see also [crate::cstr_ffi]. use std::ffi::c_void; use num_enum::TryFromPrimitive; +// region: File Extension Index + +pub const INVALID_INDEX: usize = usize::MAX; + +// endregion + // region: HICON /// The type representing Win32 HICON handle. @@ -17,7 +24,7 @@ pub type HICON = *mut c_void; /// The invalid value of Win32 HICON handle. /// /// The same reason like [HICON] to re-define it in there. -pub const INVALID_ICON: HICON = std::ptr::null_mut(); +pub const INVALID_HICON: HICON = std::ptr::null_mut(); // endregion diff --git a/wfassoc-cdylib/src/lib.rs b/wfassoc-cdylib/src/lib.rs index 9171efa..62b06c6 100644 --- a/wfassoc-cdylib/src/lib.rs +++ b/wfassoc-cdylib/src/lib.rs @@ -1,7 +1,7 @@ mod cstr_ffi; +mod ffi_types; mod last_error; mod object_pool; -mod ffi_types; use object_pool::ObjectPool; use std::sync::{LazyLock, RwLock}; @@ -188,7 +188,13 @@ static SCHEMA_POOL: LazyLock>> = static PROGRAM_POOL: LazyLock>> = LazyLock::new(|| RwLock::new(ObjectPool::new())); -static EXT_STATUE_POOL: LazyLock>> = +static EXT_STATUS_POOL: LazyLock>> = + LazyLock::new(|| RwLock::new(ObjectPool::new())); + +static ICON_RC_POOL: LazyLock>> = + LazyLock::new(|| RwLock::new(ObjectPool::new())); + +static EXT_POOL: LazyLock>> = LazyLock::new(|| RwLock::new(ObjectPool::new())); // endregion @@ -196,8 +202,8 @@ static EXT_STATUE_POOL: LazyLock bool { cffi_wrapper!(|| { let _pool = pull_writer!(SCHEMA_POOL)?; let _pool = pull_writer!(PROGRAM_POOL)?; - let _pool = pull_writer!(EXT_STATUE_POOL)?; + let _pool = pull_writer!(EXT_STATUS_POOL)?; + let _pool = pull_writer!(ICON_RC_POOL)?; + let _pool = pull_writer!(EXT_POOL)?; Ok(()) }) } @@ -224,7 +232,11 @@ pub extern "C" fn WFShutdown() -> bool { pool.clear(); let mut pool = pull_writer!(PROGRAM_POOL)?; pool.clear(); - let mut pool = pull_writer!(EXT_STATUE_POOL)?; + let mut pool = pull_writer!(EXT_STATUS_POOL)?; + pool.clear(); + let mut pool = pull_writer!(ICON_RC_POOL)?; + pool.clear(); + let mut pool = pull_writer!(EXT_POOL)?; pool.clear(); Ok(()) }) @@ -470,6 +482,99 @@ pub extern "C" fn WFProgramDestroy(in_program: in_param_ty!(Token)) -> bool { }) } +#[unsafe(no_mangle)] +pub extern "C" fn WFProgramResolveName( + in_program: in_param_ty!(Token), + out_name: out_param_ty!(CStyleString), +) -> bool { + cffi_wrapper!(|in_program: Token| -> (out_name: CStyleString) { + let mut pool = pull_writer!(PROGRAM_POOL)?; + let program = pool.get_mut(in_program)?; + + let name = match program.resolve_name()? { + Some(name) => { + cstr_ffi::set_ffi_string(&name)?; + cstr_ffi::get_ffi_string() + }, + None => { + std::ptr::null() + }, + }; + Ok(name) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFProgramResolveIcon( + in_program: in_param_ty!(Token), + out_icon_rc: out_param_ty!(Token), +) -> bool { + cffi_wrapper!(|in_program: Token| -> (out_icon_rc: Token) { + let mut pool = pull_writer!(PROGRAM_POOL)?; + let program = pool.get_mut(in_program)?; + + let icon = program.resolve_icon()?; + let token = match icon { + Some(icon) => { + let mut pool = pull_writer!(ICON_RC_POOL)?; + pool.allocate(icon)? + }, + None => { + object_pool::invalid_token() + }, + }; + Ok(token) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFProgramExtsLen( + in_program: in_param_ty!(Token), + out_len: out_param_ty!(usize), +) -> bool { + cffi_wrapper!(|in_program: Token| -> (out_len: usize) { + let mut pool = pull_writer!(PROGRAM_POOL)?; + let program = pool.get_mut(in_program)?; + Ok(program.exts_len()) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFProgramGetExt( + in_program: in_param_ty!(Token), + in_index: in_param_ty!(usize), + out_ext: out_param_ty!(Token), +) -> bool { + cffi_wrapper!(|in_program: Token, in_index: usize| -> (out_ext: Token) { + let mut pool = pull_writer!(PROGRAM_POOL)?; + let program = pool.get_mut(in_program)?; + + let ext = program.get_ext(in_index)?; + let mut pool = pull_writer!(EXT_POOL)?; + let token = pool.allocate(ext.clone())?; + Ok(token) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFProgramFindExt( + in_program: in_param_ty!(Token), + in_body: in_param_ty!(CStyleString), + out_index: out_param_ty!(usize), +) -> bool { + cffi_wrapper!(|in_program: Token, in_body: CStyleString| -> (out_index: usize) { + let mut pool = pull_writer!(PROGRAM_POOL)?; + let program = pool.get_mut(in_program)?; + + let body = cstr_ffi::parse_ffi_string(in_body)?; + let index = match program.find_ext(body) { + Some(index) => index, + None => ffi_types::INVALID_INDEX, + }; + Ok(index) + }) +} + #[unsafe(no_mangle)] pub extern "C" fn WFProgramRegister( in_program: in_param_ty!(Token), @@ -557,7 +662,7 @@ pub extern "C" fn WFProgramQueryExt( let ext_status = program.query_ext(view.into(), in_index)?; let token = match ext_status { Some(ext_status) => { - let mut pool = pull_writer!(EXT_STATUE_POOL)?; + let mut pool = pull_writer!(EXT_STATUS_POOL)?; pool.allocate(ext_status)? }, None => object_pool::invalid_token(), @@ -568,10 +673,12 @@ pub extern "C" fn WFProgramQueryExt( // endregion +// region: Extension Status + #[unsafe(no_mangle)] pub extern "C" fn WFExtStatusDestroy(in_ext_status: in_param_ty!(Token)) -> bool { cffi_wrapper!(|in_ext_status: Token| { - let mut pool = pull_writer!(EXT_STATUE_POOL)?; + let mut pool = pull_writer!(EXT_STATUS_POOL)?; Ok(pool.free(in_ext_status)?) }) } @@ -582,7 +689,7 @@ pub extern "C" fn WFExtStatusGetName( out_name: out_param_ty!(CStyleString), ) -> bool { cffi_wrapper!(|in_ext_status: Token| -> (out_name: CStyleString) { - let pool = pull_reader!(EXT_STATUE_POOL)?; + let pool = pull_reader!(EXT_STATUS_POOL)?; let ext_status = pool.get(in_ext_status)?; cstr_ffi::set_ffi_string(ext_status.get_name())?; @@ -596,15 +703,78 @@ pub extern "C" fn WFExtStatusGetIcon( out_icon: out_param_ty!(HICON), ) -> bool { cffi_wrapper!(|in_ext_status: Token| -> (out_icon: HICON) { - let pool = pull_reader!(EXT_STATUE_POOL)?; + let pool = pull_reader!(EXT_STATUS_POOL)?; let ext_status = pool.get(in_ext_status)?; let icon = match ext_status.get_icon() { Some(icon) => icon.get_icon(), - None => ffi_types::INVALID_ICON, + None => ffi_types::INVALID_HICON, }; Ok(icon) }) } // endregion + +// region: Icon Resource + +#[unsafe(no_mangle)] +pub extern "C" fn WFIconRcDestroy(in_icon_rc: in_param_ty!(Token)) -> bool { + cffi_wrapper!(|in_icon_rc: Token| { + let mut pool = pull_writer!(ICON_RC_POOL)?; + Ok(pool.free(in_icon_rc)?) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFIconRcGetIcon( + in_icon_rc: in_param_ty!(Token), + out_icon: out_param_ty!(HICON), +) -> bool { + cffi_wrapper!(|in_icon_rc: Token| -> (out_icon: HICON) { + let pool = pull_reader!(ICON_RC_POOL)?; + let icon_rc = pool.get(in_icon_rc)?; + + Ok(icon_rc.get_icon()) + }) +} + +// endregion + +// region: File Extension + +#[unsafe(no_mangle)] +pub extern "C" fn WFExtDestroy(in_ext: in_param_ty!(Token)) -> bool { + cffi_wrapper!(|in_ext: Token| { + let mut pool = pull_writer!(EXT_POOL)?; + Ok(pool.free(in_ext)?) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFExtGetInner( + in_ext: in_param_ty!(Token), + out_inner: out_param_ty!(CStyleString), +) -> bool { + cffi_wrapper!(|in_ext: Token| -> (out_inner: CStyleString) { + let pool = pull_reader!(EXT_POOL)?; + let ext = pool.get(in_ext)?; + cstr_ffi::set_ffi_string(ext.inner())?; + Ok(cstr_ffi::get_ffi_string()) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFExtGetDottedInner( + in_ext: in_param_ty!(Token), + out_inner: out_param_ty!(CStyleString), +) -> bool { + cffi_wrapper!(|in_ext: Token| -> (out_inner: CStyleString) { + let pool = pull_reader!(EXT_POOL)?; + let ext = pool.get(in_ext)?; + cstr_ffi::set_ffi_string(&ext.dotted_inner())?; + Ok(cstr_ffi::get_ffi_string()) + }) +} + +// endregion diff --git a/wfassoc/src/highlevel/program.rs b/wfassoc/src/highlevel/program.rs index d66bb2c..e82ae92 100644 --- a/wfassoc/src/highlevel/program.rs +++ b/wfassoc/src/highlevel/program.rs @@ -268,12 +268,20 @@ impl Program { } impl Program { - pub fn resolve_name(&self) -> Result { - todo!() + pub fn resolve_name(&self) -> Result, ProgramError> { + Ok(self + .name + .as_ref() + .map(|name| name.inner.extract().ok()) + .flatten()) } - pub fn resolve_icon(&self) -> Result { - todo!() + pub fn resolve_icon(&self) -> Result, ProgramError> { + Ok(self + .icon + .as_ref() + .map(|icon| icon.inner.extract(concept::IconSizeKind::Small).ok()) + .flatten()) } pub fn exts_len(&self) -> usize {