#include <cstring>
#include <mutex>
#include <string>
#define TXMP_STRING_TYPE std::string
#define XMP_INCLUDE_XMPFILES 1
#include "XMP.incl_cpp"
#ifndef NOOP_FFI
#include "XMP.hpp"
#endif
std::once_flag xmp_init_flag;
static volatile bool xmp_init_succeeded = false;
inline void init_xmp_fn() {
#ifndef NOOP_FFI
try {
SXMPMeta::Initialize();
SXMPFiles::Initialize(kXMPFiles_IgnoreLocalText);
xmp_init_succeeded = true;
}
catch (XMP_Error& e) {
fprintf(stderr, "Failed to initialize XMP Toolkit: %s\n", e.GetErrMsg());
}
#endif
}
static bool init_xmp() {
std::call_once(xmp_init_flag, init_xmp_fn);
return xmp_init_succeeded;
}
static const char* copyStringForResult(const std::string& result) {
size_t size = result.size();
void* cstr = malloc(size + 1);
memcpy(cstr, result.c_str(), size + 1);
return (const char*) cstr;
}
static const char* copyStringForResult(const char* result) {
size_t size = strlen(result);
void* cstr = malloc(size + 1);
memcpy(cstr, result, size + 1);
return (const char*) cstr;
}
extern "C" {
typedef struct CXmpError {
AdobeXMPCommon::int32 hadError;
AdobeXMPCommon::int32 id;
const char* debugMessage;
CXmpError() {
debugMessage = NULL;
reset();
}
void reset() {
hadError = 0;
id = 0;
free((void*) debugMessage);
debugMessage = NULL;
}
} CXmpError;
}
static void copyErrorForResult(XMP_Error& e, CXmpError* outError) {
if (outError) {
outError->hadError = 1;
outError->id = e.GetID();
free((void*) outError->debugMessage);
outError->debugMessage = copyStringForResult(e.GetErrMsg());
}
}
static void signalUnknownError(CXmpError* outError) {
if (outError) {
outError->hadError = 1;
outError->id = kXMPErr_Unknown;
free((void*) outError->debugMessage);
outError->debugMessage = NULL;
}
}
static void signalXmpInitFailure(CXmpError* outError) {
if (outError) {
outError->hadError = 1;
outError->id = kXMPErr_Unknown;
free((void*) outError->debugMessage);
outError->debugMessage = copyStringForResult("XMP Toolkit unavailable");
}
}
static bool xmpFileErrorCallback(void* context,
XMP_StringPtr filePath,
XMP_ErrorSeverity severity,
AdobeXMPCommon::int32 cause,
XMP_StringPtr message) {
CXmpError* err = (CXmpError*) context;
if (err) {
err->hadError = 1;
err->id = cause;
free((void*) err->debugMessage);
err->debugMessage = copyStringForResult(message);
}
return false;
}
extern "C" {
typedef struct CXmpFile {
#ifdef NOOP_FFI
int x;
#else
SXMPFiles f;
CXmpError err;
#endif
CXmpFile() {
#ifndef NOOP_FFI
f.SetErrorCallback(xmpFileErrorCallback, &err, 0xffffffff);
#endif
}
} CXmpFile;
typedef struct CXmpMeta {
#ifdef NOOP_FFI
int x;
#else
SXMPMeta m;
#endif
} CXmpMeta;
typedef struct CXmpIterator {
#ifdef NOOP_FFI
int x;
#else
CXmpIterator(SXMPIterator i): i(i) {}
SXMPIterator i;
#endif
} CXmpIterator;
const char* CXmpStringCopy(const char* str) {
return copyStringForResult(str);
}
void CXmpStringDrop(void* str) {
free(str);
}
CXmpFile* CXmpFileNew(CXmpError* outError) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
return new CXmpFile;
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpFileDrop(CXmpFile* f) {
#ifndef NOOP_FFI
delete f;
#endif
}
void CXmpFileOpen(CXmpFile* f,
CXmpError* outError,
const char* filePath,
AdobeXMPCommon::uint32 openFlags) {
#ifndef NOOP_FFI
try {
f->err.reset();
if (!f->f.OpenFile(filePath, kXMP_UnknownFile, openFlags)) {
*outError = f->err;
f->err.reset();
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpFileClose(CXmpFile* f) {
#ifndef NOOP_FFI
f->f.CloseFile();
#endif
}
CXmpMeta* CXmpFileGetXmp(CXmpFile* f) {
#ifndef NOOP_FFI
try {
CXmpMeta* r = new CXmpMeta;
try {
if (f->f.GetXMP(&(r->m))) {
return r;
}
}
catch (...) {
delete r;
}
}
catch (...) {
}
#endif
return NULL;
}
void CXmpFilePutXmp(CXmpFile* f,
CXmpError* outError,
const CXmpMeta* m) {
#ifndef NOOP_FFI
try {
f->f.PutXMP(m->m);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
int CXmpFileCanPutXmp(const CXmpFile* f,
const CXmpMeta* m) {
#ifndef NOOP_FFI
try {
return const_cast<SXMPFiles&>(f->f).CanPutXMP(m->m) ? 1 : 0;
}
catch (...) {
}
#endif
return 0;
}
CXmpMeta* CXmpMetaNew(CXmpError* outError) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
return new CXmpMeta;
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpMetaDrop(CXmpMeta* m) {
#ifndef NOOP_FFI
delete m;
#endif
}
CXmpMeta* CXmpMetaClone(CXmpMeta* m,
CXmpError* outError) {
#ifndef NOOP_FFI
try {
CXmpMeta* result = new CXmpMeta;
result->m = m->m.Clone();
return result;
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
CXmpMeta* CXmpMetaParseFromBuffer(CXmpError* outError,
const char* buffer,
AdobeXMPCommon::uint32 buffer_size,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
CXmpMeta* result = new CXmpMeta;
try {
result->m.ParseFromBuffer(buffer, buffer_size, options);
return result;
}
catch (XMP_Error& e) {
delete result;
copyErrorForResult(e, outError);
}
catch (...) {
delete result;
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaSerializeToBuffer(CXmpMeta* m,
CXmpError* outError,
AdobeXMPCommon::uint32 options,
AdobeXMPCommon::uint32 padding,
const char* newline,
const char* indent,
AdobeXMPCommon::uint32 baseIndent) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string buffer;
m->m.SerializeToBuffer(&buffer, options, padding, newline, indent, baseIndent);
return copyStringForResult(buffer);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaRegisterNamespace(CXmpError* outError,
const char* namespaceURI,
const char* suggestedPrefix) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string registeredPrefix;
SXMPMeta::RegisterNamespace(namespaceURI, suggestedPrefix, ®isteredPrefix);
return copyStringForResult(registeredPrefix);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaGetNamespacePrefix(CXmpError* outError,
const char* namespaceURI) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string outPrefix;
if (SXMPMeta::GetNamespacePrefix(namespaceURI, &outPrefix)) {
return copyStringForResult(outPrefix);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaGetNamespaceURI(CXmpError* outError,
const char* namespacePrefix) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string outURI;
if (SXMPMeta::GetNamespaceURI(namespacePrefix, &outURI)) {
return copyStringForResult(outURI);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpDumpNamespaces(void* rustString, XMP_TextOutputProc callback) {
#ifndef NOOP_FFI
if (init_xmp()) {
try {
SXMPMeta::DumpNamespaces(callback, rustString);
}
catch (...) {
}
}
#endif
}
const char* CXmpMetaGetProperty(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
if (m->m.GetProperty(schemaNS, propName, &propValue, outOptions)) {
return copyStringForResult(propValue);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
bool CXmpMetaGetProperty_Bool(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
bool* outValue,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
if (m->m.GetProperty_Bool(schemaNS, propName, outValue, outOptions)) {
return true;
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return false;
}
bool CXmpMetaGetProperty_Int(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::int32* outValue,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
if (m->m.GetProperty_Int(schemaNS, propName, outValue, outOptions)) {
return true;
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return false;
}
bool CXmpMetaGetProperty_Int64(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::int64* outValue,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
if (m->m.GetProperty_Int64(schemaNS, propName, outValue, outOptions)) {
return true;
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return false;
}
bool CXmpMetaGetProperty_Float(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
double* outValue,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
if (m->m.GetProperty_Float(schemaNS, propName, outValue, outOptions)) {
return true;
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
bool CXmpMetaGetProperty_Date(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
XMP_DateTime* outValue,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
if (m->m.GetProperty_Date(schemaNS, propName, outValue, outOptions)) {
return true;
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return false;
}
void CXmpMetaSetProperty(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
const char* propValue,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetProperty(schemaNS, propName, propValue, options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSetProperty_Bool(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
bool propValue,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetProperty_Bool(schemaNS, propName, propValue, options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSetProperty_Int(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::int32 propValue,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetProperty_Int(schemaNS, propName, propValue, options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSetProperty_Int64(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::int64 propValue,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetProperty_Int64(schemaNS, propName, propValue, options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSetProperty_Float(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
double propValue,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetProperty_Float(schemaNS, propName, propValue, options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSetProperty_Date(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
const XMP_DateTime* propValue,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetProperty_Date(schemaNS, propName, *propValue, options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaDeleteProperty(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName) {
#ifndef NOOP_FFI
try {
m->m.DeleteProperty(schemaNS, propName);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSetArrayItem(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* arrayName,
AdobeXMPCommon::uint32 itemIndex,
const char* itemValue,
AdobeXMPCommon::uint32 itemOptions) {
#ifndef NOOP_FFI
try {
m->m.SetArrayItem(schemaNS, arrayName, itemIndex, itemValue, itemOptions);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaAppendArrayItem(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* arrayName,
AdobeXMPCommon::uint32 arrayOptions,
const char* itemValue,
AdobeXMPCommon::uint32 itemOptions) {
#ifndef NOOP_FFI
try {
m->m.AppendArrayItem(schemaNS, arrayName, arrayOptions, itemValue, itemOptions);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaDeleteArrayItem(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* arrayName,
AdobeXMPCommon::uint32 itemIndex) {
#ifndef NOOP_FFI
try {
m->m.DeleteArrayItem(schemaNS, arrayName, itemIndex);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
bool CXmpMetaCountArrayItems(CXmpMeta* m,
CXmpError* outError,
const char* arrayNS,
const char* arrayName,
AdobeXMPCommon::uint32* outValue) {
*outValue = 0;
#ifndef NOOP_FFI
try {
*outValue = m->m.CountArrayItems(arrayNS, arrayName);
return true;
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return false;
}
const char* CXmpMetaGetStructField(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* structName,
const char* fieldNS,
const char* fieldName,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
if (m->m.GetStructField(schemaNS, structName, fieldNS, fieldName,
&propValue, outOptions)) {
return copyStringForResult(propValue);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpMetaSetStructField(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* structName,
const char* fieldNS,
const char* fieldName,
const char* itemValue,
AdobeXMPCommon::uint32 itemOptions) {
#ifndef NOOP_FFI
try {
m->m.SetStructField(schemaNS, structName, fieldNS, fieldName,
itemValue, itemOptions);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaDeleteStructField(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* structName,
const char* fieldNS,
const char* fieldName) {
#ifndef NOOP_FFI
try {
m->m.DeleteStructField(schemaNS, structName, fieldNS, fieldName);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
const char* CXmpMetaGetQualifier(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
const char* qualNS,
const char* qualName,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string qualValue;
if (m->m.GetQualifier(schemaNS, propName, qualNS, qualName,
&qualValue, outOptions)) {
return copyStringForResult(qualValue);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpMetaSetQualifier(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
const char* qualNS,
const char* qualName,
const char* qualValue,
AdobeXMPCommon::uint32 qualOptions) {
#ifndef NOOP_FFI
try {
m->m.SetQualifier(schemaNS, propName, qualNS, qualName,
qualValue, qualOptions);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaDeleteQualifier(CXmpMeta* m,
CXmpError* outError,
const char* propNS,
const char* propName,
const char* qualNS,
const char* qualName) {
#ifndef NOOP_FFI
try {
m->m.DeleteQualifier(propNS, propName, qualNS, qualName);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
int CXmpMetaDoesPropertyExist(CXmpMeta* m,
const char* schemaNS,
const char* propName) {
#ifndef NOOP_FFI
try {
return (m->m.DoesPropertyExist(schemaNS, propName)) ? 1 : 0;
}
catch (...) {
}
#endif
return 0;
}
int CXmpMetaDoesStructFieldExist(CXmpMeta* m,
const char* schemaNS,
const char* structName,
const char* fieldNS,
const char* fieldName) {
#ifndef NOOP_FFI
try {
return (m->m.DoesStructFieldExist(schemaNS, structName, fieldNS, fieldName)) ? 1 : 0;
}
catch (...) {
}
#endif
return 0;
}
int CXmpMetaDoesQualifierExist(CXmpMeta* m,
const char* schemaNS,
const char* propName,
const char* qualNS,
const char* qualName) {
#ifndef NOOP_FFI
try {
return (m->m.DoesQualifierExist(schemaNS, propName, qualNS, qualName)) ? 1 : 0;
}
catch (...) {
}
#endif
return 0;
}
const char* CXmpMetaGetArrayItem(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::uint32 index,
AdobeXMPCommon::uint32* outOptions) {
#ifdef NOOP_FFI
*outOptions = 0;
return NULL;
#else
std::string propValue;
try {
if (m->m.GetArrayItem(schemaNS, propName, index, &propValue, outOptions)) {
return copyStringForResult(propValue);
} else {
*outOptions = 0;
return NULL;
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
return NULL;
}
catch (...) {
signalUnknownError(outError);
return NULL;
}
#endif
}
const char* CXmpMetaGetLocalizedText(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* altTextName,
const char* genericLang,
const char* specificLang,
const char** actualLang,
AdobeXMPCommon::uint32* outOptions) {
*outOptions = 0;
#ifndef NOOP_FFI
try {
std::string propValue;
std::string outActualLang;
if (m->m.GetLocalizedText(schemaNS,
altTextName,
genericLang,
specificLang,
&outActualLang,
&propValue,
outOptions)) {
*actualLang = copyStringForResult(outActualLang);
return copyStringForResult(propValue);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpMetaSetLocalizedText(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* altTextName,
const char* genericLang,
const char* specificLang,
const char* itemValue, const char** actualLang,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
m->m.SetLocalizedText(schemaNS,
altTextName,
genericLang,
specificLang,
itemValue,
options);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpMetaSort(CXmpMeta* m, CXmpError* outError) {
#ifndef NOOP_FFI
try {
m->m.Sort();
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
const char* CXmpMetaGetObjectName(CXmpMeta* m, CXmpError* outError) {
#ifndef NOOP_FFI
try {
std::string name;
m->m.GetObjectName(&name);
return copyStringForResult(name);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpMetaSetObjectName(CXmpMeta* m,
CXmpError* outError,
const char* name) {
#ifndef NOOP_FFI
try {
m->m.SetObjectName(name);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
const char* CXmpMetaComposeArrayItemPath(CXmpError* outError,
const char* schemaNS,
const char* arrayName,
AdobeXMPCommon::int32 index) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string resultPath;
SXMPUtils::ComposeArrayItemPath(schemaNS,
arrayName,
index,
&resultPath);
return copyStringForResult(resultPath);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaComposeLangSelector(CXmpError* outError,
const char* schemaNS,
const char* arrayName,
const char* langName) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string resultPath;
SXMPUtils::ComposeLangSelector(schemaNS,
arrayName,
langName,
&resultPath);
return copyStringForResult(resultPath);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaComposeFieldSelector(CXmpError* outError,
const char* schemaNS,
const char* structName,
const char* fieldNS,
const char* fieldName,
const char* fieldValue) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string resultPath;
SXMPUtils::ComposeFieldSelector(schemaNS,
structName,
fieldNS,
fieldName,
fieldValue,
&resultPath);
return copyStringForResult(resultPath);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaComposeQualifierPath(CXmpError* outError,
const char* schemaNS,
const char* structName,
const char* qualNS,
const char* qualName) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string resultPath;
SXMPUtils::ComposeQualifierPath(schemaNS,
structName,
qualNS,
qualName,
&resultPath);
return copyStringForResult(resultPath);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
const char* CXmpMetaComposeStructFieldPath(CXmpError* outError,
const char* schemaNS,
const char* structName,
const char* fieldNS,
const char* fieldName) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
std::string resultPath;
SXMPUtils::ComposeStructFieldPath(schemaNS,
structName,
fieldNS,
fieldName,
&resultPath);
return copyStringForResult(resultPath);
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpMetaDumpObj(CXmpMeta* m,
void* rustString,
XMP_TextOutputProc callback) {
#ifndef NOOP_FFI
try {
m->m.DumpObject(callback, rustString);
}
catch (...) {
}
#endif
}
CXmpIterator* CXmpIteratorNew(CXmpMeta* m,
CXmpError* outError,
const char* schemaNS,
const char* propName,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
if (m) {
return new CXmpIterator(SXMPIterator(m->m, schemaNS, propName, options));
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
void CXmpIteratorDrop(CXmpIterator* i) {
#ifndef NOOP_FFI
delete i;
#endif
}
bool CXmpIteratorNext(CXmpIterator* i,
CXmpError* outError,
const char** outSchemaNS,
const char** outPropPath,
const char** outPropValue,
AdobeXMPCommon::uint32* outOptions) {
#ifndef NOOP_FFI
try {
if (i) {
std::string schemaNS;
std::string propPath;
std::string propValue;
if (i->i.Next(&schemaNS, &propPath, &propValue, outOptions)) {
*outSchemaNS = copyStringForResult(schemaNS);
*outPropPath = copyStringForResult(propPath);
*outPropValue = copyStringForResult(propValue);
return true;
}
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return false;
}
void CXmpIteratorSkip(CXmpIterator* i,
CXmpError* outError,
AdobeXMPCommon::uint32 options) {
#ifndef NOOP_FFI
try {
if (i) {
i->i.Skip(options);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpDateTimeCurrent(XMP_DateTime* dt, CXmpError* outError) {
#ifndef NOOP_FFI
try {
if (dt) {
SXMPUtils::CurrentDateTime(dt);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpDateTimeSetTimeZone(XMP_DateTime* dt, CXmpError* outError) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return;
}
try {
if (dt) {
SXMPUtils::SetTimeZone(dt);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpDateTimeConvertToLocalTime(XMP_DateTime* dt, CXmpError* outError) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return;
}
try {
if (dt) {
SXMPUtils::ConvertToLocalTime(dt);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
void CXmpDateTimeConvertToUTCTime(XMP_DateTime* dt, CXmpError* outError) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return;
}
try {
if (dt) {
SXMPUtils::ConvertToUTCTime(dt);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
}
const char* CXmpDateTimeToString(const XMP_DateTime* dt, CXmpError* outError) {
#ifndef NOOP_FFI
if (!init_xmp()) {
signalXmpInitFailure(outError);
return NULL;
}
try {
if (dt) {
std::string dtAsString;
SXMPUtils::ConvertFromDate(*dt, &dtAsString);
return copyStringForResult(dtAsString);
}
}
catch (XMP_Error& e) {
copyErrorForResult(e, outError);
}
catch (...) {
signalUnknownError(outError);
}
#endif
return NULL;
}
}