feat: #37 Batch1 — detect_material_type/read_image_meta/read_text_stats/parse_text out-pointer FFI
新增 4 个 _separate 函数绕过 RustBuffer struct-passing: - ffi_zx_document_ffi_detect_material_type_separate - ffi_zx_document_ffi_read_image_meta_separate - ffi_zx_document_ffi_read_text_stats_separate - ffi_zx_document_ffi_parse_text_separate 提取 write_result_to_out! 宏和 read_str_input helper 减少样板代码。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
65c9ab8a50
commit
c09caab0e6
@ -242,6 +242,88 @@ fn clear_exported_events(count: u32) {
|
|||||||
zx_document_core::events::clear_exported_events(count as usize)
|
zx_document_core::events::clear_exported_events(count as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper: serialize a Result<T, DocumentError> into out-pointers.
|
||||||
|
/// Generic over T; the RustBuffer methods are accessed via the concrete type
|
||||||
|
/// after the `lower_return` call.
|
||||||
|
macro_rules! write_result_to_out {
|
||||||
|
($result:expr, $out_capacity:ident, $out_len:ident, $out_data:ident, $out_error_code:ident) => {{
|
||||||
|
use uniffi::LowerReturn;
|
||||||
|
match <Result<_, DocumentError> as LowerReturn<UniFfiTag>>::lower_return($result) {
|
||||||
|
Ok(buf) => {
|
||||||
|
unsafe {
|
||||||
|
*$out_capacity = buf.capacity() as u64;
|
||||||
|
*$out_len = buf.len() as u64;
|
||||||
|
*$out_data = buf.data_pointer() as *mut u8;
|
||||||
|
*$out_error_code = 0;
|
||||||
|
}
|
||||||
|
std::mem::forget(buf);
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
unsafe { *$out_error_code = -1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper: read a UTF-8 string from raw bytes, or set error and return false.
|
||||||
|
unsafe fn read_str_input(len: i32, data: *const u8, out_error_code: *mut i8) -> Option<String> {
|
||||||
|
let slice = std::slice::from_raw_parts(data, len as usize);
|
||||||
|
match std::str::from_utf8(slice) {
|
||||||
|
Ok(s) => Some(s.to_string()),
|
||||||
|
Err(_) => { *out_error_code = -1; None },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Batch 1 out-pointer functions: String input → Result<T, E> output ───
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_detect_material_type_separate(
|
||||||
|
len: i32, data: *const u8,
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let file_path = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let result = crate::detect_material_type(file_path);
|
||||||
|
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_read_image_meta_separate(
|
||||||
|
len: i32, data: *const u8,
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let file_path = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let result = crate::read_image_meta(file_path);
|
||||||
|
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_read_text_stats_separate(
|
||||||
|
len: i32, data: *const u8,
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let file_path = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let result = crate::read_text_stats(file_path);
|
||||||
|
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_parse_text_separate(
|
||||||
|
len: i32, data: *const u8,
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let content = match unsafe { read_str_input(len, data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let result = crate::parse_text(content);
|
||||||
|
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
// Reverse conversion: FFI DocumentBlock → core DocumentBlock, used by search.
|
// Reverse conversion: FFI DocumentBlock → core DocumentBlock, used by search.
|
||||||
fn core_block_from_ffi(block: DocumentBlock) -> core_blocks::DocumentBlock {
|
fn core_block_from_ffi(block: DocumentBlock) -> core_blocks::DocumentBlock {
|
||||||
match block {
|
match block {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user