Mercurial > cgi-bin > hgweb.cgi > JpegWasher
diff src/name/blackcap/exifwasher/exiv2/Initialize.kt @ 0:db63d01a23c6
JNI calls and test case (finally!) seem to work.
author | David Barts <n5jrn@me.com> |
---|---|
date | Tue, 31 Mar 2020 13:24:48 -0700 |
parents | |
children | 42277ce58ace |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/name/blackcap/exifwasher/exiv2/Initialize.kt Tue Mar 31 13:24:48 2020 -0700 @@ -0,0 +1,81 @@ +/* + * Logic common to initializing all external (JNI) classes goes here. + */ +package name.blackcap.exifwasher.exiv2 + +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.util.jar.JarEntry +import java.util.jar.JarFile +import name.blackcap.exifwasher.LF_DIR +import name.blackcap.exifwasher.OS + +object Initialize { + private var initialized = false + + public fun libraries() { + /* no-op if already initialized */ + if (initialized) { + return + } + + /* use the appropriate binary for the system we're on */ + val subdir = when(OS.type) { + OS.UNIX -> "linux" + OS.MAC -> "mac" + OS.WINDOWS -> "windows" + OS.OTHER -> throw RuntimeException("unsupported OS!") + } + val ext = when(OS.type) { + OS.UNIX -> "so" + OS.MAC -> "dylib" + OS.WINDOWS -> "dll" + OS.OTHER -> throw RuntimeException("unsupported OS!") + } + + /* extract to scratch files, if needed, then load */ + val klass = Initialize::class.java + var myJar = JarFile(File(klass.getProtectionDomain().getCodeSource().getLocation().toURI())) + for (base in arrayOf("libexiv2", "libjni")) { + val eBase = "${base}.${ext}" + val sPath = "name/blackcap/exifwasher/binaries/${subdir}/${eBase}" + val source = myJar.getJarEntry(sPath) + if (source == null) { + die("${sPath} not found in jar") + } + val target = File(LF_DIR, eBase) + val tPath = target.toString() + try { + if (!target.exists() || target.lastModified() < source.getTime()) { + myJar.getInputStream(source).use { sfp -> + FileOutputStream(target).use { tfp -> + sfp.copyTo(tfp) + } + } + target.setExecutable(true) + target.setLastModified(source.getTime()) + } + } catch (e: IOException) { + val message = e.message ?: "I/O error" + die("unable to create ${tPath}: ${message}") + } + try { + println("loading: ${tPath}") /* debug */ + System.load(tPath) + } catch (e: UnsatisfiedLinkError) { + val message = e.message ?: "unsatisfied link" + die("unable to link ${tPath}: ${message}") + } + } + + initialized = true + System.err.println("libraries loaded") /* debug */ + } + + private fun die(message: String) { + /* should open a dialog */ + System.err.println(message) + System.exit(1) + } +}