use std::{
ffi::{CStr, CString},
os::raw::{c_char, c_int, c_void},
slice,
};
pub(crate) struct CXmpString {
pub(crate) s: *const c_char,
}
impl CXmpString {
pub(crate) fn from_ptr(s: *const c_char) -> Self {
Self { s }
}
pub(crate) fn as_string(&self) -> String {
unsafe { CStr::from_ptr(self.s).to_string_lossy().into_owned() }
}
pub(crate) fn map<U, F>(&self, f: F) -> Option<U>
where
F: FnOnce(String) -> U,
{
if self.s.is_null() {
None
} else {
let s = self.as_string();
Some(f(s))
}
}
}
impl Drop for CXmpString {
fn drop(&mut self) {
unsafe { CXmpStringDrop(self.s) };
}
}
type CXmpTextOutputProc = extern "C" fn(s: *mut c_void, buffer: *const u8, len: u32) -> i32;
pub(crate) extern "C" fn xmp_dump_to_string(s: *mut c_void, buffer: *const u8, len: u32) -> i32 {
unsafe {
let cstr = slice::from_raw_parts(buffer, len as usize);
let cstr = String::from_utf8_lossy(cstr);
let s = &mut *s.cast::<String>();
s.push_str(cstr.as_ref());
}
0
}
#[repr(C)]
pub(crate) struct CXmpError {
pub(crate) had_error: u32,
pub(crate) id: i32,
pub(crate) debug_message: *const c_char,
}
impl CXmpError {
#[allow(dead_code, clippy::unwrap_used)] pub(crate) fn new(had_error: bool, id: i32, debug_message: Option<&str>) -> Self {
Self {
had_error: u32::from(had_error),
id,
debug_message: unsafe {
match debug_message {
Some(debug_message) => {
let debug_message_as_cstr = CString::new(debug_message).unwrap();
CXmpStringCopy(debug_message_as_cstr.as_ptr())
}
None => std::ptr::null(),
}
},
}
}
}
impl Default for CXmpError {
fn default() -> Self {
Self {
had_error: 0,
id: 0,
debug_message: std::ptr::null(),
}
}
}
impl Drop for CXmpError {
fn drop(&mut self) {
unsafe { CXmpStringDrop(self.debug_message) };
self.debug_message = std::ptr::null();
}
}
#[derive(Debug, Default, Eq, PartialEq)]
#[repr(C)]
pub(crate) struct CXmpDateTime {
pub(crate) year: i32,
pub(crate) month: i32,
pub(crate) day: i32,
pub(crate) hour: i32,
pub(crate) minute: i32,
pub(crate) second: i32,
pub(crate) has_date: bool,
pub(crate) has_time: bool,
pub(crate) has_time_zone: bool,
pub(crate) tz_sign: i8,
pub(crate) tz_hour: i32,
pub(crate) tz_minute: i32,
pub(crate) nanosecond: i32,
}
pub(crate) enum CXmpFile {}
pub(crate) enum CXmpMeta {}
pub(crate) enum CXmpIterator {}
extern "C" {
pub(crate) fn CXmpStringCopy(s: *const c_char) -> *const c_char;
pub(crate) fn CXmpStringDrop(s: *const c_char);
pub(crate) fn CXmpFileNew(out_error: *mut CXmpError) -> *mut CXmpFile;
pub(crate) fn CXmpFileDrop(file: *mut CXmpFile);
pub(crate) fn CXmpFileOpen(
file: *mut CXmpFile,
out_error: *mut CXmpError,
path: *const c_char,
flags: u32,
);
pub(crate) fn CXmpFileClose(file: *mut CXmpFile);
pub(crate) fn CXmpFileGetXmp(file: *mut CXmpFile) -> *mut CXmpMeta;
pub(crate) fn CXmpFilePutXmp(
file: *mut CXmpFile,
out_error: *mut CXmpError,
meta: *const CXmpMeta,
);
pub(crate) fn CXmpFileCanPutXmp(file: *const CXmpFile, meta: *const CXmpMeta) -> c_int;
pub(crate) fn CXmpMetaNew(out_error: *mut CXmpError) -> *mut CXmpMeta;
pub(crate) fn CXmpMetaDrop(meta: *mut CXmpMeta);
pub(crate) fn CXmpMetaClone(m: *const CXmpMeta, out_error: *mut CXmpError) -> *mut CXmpMeta;
pub(crate) fn CXmpMetaParseFromBuffer(
out_error: *mut CXmpError,
buffer: *const u8,
buffer_size: u32,
options: u32,
) -> *mut CXmpMeta;
pub(crate) fn CXmpMetaSerializeToBuffer(
meta: *const CXmpMeta,
out_error: *mut CXmpError,
options: u32,
padding: u32,
newline: *const c_char,
indent: *const c_char,
base_indent: u32,
) -> *const c_char;
pub(crate) fn CXmpMetaRegisterNamespace(
out_error: *mut CXmpError,
namespace_uri: *const c_char,
suggested_prefix: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpMetaGetNamespacePrefix(
out_error: *mut CXmpError,
namespace_uri: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpMetaGetNamespaceURI(
out_error: *mut CXmpError,
namespace_prefix: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpDumpNamespaces(out_string: *mut c_void, callback: CXmpTextOutputProc);
pub(crate) fn CXmpMetaGetProperty(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
out_options: *mut u32,
) -> *const c_char;
pub(crate) fn CXmpMetaGetProperty_Bool(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
out_value: *mut bool,
out_options: *mut u32,
) -> bool;
pub(crate) fn CXmpMetaGetProperty_Int(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
out_value: *mut i32,
out_options: *mut u32,
) -> bool;
pub(crate) fn CXmpMetaGetProperty_Int64(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
out_value: *mut i64,
out_options: *mut u32,
) -> bool;
pub(crate) fn CXmpMetaGetProperty_Float(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
out_value: *mut f64,
out_options: *mut u32,
) -> bool;
pub(crate) fn CXmpMetaGetProperty_Date(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
out_value: *mut CXmpDateTime,
out_options: *mut u32,
) -> bool;
pub(crate) fn CXmpMetaGetStructField(
meta: *const CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
struct_name: *const c_char,
field_ns: *const c_char,
field_name: *const c_char,
out_options: *mut u32,
) -> *const c_char;
pub(crate) fn CXmpMetaSetProperty(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
prop_value: *const c_char,
options: u32,
);
pub(crate) fn CXmpMetaSetProperty_Bool(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
prop_value: bool,
options: u32,
);
pub(crate) fn CXmpMetaSetProperty_Int(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
prop_value: i32,
options: u32,
);
pub(crate) fn CXmpMetaSetProperty_Int64(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
prop_value: i64,
options: u32,
);
pub(crate) fn CXmpMetaSetProperty_Float(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
prop_value: f64,
options: u32,
);
pub(crate) fn CXmpMetaSetProperty_Date(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
prop_value: *const CXmpDateTime,
options: u32,
);
pub(crate) fn CXmpMetaDeleteProperty(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
);
pub(crate) fn CXmpMetaSetArrayItem(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
array_name: *const c_char,
item_index: u32,
item_value: *const c_char,
item_options: u32,
);
pub(crate) fn CXmpMetaAppendArrayItem(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
array_name: *const c_char,
array_options: u32,
item_value: *const c_char,
item_options: u32,
);
pub(crate) fn CXmpMetaDeleteArrayItem(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
array_name: *const c_char,
item_index: i32,
);
pub(crate) fn CXmpMetaCountArrayItems(
meta: *const CXmpMeta,
out_error: *mut CXmpError,
array_ns: *const c_char,
array_name: *const c_char,
count: *mut u32,
) -> bool;
pub(crate) fn CXmpMetaSetStructField(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
struct_name: *const c_char,
field_ns: *const c_char,
field_name: *const c_char,
item_value: *const c_char,
item_options: u32,
);
pub(crate) fn CXmpMetaDeleteStructField(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
struct_name: *const c_char,
field_ns: *const c_char,
field_name: *const c_char,
);
pub(crate) fn CXmpMetaGetQualifier(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
qual_ns: *const c_char,
qual_name: *const c_char,
out_qual_options: *mut u32,
) -> *const c_char;
pub(crate) fn CXmpMetaSetQualifier(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
qual_ns: *const c_char,
qual_name: *const c_char,
qual_value: *const c_char,
qual_options: u32,
);
pub(crate) fn CXmpMetaDeleteQualifier(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
prop_ns: *const c_char,
prop_name: *const c_char,
qual_ns: *const c_char,
qual_name: *const c_char,
);
pub(crate) fn CXmpMetaDoesPropertyExist(
meta: *const CXmpMeta,
schema_ns: *const c_char,
prop_name: *const c_char,
) -> c_int;
pub(crate) fn CXmpMetaDoesStructFieldExist(
meta: *const CXmpMeta,
schema_ns: *const c_char,
struct_name: *const c_char,
field_ns: *const c_char,
field_name: *const c_char,
) -> c_int;
pub(crate) fn CXmpMetaDoesQualifierExist(
meta: *const CXmpMeta,
prop_ns: *const c_char,
prop_name: *const c_char,
qual_ns: *const c_char,
qual_name: *const c_char,
) -> c_int;
pub(crate) fn CXmpMetaGetArrayItem(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
index: i32,
out_options: *mut u32,
) -> *const c_char;
pub(crate) fn CXmpMetaGetLocalizedText(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
alt_text_name: *const c_char,
generic_lang: *const c_char,
specific_lang: *const c_char,
out_actual_lang: *mut *const c_char,
out_options: *mut u32,
) -> *const c_char;
pub(crate) fn CXmpMetaSetLocalizedText(
meta: *const CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
alt_text_name: *const c_char,
generic_lang: *const c_char,
specific_lang: *const c_char,
item_value: *const c_char,
options: u32,
);
pub(crate) fn CXmpMetaSort(meta: *mut CXmpMeta, out_error: *mut CXmpError);
pub(crate) fn CXmpMetaGetObjectName(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
) -> *const c_char;
pub(crate) fn CXmpMetaSetObjectName(
meta: *mut CXmpMeta,
out_error: *mut CXmpError,
name: *const c_char,
);
pub(crate) fn CXmpMetaComposeArrayItemPath(
out_error: *mut CXmpError,
schema_ns: *const c_char,
array_name: *const c_char,
index: i32,
) -> *const c_char;
pub(crate) fn CXmpMetaComposeLangSelector(
out_error: *mut CXmpError,
schema_ns: *const c_char,
array_name: *const c_char,
lang_name: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpMetaComposeFieldSelector(
out_error: *mut CXmpError,
schema_ns: *const c_char,
struct_name: *const c_char,
field_ns: *const c_char,
field_name: *const c_char,
field_value: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpMetaComposeQualifierPath(
out_error: *mut CXmpError,
schema_ns: *const c_char,
struct_name: *const c_char,
qual_ns: *const c_char,
qual_name: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpMetaComposeStructFieldPath(
out_error: *mut CXmpError,
schema_ns: *const c_char,
struct_name: *const c_char,
field_ns: *const c_char,
field_name: *const c_char,
) -> *const c_char;
pub(crate) fn CXmpMetaDumpObj(
meta: *mut CXmpMeta,
out_string: *mut c_void,
callback: CXmpTextOutputProc,
);
pub(crate) fn CXmpIteratorNew(
m: *const CXmpMeta,
out_error: *mut CXmpError,
schema_ns: *const c_char,
prop_name: *const c_char,
options: u32,
) -> *mut CXmpIterator;
pub(crate) fn CXmpIteratorDrop(i: *mut CXmpIterator);
pub(crate) fn CXmpIteratorNext(
i: *mut CXmpIterator,
out_error: *mut CXmpError,
out_schema_ns: *mut *const c_char,
out_prop_path: *mut *const c_char,
out_prop_value: *mut *const c_char,
out_options: *mut u32,
) -> bool;
pub(crate) fn CXmpIteratorSkip(i: *mut CXmpIterator, out_error: *mut CXmpError, options: u32);
pub(crate) fn CXmpDateTimeCurrent(dt: *mut CXmpDateTime, out_error: *mut CXmpError);
pub(crate) fn CXmpDateTimeSetTimeZone(dt: *mut CXmpDateTime, out_error: *mut CXmpError);
pub(crate) fn CXmpDateTimeConvertToLocalTime(dt: *mut CXmpDateTime, out_error: *mut CXmpError);
pub(crate) fn CXmpDateTimeConvertToUTCTime(dt: *mut CXmpDateTime, out_error: *mut CXmpError);
pub(crate) fn CXmpDateTimeToString(
dt: *const CXmpDateTime,
out_error: *mut CXmpError,
) -> *const c_char;
}