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 }