Mercurial > cgi-bin > hgweb.cgi > JpegWasher
annotate src/name/blackcap/exifwasher/exiv2/Initialize.kt @ 2:efd9fe2d70d7
Rationalize exceptions, code whitelist, add command-line tool.
author | David Barts <n5jrn@me.com> |
---|---|
date | Wed, 01 Apr 2020 14:23:54 -0700 |
parents | 42277ce58ace |
children | 9ac6136c710c |
rev | line source |
---|---|
0
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
1 /* |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
2 * Logic common to initializing all external (JNI) classes goes here. |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
3 */ |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
4 package name.blackcap.exifwasher.exiv2 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
5 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
6 import java.io.File |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
7 import java.io.FileOutputStream |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
8 import java.io.IOException |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
9 import java.util.jar.JarEntry |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
10 import java.util.jar.JarFile |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
11 import name.blackcap.exifwasher.LF_DIR |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
12 import name.blackcap.exifwasher.OS |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
13 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
14 object Initialize { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
15 private var initialized = false |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
16 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
17 public fun libraries() { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
18 /* no-op if already initialized */ |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
19 if (initialized) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
20 return |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
21 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
22 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
23 /* use the appropriate binary for the system we're on */ |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
24 val subdir = when(OS.type) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
25 OS.UNIX -> "linux" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
26 OS.MAC -> "mac" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
27 OS.WINDOWS -> "windows" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
28 OS.OTHER -> throw RuntimeException("unsupported OS!") |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
29 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
30 val ext = when(OS.type) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
31 OS.UNIX -> "so" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
32 OS.MAC -> "dylib" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
33 OS.WINDOWS -> "dll" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
34 OS.OTHER -> throw RuntimeException("unsupported OS!") |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
35 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
36 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
37 /* extract to scratch files, if needed, then load */ |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
38 val klass = Initialize::class.java |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
39 var myJar = JarFile(File(klass.getProtectionDomain().getCodeSource().getLocation().toURI())) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
40 for (base in arrayOf("libexiv2", "libjni")) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
41 val eBase = "${base}.${ext}" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
42 val sPath = "name/blackcap/exifwasher/binaries/${subdir}/${eBase}" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
43 val source = myJar.getJarEntry(sPath) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
44 if (source == null) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
45 die("${sPath} not found in jar") |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
46 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
47 val target = File(LF_DIR, eBase) |
1
42277ce58ace
Improve exception handling; always use absolute paths on libs.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
48 val tPath = target.absolutePath |
0
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
49 try { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
50 if (!target.exists() || target.lastModified() < source.getTime()) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
51 myJar.getInputStream(source).use { sfp -> |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
52 FileOutputStream(target).use { tfp -> |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
53 sfp.copyTo(tfp) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
54 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
55 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
56 target.setExecutable(true) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
57 target.setLastModified(source.getTime()) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
58 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
59 } catch (e: IOException) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
60 val message = e.message ?: "I/O error" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
61 die("unable to create ${tPath}: ${message}") |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
62 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
63 try { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
64 System.load(tPath) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
65 } catch (e: UnsatisfiedLinkError) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
66 val message = e.message ?: "unsatisfied link" |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
67 die("unable to link ${tPath}: ${message}") |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
68 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
69 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
70 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
71 initialized = true |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
72 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
73 |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
74 private fun die(message: String) { |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
75 /* should open a dialog */ |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
76 System.err.println(message) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
77 System.exit(1) |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
78 } |
db63d01a23c6
JNI calls and test case (finally!) seem to work.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
79 } |