1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module org.eclipse.swt.internal.Library;
14 
15 import java.lang.all;
16 
17 // do it here, so it can be evaluated at compile time
18 // this saves a static ctor.
19 // empty () hack to get body in to .di
20 private int buildSWT_VERSION() (int major, int minor) {
21     return major * 1000 + minor;
22 }
23 
24 
25 public class Library {
26 
27     /* SWT Version - Mmmm (M=major, mmm=minor) */
28 
29     /**
30      * SWT Major version number (must be >= 0)
31      */
32     static const int MAJOR_VERSION = 3;
33 
34     /**
35      * SWT Minor version number (must be in the range 0..999)
36      */
37     static const int MINOR_VERSION = 449;
38 
39     /**
40      * SWT revision number (must be >= 0)
41      */
42     static const int REVISION = 0;
43 
44     /**
45      * The JAVA and SWT versions
46      */
47     //public static const int JAVA_VERSION;
48     public static const int SWT_VERSION = .buildSWT_VERSION(MAJOR_VERSION, MINOR_VERSION);
49 
50     version( linux ){
51         static const String SEPARATOR = "\n";
52     }
53     else {
54         static assert( false, "only linux supported for this port" );
55     }
56 
57 
58 static int parseVersion(String aVersion) {
59     if (aVersion == null) return 0;
60     int major = 0, minor = 0, micro = 0;
61     int length = cast(int)/*64bit*/aVersion.length, index = 0, start = 0;
62     bool isDigit( char c ){
63         return c >= '0' && c <= '9';
64     }
65     while (index < length && isDigit(aVersion[index])) index++;
66     try {
67         if (start < length) major = Integer.parseInt( aVersion[start .. index] );
68     } catch (NumberFormatException e) {}
69     start = ++index;
70     while (index < length && isDigit(aVersion[index])) index++;
71     try {
72         if (start < length) minor = Integer.parseInt(aVersion[start .. index]);
73     } catch (NumberFormatException e) {}
74     start = ++index;
75     while (index < length && isDigit(aVersion[index])) index++;
76     try {
77         if (start < length) micro = Integer.parseInt(aVersion[start .. index]);
78     } catch (NumberFormatException e) {}
79     return buildJAVA_VERSION(major, minor, micro);
80 }
81 
82 /**
83  * Returns the Java version number as an integer.
84  *
85  * @param major
86  * @param minor
87  * @param micro
88  * @return the version
89  */
90 public static int buildJAVA_VERSION (int major, int minor, int micro) {
91     return (major << 16) + (minor << 8) + micro;
92 }
93 
94 /**
95  * Returns the SWT version number as an integer.
96  *
97  * @param major
98  * @param minor
99  * @return the version
100  */
101 public static int buildSWT_VERSION (int major, int minor) {
102     return .buildSWT_VERSION(major, minor);
103 }
104 /+ PORTING_LEFT
105 static bool extract (String fileName, String mappedName) {
106     FileOutputStream os = null;
107     InputStream is = null;
108     File file = new File(fileName);
109     try {
110         if (!file.exists ()) {
111             is = Library.class.getResourceAsStream ("/" + mappedName); //$NON-NLS-1$
112             if (is != null) {
113                 int read;
114                 byte [] buffer = new byte [4096];
115                 os = new FileOutputStream (fileName);
116                 while ((read = is.read (buffer)) != -1) {
117                     os.write(buffer, 0, read);
118                 }
119                 os.close ();
120                 is.close ();
121                 if (!Platform.PLATFORM.equals ("win32")) { //$NON-NLS-1$
122                     try {
123                         Runtime.getRuntime ().exec (new String []{"chmod", "755", fileName}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
124                     } catch (Throwable e) {}
125                 }
126                 if (load (fileName)) return true;
127             }
128         }
129     } catch (Throwable e) {
130         try {
131             if (os != null) os.close ();
132         } catch (IOException e1) {}
133         try {
134             if (is != null) is.close ();
135         } catch (IOException e1) {}
136     }
137     if (file.exists ()) file.delete ();
138     return false;
139 }
140 
141 static bool load (String libName) {
142     try {
143         if (libName.indexOf (SEPARATOR) != -1) {
144             System.load (libName);
145         } else {
146             System.loadLibrary (libName);
147         }
148         return true;
149     } catch (UnsatisfiedLinkError e) {}
150     return false;
151 }
152 
153 /**
154  * Loads the shared library that matches the version of the
155  * Java code which is currently running.  SWT shared libraries
156  * follow an encoding scheme where the major, minor and revision
157  * numbers are embedded in the library name and this along with
158  * <code>name</code> is used to load the library.  If this fails,
159  * <code>name</code> is used in another attempt to load the library,
160  * this time ignoring the SWT version encoding scheme.
161  *
162  * @param name the name of the library to load
163  */
164 public static void loadLibrary (String name) {
165     loadLibrary (name, true);
166 }
167 
168 /**
169  * Loads the shared library that matches the version of the
170  * Java code which is currently running.  SWT shared libraries
171  * follow an encoding scheme where the major, minor and revision
172  * numbers are embedded in the library name and this along with
173  * <code>name</code> is used to load the library.  If this fails,
174  * <code>name</code> is used in another attempt to load the library,
175  * this time ignoring the SWT version encoding scheme.
176  *
177  * @param name the name of the library to load
178  * @param mapName true if the name should be mapped, false otherwise
179  */
180 public static void loadLibrary (String name, boolean mapName) {
181     String prop = System.getProperty ("sun.arch.data.model"); //$NON-NLS-1$
182     if (prop is null) prop = System.getProperty ("com.ibm.vm.bitmode"); //$NON-NLS-1$
183     if (prop !is null) {
184         if ("32".equals (prop)) { //$NON-NLS-1$
185              if (0x1FFFFFFFFL is cast(ptrdiff_t)0x1FFFFFFFFL) {
186                 throw new UnsatisfiedLinkError ("Cannot load 64-bit SWT libraries on 32-bit JVM"); //$NON-NLS-1$
187              }
188         }
189         if ("64".equals (prop)) { //$NON-NLS-1$
190             if (0x1FFFFFFFFL !is cast(ptrdiff_t)0x1FFFFFFFFL) {
191                 throw new UnsatisfiedLinkError ("Cannot load 32-bit SWT libraries on 64-bit JVM"); //$NON-NLS-1$
192             }       
193         }
194     }
195 
196     /* Compute the library name and mapped name */
197     String libName1, libName2, mappedName1, mappedName2;
198     if (mapName) {
199         String version = System.getProperty ("swt.version"); //$NON-NLS-1$
200         if (version == null) {
201             version = "" + MAJOR_VERSION; //$NON-NLS-1$
202             /* Force 3 digits in minor version number */
203             if (MINOR_VERSION < 10) {
204                 version += "00"; //$NON-NLS-1$
205             } else {
206                 if (MINOR_VERSION < 100) version += "0"; //$NON-NLS-1$
207             }
208             version += MINOR_VERSION;
209             /* No "r" until first revision */
210             if (REVISION > 0) version += "r" + REVISION; //$NON-NLS-1$
211         }
212         libName1 = name + "-" + Platform.PLATFORM + "-" + version;  //$NON-NLS-1$ //$NON-NLS-2$
213         libName2 = name + "-" + Platform.PLATFORM;  //$NON-NLS-1$
214         mappedName1 = System.mapLibraryName (libName1);
215         mappedName2 = System.mapLibraryName (libName2);
216     } else {
217         libName1 = libName2 = mappedName1 = mappedName2 = name;
218     }
219 
220     /* Try loading library from swt library path */
221     String path = System.getProperty ("swt.library.path"); //$NON-NLS-1$
222     if (path != null) {
223         path = new File (path).getAbsolutePath ();
224         if (load (path + SEPARATOR + mappedName1)) return;
225         if (mapName && load (path + SEPARATOR + mappedName2)) return;
226     }
227 
228     /* Try loading library from java library path */
229     if (load (libName1)) return;
230     if (mapName && load (libName2)) return;
231 
232     /* Try loading library from the tmp directory if swt library path is not specified */
233     if (path == null) {
234         path = System.getProperty ("java.io.tmpdir"); //$NON-NLS-1$
235         path = new File (path).getAbsolutePath ();
236         if (load (path + SEPARATOR + mappedName1)) return;
237         if (mapName && load (path + SEPARATOR + mappedName2)) return;
238     }
239 
240     /* Try extracting and loading library from jar */
241     if (path != null) {
242         if (extract (path + SEPARATOR + mappedName1, mappedName1)) return;
243         if (mapName && extract (path + SEPARATOR + mappedName2, mappedName2)) return;
244     }
245 
246     /* Failed to find the library */
247     throw new UnsatisfiedLinkError ("no " + libName1 + " or " + libName2 + " in swt.library.path, java.library.path or the jar file"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
248 }
249 +/
250 }