use crate::{
PdfiumStructElementAttr,
error::{PdfiumError, PdfiumResult},
lib,
pdfium_types::{FPDF_STRUCTELEMENT_ATTR_VALUE, Handle, StructElementAttrValueHandle},
};
#[derive(Debug, Clone)]
pub struct PdfiumStructElementAttrValue {
handle: StructElementAttrValueHandle,
owner: Option<PdfiumStructElementAttr>,
}
impl PdfiumStructElementAttrValue {
pub(crate) fn new_from_handle(handle: FPDF_STRUCTELEMENT_ATTR_VALUE) -> 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: PdfiumStructElementAttr) {
self.owner = Some(owner);
}
pub fn value_type(&self) -> i32 {
lib().FPDF_StructElement_Attr_GetType(self)
}
pub fn boolean_value(&self) -> Option<bool> {
let mut value = 0;
if lib()
.FPDF_StructElement_Attr_GetBooleanValue(self, &mut value)
.is_ok()
{
Some(value != 0)
} else {
None
}
}
pub fn number_value(&self) -> Option<f32> {
let mut value = 0.0;
if lib()
.FPDF_StructElement_Attr_GetNumberValue(self, &mut value)
.is_ok()
{
Some(value)
} else {
None
}
}
pub fn string_value(&self) -> Option<String> {
let mut len: std::os::raw::c_ulong = 0;
if lib()
.FPDF_StructElement_Attr_GetStringValue(self, None, 0, &mut len)
.is_ok()
&& len > 0
{
let mut buffer = vec![0u8; len as usize];
if lib()
.FPDF_StructElement_Attr_GetStringValue(self, Some(&mut buffer), len, &mut len)
.is_ok()
{
let u16_buffer: Vec<u16> = buffer
.chunks_exact(2)
.map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]]))
.take_while(|&c| c != 0)
.collect();
return Some(String::from_utf16_lossy(&u16_buffer));
}
}
None
}
pub fn blob_value(&self) -> Option<Vec<u8>> {
let mut len: std::os::raw::c_ulong = 0;
if lib()
.FPDF_StructElement_Attr_GetBlobValue(self, None, 0, &mut len)
.is_ok()
&& len > 0
{
let mut buffer = vec![0u8; len as usize];
if lib()
.FPDF_StructElement_Attr_GetBlobValue(self, Some(&mut buffer), len, &mut len)
.is_ok()
{
return Some(buffer);
}
}
None
}
pub fn count_children(&self) -> i32 {
lib().FPDF_StructElement_Attr_CountChildren(self)
}
pub fn get_child_at_index(&self, index: i32) -> PdfiumResult<PdfiumStructElementAttrValue> {
let mut child = lib().FPDF_StructElement_Attr_GetChildAtIndex(self, index)?;
if let Some(owner) = &self.owner {
child.set_owner(owner.clone());
}
Ok(child)
}
}
impl From<&PdfiumStructElementAttrValue> for FPDF_STRUCTELEMENT_ATTR_VALUE {
fn from(struct_element_attr_value: &PdfiumStructElementAttrValue) -> Self {
struct_element_attr_value.handle.handle()
}
}