use super::document::CPDF_DOCS;
use super::{clear_error, set_error};
use crate::cpdf::ocg;
use crate::ffi::Handle;
use std::ffi::{CStr, CString, c_char};
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_OCGList(doc: Handle, len_out: *mut usize) -> *mut u8 {
clear_error();
let d = match CPDF_DOCS.get(doc) {
Some(arc) => arc,
None => {
set_error(1, &format!("invalid handle: {doc}"));
return std::ptr::null_mut();
}
};
let guard = d.lock().unwrap();
match ocg::list_ocgs(&guard) {
Ok(names) => {
let json = match serde_json::to_string_pretty(&names) {
Ok(j) => j,
Err(e) => {
set_error(1, &e.to_string());
return std::ptr::null_mut();
}
};
let bytes = json.into_bytes();
let len = bytes.len();
let ptr = unsafe {
let layout = std::alloc::Layout::from_size_align_unchecked(len, 1);
let p = std::alloc::alloc(layout);
if p.is_null() {
set_error(1, "alloc failed");
return std::ptr::null_mut();
}
std::ptr::copy_nonoverlapping(bytes.as_ptr(), p, len);
p
};
if !len_out.is_null() {
unsafe {
*len_out = len;
}
}
ptr
}
Err(e) => {
set_error(1, &e.to_string());
std::ptr::null_mut()
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_OCGRename(doc: Handle, from: *const c_char, to: *const c_char) -> Handle {
clear_error();
let d = match CPDF_DOCS.get(doc) {
Some(arc) => arc.lock().unwrap().clone(),
None => {
set_error(1, &format!("invalid handle: {doc}"));
return 0;
}
};
let f = if from.is_null() {
""
} else {
unsafe { CStr::from_ptr(from) }.to_str().unwrap_or("")
};
let t = if to.is_null() {
""
} else {
unsafe { CStr::from_ptr(to) }.to_str().unwrap_or("")
};
match ocg::rename_ocg(d, f, t) {
Ok(doc) => CPDF_DOCS.insert(doc),
Err(e) => {
set_error(1, &e.to_string());
0
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_OCGCoalesce(doc: Handle) -> Handle {
clear_error();
let d = match CPDF_DOCS.get(doc) {
Some(arc) => arc.lock().unwrap().clone(),
None => {
set_error(1, &format!("invalid handle: {doc}"));
return 0;
}
};
match ocg::coalesce_ocgs(d) {
Ok(doc) => CPDF_DOCS.insert(doc),
Err(e) => {
set_error(1, &e.to_string());
0
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn cpdf_OCGOrderAll(doc: Handle) -> Handle {
clear_error();
let d = match CPDF_DOCS.get(doc) {
Some(arc) => arc.lock().unwrap().clone(),
None => {
set_error(1, &format!("invalid handle: {doc}"));
return 0;
}
};
match ocg::order_all_ocgs(d) {
Ok(doc) => CPDF_DOCS.insert(doc),
Err(e) => {
set_error(1, &e.to_string());
0
}
}
}