use crate::bindgen::FPDF_DOCUMENT;
use crate::bindings::PdfiumLibraryBindings;
use crate::error::{PdfiumError, PdfiumInternalError};
use crate::signature::PdfSignature;
use std::ops::{Range, RangeInclusive};
use std::os::raw::c_int;
pub type PdfSignatureIndex = u16;
pub struct PdfSignatures<'a> {
document_handle: FPDF_DOCUMENT,
bindings: &'a dyn PdfiumLibraryBindings,
}
impl<'a> PdfSignatures<'a> {
#[inline]
pub(crate) fn from_pdfium(
document_handle: FPDF_DOCUMENT,
bindings: &'a dyn PdfiumLibraryBindings,
) -> Self {
PdfSignatures {
document_handle,
bindings,
}
}
#[inline]
pub fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
self.bindings
}
pub fn len(&self) -> PdfSignatureIndex {
self.bindings().FPDF_GetSignatureCount(self.document_handle) as PdfSignatureIndex
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_range(&self) -> Range<PdfSignatureIndex> {
0..self.len()
}
#[inline]
pub fn as_range_inclusive(&self) -> RangeInclusive<PdfSignatureIndex> {
if self.is_empty() {
0..=0
} else {
0..=(self.len() - 1)
}
}
pub fn get(&self, index: PdfSignatureIndex) -> Result<PdfSignature<'a>, PdfiumError> {
if index >= self.len() {
return Err(PdfiumError::SignatureIndexOutOfBounds);
}
let handle = self
.bindings()
.FPDF_GetSignatureObject(self.document_handle, index as c_int);
if handle.is_null() {
if let Some(error) = self.bindings().get_pdfium_last_error() {
Err(PdfiumError::PdfiumLibraryInternalError(error))
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
} else {
Ok(PdfSignature::from_pdfium(handle, self.bindings()))
}
}
#[inline]
pub fn iter(&self) -> PdfSignaturesIterator {
PdfSignaturesIterator::new(self)
}
}
pub struct PdfSignaturesIterator<'a> {
signatures: &'a PdfSignatures<'a>,
next_index: PdfSignatureIndex,
}
impl<'a> PdfSignaturesIterator<'a> {
#[inline]
pub(crate) fn new(signatures: &'a PdfSignatures<'a>) -> Self {
PdfSignaturesIterator {
signatures,
next_index: 0,
}
}
}
impl<'a> Iterator for PdfSignaturesIterator<'a> {
type Item = PdfSignature<'a>;
fn next(&mut self) -> Option<Self::Item> {
let next = self.signatures.get(self.next_index);
self.next_index += 1;
next.ok()
}
}