001 package com.github.sarxos.webcam.ds.civil; 002 003 import java.io.File; 004 import java.io.FileNotFoundException; 005 import java.io.FileOutputStream; 006 import java.io.IOException; 007 import java.io.InputStream; 008 import java.io.OutputStream; 009 010 import org.slf4j.Logger; 011 import org.slf4j.LoggerFactory; 012 013 014 public class LtiCivilLoader { 015 016 private static final Logger LOG = LoggerFactory.getLogger(LtiCivilLoader.class); 017 018 /** 019 * Will be called until JVM shutdown. 020 * 021 * @author Bartosz Firyn (SarXos) 022 */ 023 private static class Deleter extends Thread { 024 025 private File file = null; 026 027 public Deleter(File file) { 028 super(); 029 this.file = file; 030 } 031 032 @Override 033 public void run() { 034 super.run(); 035 boolean removed = file.delete(); 036 if (!removed) { 037 file.deleteOnExit(); 038 } 039 } 040 } 041 042 /** 043 * Copy bytes from a large (over 2GB) InputStream to an OutputStream. 044 * 045 * @param input the InputStream to read from 046 * @param output the OutputStream to write to 047 * @return the number of bytes copied 048 * @throws NullPointerException if the input or output is null 049 * @throws IOException if an I/O error occurs 050 */ 051 public static long copy(InputStream input, OutputStream output) throws IOException { 052 byte[] buffer = new byte[1024 * 4]; 053 long count = 0; 054 int n = 0; 055 while (-1 != (n = input.read(buffer))) { 056 output.write(buffer, 0, n); 057 count += n; 058 } 059 return count; 060 } 061 062 public static void load(String lib) { 063 LOG.info("Loading native library: " + lib); 064 try { 065 System.loadLibrary(lib); 066 LOG.info("DLL has been loaded from memory: " + lib); 067 } catch (UnsatisfiedLinkError e) { 068 try { 069 load("webcam-capture-lib-" + System.currentTimeMillis(), lib); 070 } catch (Exception e2) { 071 LOG.error("Exception when loading DLL library", e2); 072 throw new RuntimeException(e2); 073 } 074 } 075 } 076 077 public static void load(String path, String name) { 078 079 String libroot = "/META-INF/lib"; 080 String libpath = null; 081 String libfile = null; 082 083 boolean arch64 = System.getProperty("os.arch").indexOf("64") != -1; 084 boolean linux = System.getProperty("os.name").toLowerCase().indexOf("linux") != -1; 085 086 if (linux) { 087 if (arch64) { 088 libpath = libroot + "/linux64/"; 089 libfile = "lib" + name + ".so"; 090 } else { 091 libpath = libroot + "/linux32/"; 092 libfile = "lib" + name + ".so"; 093 } 094 } else { 095 libpath = libroot + "/win32/"; 096 libfile = name + ".dll"; 097 } 098 099 File parent = new File(System.getProperty("java.io.tmpdir") + "/" + path); 100 if (!parent.exists()) { 101 if (!parent.mkdirs()) { 102 throw new RuntimeException("Cannot create directory: " + parent.getAbsolutePath()); 103 } 104 } 105 106 File file = new File(parent, libfile); 107 if (!file.exists()) { 108 109 boolean created = false; 110 try { 111 created = file.createNewFile(); 112 } catch (IOException e) { 113 throw new RuntimeException("Not able to create file: " + file, e); 114 } 115 if (!created) { 116 throw new RuntimeException("File cannot be created: " + file); 117 } 118 119 Runtime.getRuntime().addShutdownHook(new Deleter(file)); 120 } 121 122 String resource = libpath + libfile; 123 124 InputStream in = LtiCivilDriver.class.getResourceAsStream(resource); 125 if (in == null) { 126 throw new RuntimeException("Resource not found: " + resource); 127 } 128 129 FileOutputStream fos = null; 130 131 try { 132 fos = new FileOutputStream(file); 133 copy(in, fos); 134 } catch (FileNotFoundException e) { 135 throw new RuntimeException("File not found " + file, e); 136 } catch (IOException e) { 137 throw new RuntimeException("IO exception", e); 138 } finally { 139 if (in != null) { 140 try { 141 in.close(); 142 } catch (IOException e) { 143 throw new RuntimeException("Cannot close input stream", e); 144 } 145 } 146 if (fos != null) { 147 try { 148 fos.close(); 149 } catch (IOException e) { 150 throw new RuntimeException("Cannot close file output stream", e); 151 } 152 } 153 } 154 155 try { 156 System.load(file.getAbsolutePath()); 157 } catch (UnsatisfiedLinkError e) { 158 throw new RuntimeException("Library file cannot be loaded: " + file, e); 159 } 160 } 161 }