Mercurial > cgi-bin > hgweb.cgi > JpegWasher
view 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 source
/* * 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) } }