micropdf 0.16.0

A pure Rust PDF library - A pure Rust PDF library with fz_/pdf_ API compatibility
//! PDF Object Creation FFI Functions

use super::super::Handle;
use super::types::{PDF_OBJECTS, PdfObj, PdfObjHandle};
use std::ffi::{CStr, c_char};

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_null(_ctx: Handle) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_null())
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_bool(_ctx: Handle, b: i32) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_bool(b != 0))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_int(_ctx: Handle, i: i64) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_int(i))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_real(_ctx: Handle, f: f32) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_real(f as f64))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_name(_ctx: Handle, str: *const c_char) -> PdfObjHandle {
    if str.is_null() {
        return PDF_OBJECTS.insert(PdfObj::new_name(""));
    }
    let name = unsafe { CStr::from_ptr(str) }.to_str().unwrap_or("");
    PDF_OBJECTS.insert(PdfObj::new_name(name))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_string(_ctx: Handle, str: *const c_char, len: usize) -> PdfObjHandle {
    if str.is_null() || len == 0 {
        return PDF_OBJECTS.insert(PdfObj::new_string(&[]));
    }
    let data = unsafe { std::slice::from_raw_parts(str as *const u8, len) };
    PDF_OBJECTS.insert(PdfObj::new_string(data))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_text_string(_ctx: Handle, s: *const c_char) -> PdfObjHandle {
    if s.is_null() {
        return PDF_OBJECTS.insert(PdfObj::new_string(&[]));
    }
    let text = unsafe { CStr::from_ptr(s) }.to_str().unwrap_or("");
    PDF_OBJECTS.insert(PdfObj::new_string(text.as_bytes()))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_indirect(
    _ctx: Handle,
    _doc: Handle,
    num: i32,
    generation: i32,
) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_indirect(num, generation))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_array(_ctx: Handle, _doc: Handle, initialcap: i32) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_array(initialcap.max(0) as usize))
}

#[unsafe(no_mangle)]
pub extern "C" fn pdf_new_dict(_ctx: Handle, _doc: Handle, initialcap: i32) -> PdfObjHandle {
    PDF_OBJECTS.insert(PdfObj::new_dict(initialcap.max(0) as usize))
}

#[cfg(test)]
mod tests {
    use super::super::check::{
        pdf_is_bool, pdf_is_int, pdf_is_name, pdf_is_null, pdf_is_real, pdf_is_string,
    };
    use super::*;
    use std::ffi::CString;

    #[test]
    fn test_pdf_new_null() {
        let obj = pdf_new_null(0);
        assert_eq!(pdf_is_null(0, obj), 1);
    }

    #[test]
    fn test_pdf_new_bool() {
        let obj = pdf_new_bool(0, 1);
        assert_eq!(pdf_is_bool(0, obj), 1);
    }

    #[test]
    fn test_pdf_new_int() {
        let obj = pdf_new_int(0, 42);
        assert_eq!(pdf_is_int(0, obj), 1);
    }

    #[test]
    fn test_pdf_new_real() {
        let obj = pdf_new_real(0, 3.14);
        assert_eq!(pdf_is_real(0, obj), 1);
    }

    #[test]
    fn test_pdf_new_text_string() {
        let s = CString::new("hello").unwrap();
        let obj = pdf_new_text_string(0, s.as_ptr());
        assert_eq!(pdf_is_string(0, obj), 1);
    }

    #[test]
    fn test_pdf_new_text_string_null() {
        let obj = pdf_new_text_string(0, std::ptr::null());
        assert_eq!(pdf_is_string(0, obj), 1);
    }

    #[test]
    fn test_pdf_new_name() {
        let s = CString::new("Type").unwrap();
        let obj = pdf_new_name(0, s.as_ptr());
        assert_eq!(pdf_is_name(0, obj), 1);
    }
}