view src/name/blackcap/exifwasher/exiv2/native.cpp @ 1:42277ce58ace

Improve exception handling; always use absolute paths on libs.
author David Barts <n5jrn@me.com>
date Tue, 31 Mar 2020 15:38:25 -0700
parents db63d01a23c6
children efd9fe2d70d7
line wrap: on
line source

#include <jni.h>
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>

/* Functions for class name_blackcap_exifwasher_exiv2_Image */

#ifndef _Included_name_blackcap_exifwasher_exiv2_Image
#define _Included_name_blackcap_exifwasher_exiv2_Image
#ifdef __cplusplus
extern "C" {
#endif

/*
 * Utility function to get pointer field.
 */
jlong getPointer(JNIEnv *jEnv, jobject jThis) {
    return jEnv->GetLongField(jThis, jEnv->GetFieldID(jEnv->GetObjectClass(jThis), "pointer", "J"));
}

/*
 * Class:     name_blackcap_exifwasher_exiv2_Image
 * Method:    _ctor
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1ctor
  (JNIEnv *jEnv, jobject jThis, jstring path) {
      const char *cPath = jEnv->GetStringUTFChars(path, NULL);
      jlong ret = 0;
      try {
          ret = reinterpret_cast<jlong> (Exiv2::ImageFactory::open(cPath).release());
      } catch (...) {
          jEnv->ExceptionClear();
          jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception");
          const char *pfx = "unable to open ";
          char *message = (char *) malloc(strlen(cPath) + strlen(pfx) + 1);
          strcpy(message, pfx);
          strcat(message, cPath);
          jEnv->ThrowNew(ex, message);
          free(message);
      }
      jEnv->ReleaseStringUTFChars(path, cPath);
      return ret;
  }

/*
 * Class:     name_blackcap_exifwasher_exiv2_Image
 * Method:    _writeMetadata
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1writeMetadata
  (JNIEnv *jEnv, jobject jThis) {
      Exiv2::Image *image = reinterpret_cast<Exiv2::Image *> (getPointer(jEnv, jThis));
      if (jEnv->ExceptionCheck()) return;
      try {
          image->writeMetadata();
      } catch (...) {
          jEnv->ExceptionClear();
          jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception");
          jEnv->ThrowNew(ex, "unable to write metadata");
      }
  }

/*
 * Class:     name_blackcap_exifwasher_exiv2_Image
 * Method:    _getMetadata
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1getMetadata
  (JNIEnv *jEnv, jobject jThis) {
      Exiv2::Image *image = reinterpret_cast<Exiv2::Image *> (getPointer(jEnv, jThis));
      if (jEnv->ExceptionCheck()) return 0;
      try {
          image->readMetadata();
      } catch (...) {
          jEnv->ExceptionClear();
          jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception");
          jEnv->ThrowNew(ex, "unable to read metadata");
          return 0;
      }
      return reinterpret_cast<jlong> (&(image->exifData()));
  }

/*
 * Class:     name_blackcap_exifwasher_exiv2_Image
 * Method:    _dtor
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_name_blackcap_exifwasher_exiv2_Image__1dtor
  (JNIEnv *jEnv, jobject jThis) {
      Exiv2::Image *image = reinterpret_cast<Exiv2::Image *> (getPointer(jEnv, jThis));
      if (jEnv->ExceptionCheck()) return;
      delete image;
  }

#ifdef __cplusplus
}
#endif
#endif
/* Header for class name_blackcap_exifwasher_exiv2_ExifData */

#ifndef _Included_name_blackcap_exifwasher_exiv2_ExifData
#define _Included_name_blackcap_exifwasher_exiv2_ExifData
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     name_blackcap_exifwasher_exiv2_ExifData
 * Method:    _erase
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_name_blackcap_exifwasher_exiv2_ExifData__1erase
  (JNIEnv *jEnv, jobject jThis, jstring key) {
      Exiv2::ExifData *data = reinterpret_cast<Exiv2::ExifData *> (getPointer(jEnv, jThis));
      if (jEnv->ExceptionCheck()) return;
      const char *cKey = jEnv->GetStringUTFChars(key, NULL);
      Exiv2::ExifData::iterator found = data->findKey(Exiv2::ExifKey(std::string(cKey)));
      try {
          data->erase(found);
      } catch (...) {
          jEnv->ExceptionClear();
          jclass ex = jEnv->FindClass("name/blackcap/exifwasher/exiv2/Exiv2Exception");
          const char *pfx = "unable to delete ";
          char *message = (char *) malloc(strlen(cKey) + strlen(pfx) + 1);
          strcpy(message, pfx);
          strcat(message, cKey);
          jEnv->ThrowNew(ex, message);
          free(message);
      }
      jEnv->ReleaseStringUTFChars(key, cKey);
  }

/*
 * Class:     name_blackcap_exifwasher_exiv2_ExifData
 * Method:    _value
 * Signature: (Ljava/lang/String;)Lname/blackcap/exifwasher/exiv2/ExifData/Value;
 */
JNIEXPORT jobject JNICALL Java_name_blackcap_exifwasher_exiv2_ExifData__1value
  (JNIEnv *jEnv, jobject jThis, jstring key) {
      Exiv2::ExifData *data = reinterpret_cast<Exiv2::ExifData *> (getPointer(jEnv, jThis));
      if (jEnv->ExceptionCheck()) return NULL;
      const char *cKey = jEnv->GetStringUTFChars(key, NULL);
      Exiv2::ExifData::const_iterator found = data->findKey(Exiv2::ExifKey(std::string(cKey)));
      jEnv->ReleaseStringUTFChars(key, cKey);
      if (found == data->end()) {
          return NULL;
      }
      jclass klass = jEnv->FindClass("name/blackcap/exifwasher/exiv2/ExifData$Value");
      if (jEnv->ExceptionCheck()) return NULL;
      jstring type = jEnv->NewStringUTF(found->typeName());
      jstring value = jEnv->NewStringUTF(found->toString().c_str());
      jmethodID method = jEnv->GetMethodID(klass, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
      if (jEnv->ExceptionCheck()) return NULL;
      return jEnv->NewObject(klass, method, type, value);
  }

/*
 * Class:     name_blackcap_exifwasher_exiv2_ExifData
 * Method:    _keys
 * Signature: ()[Ljava/lang/String;
 */
JNIEXPORT jobjectArray JNICALL Java_name_blackcap_exifwasher_exiv2_ExifData__1keys
  (JNIEnv *jEnv, jobject jThis) {
      Exiv2::ExifData *data = reinterpret_cast<Exiv2::ExifData *> (getPointer(jEnv, jThis));
      if (jEnv->ExceptionCheck()) return NULL;
      jclass klass = jEnv->FindClass("java/lang/String");
      if (jEnv->ExceptionCheck()) return NULL;
      jobjectArray ret = jEnv->NewObjectArray(data->count(), klass, NULL);
      if (jEnv->ExceptionCheck()) return NULL;
      Exiv2::ExifData::const_iterator end = data->end();
      jsize j = 0;
      for (Exiv2::ExifData::const_iterator i = data->begin(); i != end; ++i) {
          jEnv->SetObjectArrayElement(ret, j++, jEnv->NewStringUTF(i->key().c_str()));
          if (jEnv->ExceptionCheck()) break;
      }
      return ret;
  }

#ifdef __cplusplus
}
#endif
#endif