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