pdfium_render/pdf/action/
uri.rs1use crate::bindgen::{FPDF_ACTION, FPDF_DOCUMENT};
5use crate::error::PdfiumError;
6use crate::pdf::action::private::internal::PdfActionPrivate;
7use crate::pdfium::PdfiumLibraryBindingsAccessor;
8use crate::utils::mem::create_byte_buffer;
9use std::ffi::{c_void, CString};
10use std::marker::PhantomData;
11
12pub struct PdfActionUri<'a> {
13 handle: FPDF_ACTION,
14 document: FPDF_DOCUMENT,
15 lifetime: PhantomData<&'a FPDF_ACTION>,
16}
17
18impl<'a> PdfActionUri<'a> {
19 #[inline]
20 pub(crate) fn from_pdfium(handle: FPDF_ACTION, document: FPDF_DOCUMENT) -> Self {
21 PdfActionUri {
22 handle,
23 document,
24 lifetime: PhantomData,
25 }
26 }
27
28 pub fn uri(&self) -> Result<String, PdfiumError> {
30 let buffer_length = unsafe {
40 self.bindings().FPDFAction_GetURIPath(
41 self.document,
42 self.handle,
43 std::ptr::null_mut(),
44 0,
45 )
46 };
47
48 if buffer_length == 0 {
49 return Err(PdfiumError::NoUriForAction);
52 }
53
54 let mut buffer = create_byte_buffer(buffer_length as usize);
55
56 let result = unsafe {
57 self.bindings().FPDFAction_GetURIPath(
58 self.document,
59 self.handle,
60 buffer.as_mut_ptr() as *mut c_void,
61 buffer_length,
62 )
63 };
64
65 assert_eq!(result, buffer_length);
66
67 if let Ok(result) = CString::from_vec_with_nul(buffer) {
68 result
69 .into_string()
70 .map_err(PdfiumError::CStringConversionError)
71 } else {
72 Err(PdfiumError::NoUriForAction)
73 }
74 }
75}
76
77impl<'a> PdfActionPrivate<'a> for PdfActionUri<'a> {
78 #[inline]
79 fn handle(&self) -> &FPDF_ACTION {
80 &self.handle
81 }
82}
83
84impl<'a> PdfiumLibraryBindingsAccessor<'a> for PdfActionUri<'a> {}
85
86#[cfg(feature = "thread_safe")]
87unsafe impl<'a> Send for PdfActionUri<'a> {}
88
89#[cfg(feature = "thread_safe")]
90unsafe impl<'a> Sync for PdfActionUri<'a> {}