|
1 | 1 | package martin.tempest.core; |
2 | 2 |
|
| 3 | +import java.io.File; |
| 4 | +import java.io.FileInputStream; |
| 5 | +import java.io.FileNotFoundException; |
| 6 | +import java.io.FileOutputStream; |
| 7 | +import java.io.IOException; |
| 8 | +import java.io.InputStream; |
| 9 | + |
| 10 | +/** |
| 11 | + * This is a Java wrapper library for TSDRLibrary |
| 12 | + * |
| 13 | + * @author Martin |
| 14 | + * |
| 15 | + */ |
3 | 16 | public class TSDRLibrary { |
4 | 17 |
|
| 18 | + // If the binaries weren't loaded, this will go off |
| 19 | + private static Exception m_e = null; |
| 20 | + |
| 21 | + /** |
| 22 | + * Extracts a library to a temporary path and prays for the OS to delete it after the app closes. |
| 23 | + * @param name |
| 24 | + * @return |
| 25 | + * @throws IOException |
| 26 | + */ |
| 27 | + static final File extractLibrary(final String name) throws IOException { |
| 28 | + final String rawOSNAME = System.getProperty("os.name").toLowerCase(); |
| 29 | + final String rawARCHNAME = System.getProperty("os.arch").toLowerCase(); |
| 30 | + |
| 31 | + String OSNAME = null, EXT = null, ARCHNAME = null; |
| 32 | + |
| 33 | + if (rawOSNAME.contains("win")) { |
| 34 | + OSNAME = "WINDOWS"; |
| 35 | + EXT = ".dll"; |
| 36 | + } else if (rawOSNAME.contains("nix") || rawOSNAME.contains("nux") || rawOSNAME.contains("aix")) { |
| 37 | + OSNAME = "LINUX"; |
| 38 | + EXT = ".so"; |
| 39 | + } else if (rawOSNAME.contains("mac")) { |
| 40 | + OSNAME = "MAC"; |
| 41 | + EXT = ".a"; |
| 42 | + } |
| 43 | + |
| 44 | + if (rawARCHNAME.contains("arm")) |
| 45 | + ARCHNAME = "ARM"; |
| 46 | + else if (rawARCHNAME.contains("64")) |
| 47 | + ARCHNAME = "X64"; |
| 48 | + else |
| 49 | + ARCHNAME = "X86"; |
| 50 | + |
| 51 | + if (OSNAME == null || EXT == null || ARCHNAME == null) |
| 52 | + throw new RuntimeException("Your OS or CPU is not yet supported, sorry."); |
| 53 | + |
| 54 | + final String relative_path = "lib/"+OSNAME+"/"+ARCHNAME+"/"+name+EXT; |
| 55 | + |
| 56 | + InputStream in = TSDRLibrary.class.getClassLoader().getResourceAsStream(relative_path); |
| 57 | + |
| 58 | + if (in == null) |
| 59 | + try { |
| 60 | + in = new FileInputStream(relative_path); |
| 61 | + } catch (FileNotFoundException e) {} |
| 62 | + |
| 63 | + if (in == null) throw new RuntimeException("The library has not been compiled for your OS/Architecture yet ("+OSNAME+"/"+ARCHNAME+")."); |
| 64 | + |
| 65 | + |
| 66 | + byte[] buffer = new byte[in.available()]; |
| 67 | + |
| 68 | + int read = -1; |
| 69 | + final File temp = new File(System.getProperty("java.io.tmpdir"), name+EXT); |
| 70 | + temp.deleteOnExit(); |
| 71 | + final FileOutputStream fos = new FileOutputStream(temp); |
| 72 | + |
| 73 | + while((read = in.read(buffer)) != -1) { |
| 74 | + fos.write(buffer, 0, read); |
| 75 | + } |
| 76 | + fos.close(); |
| 77 | + in.close(); |
| 78 | + |
| 79 | + return temp; |
| 80 | + } |
| 81 | + |
| 82 | + /** |
| 83 | + * Loads a dll library on the fly based on OS and ARCH. Do not supply extension. |
| 84 | + * @param name |
| 85 | + * @throws IOException |
| 86 | + */ |
| 87 | + static final void loadLibrary(final String name) throws IOException { |
| 88 | + try { |
| 89 | + // try traditional method |
| 90 | + System.loadLibrary(name); |
| 91 | + } catch (Throwable t) { |
| 92 | + final File library = extractLibrary(name); |
| 93 | + System.load(library.getAbsolutePath()); |
| 94 | + library.delete(); |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + /** |
| 99 | + * Load the libraries statically and detect errors |
| 100 | + */ |
5 | 101 | static { |
6 | | - System.loadLibrary("TSDRLibraryNDK"); |
| 102 | + try { |
| 103 | + loadLibrary("TSDRLibrary"); |
| 104 | + loadLibrary("TSDRLibraryNDK"); |
| 105 | + extractLibrary("TSDRPlugin_RawFile"); |
| 106 | + } catch (IOException e) { |
| 107 | + m_e = e; |
| 108 | + } |
7 | 109 | } |
8 | 110 |
|
| 111 | + public TSDRLibrary() throws Exception { |
| 112 | + if (m_e != null) throw m_e; |
| 113 | + } |
| 114 | + |
9 | 115 | public native void test(); |
10 | 116 | } |
0 commit comments