use crate::{
PdfiumStructElement, PdfiumStructElementAttrValue,
error::{PdfiumError, PdfiumResult},
lib,
pdfium_types::{FPDF_STRUCTELEMENT_ATTR, Handle, StructElementAttrHandle},
};
#[derive(Debug, Clone)]
pub struct PdfiumStructElementAttr {
handle: StructElementAttrHandle,
owner: Option<PdfiumStructElement>,
}
impl PdfiumStructElementAttr {
pub(crate) fn new_from_handle(handle: FPDF_STRUCTELEMENT_ATTR) -> PdfiumResult<Self> {
if handle.is_null() {
Err(PdfiumError::NullHandle)
} else {
Ok(Self {
handle: Handle::new_const(handle),
owner: None,
})
}
}
pub(crate) fn set_owner(&mut self, owner: PdfiumStructElement) {
self.owner = Some(owner);
}
pub fn count(&self) -> i32 {
lib().FPDF_StructElement_Attr_GetCount(self)
}
pub fn name(&self, index: i32) -> Option<String> {
let mut len: std::os::raw::c_ulong = 0;
if lib()
.FPDF_StructElement_Attr_GetName(self, index, None, 0, &mut len)
.is_ok()
&& len > 0
{
let mut buffer = vec![0u8; len as usize];
if lib()
.FPDF_StructElement_Attr_GetName(self, index, Some(&mut buffer), len, &mut len)
.is_ok()
{
let end = buffer.iter().position(|&b| b == 0).unwrap_or(buffer.len());
return Some(String::from_utf8_lossy(&buffer[..end]).into_owned());
}
}
None
}
pub fn value(&self, name: &str) -> Option<PdfiumStructElementAttrValue> {
let c_name = std::ffi::CString::new(name).ok()?;
let mut val = lib().FPDF_StructElement_Attr_GetValue(self, &c_name).ok()?;
val.set_owner(self.clone());
Some(val)
}
}
impl From<&PdfiumStructElementAttr> for FPDF_STRUCTELEMENT_ATTR {
fn from(struct_element_attr: &PdfiumStructElementAttr) -> Self {
struct_element_attr.handle.handle()
}
}