feat: #37 Batch2+3 — 全部函数迁移到 out-pointer FFI
新增 8 个 _separate 函数: - push_reading_event_separate - update_reading_position_separate - export_pending_events_separate - create_note_anchor_separate - search_markdown_blocks_separate - search_text_content_separate 新增 lift_from_raw! 宏用于从原始 buffer 参数反序列化复杂类型。 原 #[uniffi::export] 函数保留(macOS/Android 路径可用)。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c09caab0e6
commit
1a246445fe
@ -324,6 +324,98 @@ pub extern "C" fn ffi_zx_document_ffi_parse_text_separate(
|
|||||||
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Helper: lift from raw buffer fields ───
|
||||||
|
|
||||||
|
macro_rules! lift_from_raw {
|
||||||
|
($T:ty, $capacity:expr, $len:expr, $data:expr) => {{
|
||||||
|
let v = unsafe { Vec::from_raw_parts($data as *mut u8, $len as usize, $capacity as usize) };
|
||||||
|
let buf = uniffi::RustBuffer::from_vec(v);
|
||||||
|
<$T as uniffi::Lift<UniFfiTag>>::try_lift(buf).expect(concat!("failed to lift ", stringify!($T)))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Batch 2: complex type input/output ───
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_push_reading_event_separate(
|
||||||
|
event_cap: u64, event_len: u64, event_data: *const u8,
|
||||||
|
) {
|
||||||
|
let event: ReadingEvent = lift_from_raw!(ReadingEvent, event_cap, event_len, event_data);
|
||||||
|
crate::push_reading_event(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_update_reading_position_separate(
|
||||||
|
mid_len: i32, mid_data: *const u8,
|
||||||
|
pos_cap: u64, pos_len: u64, pos_data: *const u8,
|
||||||
|
out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let material_id = match unsafe { read_str_input(mid_len, mid_data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
unsafe { *out_error_code = 0; }
|
||||||
|
let position: ReadingPosition = lift_from_raw!(ReadingPosition, pos_cap, pos_len, pos_data);
|
||||||
|
crate::update_reading_position(material_id, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_export_pending_events_separate(
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let result: Vec<ReadingEvent> = crate::export_pending_events();
|
||||||
|
write_result_to_out!(Ok::<_, DocumentError>(result), out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_create_note_anchor_separate(
|
||||||
|
mid_len: i32, mid_data: *const u8,
|
||||||
|
pos_cap: u64, pos_len: u64, pos_data: *const u8, pos_has_value: i8,
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let material_id = match unsafe { read_str_input(mid_len, mid_data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let position: Option<ReadingPosition> = if pos_has_value != 0 {
|
||||||
|
Some(lift_from_raw!(ReadingPosition, pos_cap, pos_len, pos_data))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let result: Result<NoteAnchor, DocumentError> = Ok(crate::create_note_anchor(material_id, position));
|
||||||
|
write_result_to_out!(result, out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Batch 3: search functions ───
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_search_markdown_blocks_separate(
|
||||||
|
blocks_cap: u64, blocks_len: u64, blocks_data: *const u8,
|
||||||
|
query_len: i32, query_data: *const u8,
|
||||||
|
out_capacity: *mut u64, out_len: *mut u64, out_data: *mut *mut u8, out_error_code: *mut i8,
|
||||||
|
) {
|
||||||
|
let query = match unsafe { read_str_input(query_len, query_data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let blocks: Vec<DocumentBlock> = lift_from_raw!(Vec<DocumentBlock>, blocks_cap, blocks_len, blocks_data);
|
||||||
|
let result: Vec<SearchResult> = crate::search_markdown_blocks(blocks, query);
|
||||||
|
write_result_to_out!(Ok::<_, DocumentError>(result), out_capacity, out_len, out_data, out_error_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ffi_zx_document_ffi_search_text_content_separate(
|
||||||
|
content_len: i32, content_data: *const u8,
|
||||||
|
query_len: i32, query_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(content_len, content_data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let query = match unsafe { read_str_input(query_len, query_data, out_error_code) } {
|
||||||
|
Some(s) => s, None => return,
|
||||||
|
};
|
||||||
|
let result: Vec<SearchResult> = crate::search_text_content(content, query);
|
||||||
|
write_result_to_out!(Ok::<_, DocumentError>(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