25 package org.direct_bt;
28 import java.nio.ByteBuffer;
29 import java.nio.ByteOrder;
30 import java.nio.IntBuffer;
31 import java.nio.ShortBuffer;
32 import java.security.AccessController;
33 import java.security.PrivilegedAction;
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.StringTokenizer;
42 final class PlatformToolkit {
112 this.is32Bit = is32Bit;
120 if(
null == other ) {
122 }
else if( other ==
this ) {
125 return this.family == other.
family &&
131 if(
null == cpuABILower ) {
132 throw new IllegalArgumentException(
"Null cpuABILower arg");
134 if( cpuABILower.equals(
"x86") ||
135 cpuABILower.equals(
"i386") ||
136 cpuABILower.equals(
"i486") ||
137 cpuABILower.equals(
"i586") ||
138 cpuABILower.equals(
"i686") ) {
140 }
else if( cpuABILower.equals(
"x86_64") ||
141 cpuABILower.equals(
"amd64") ) {
143 }
else if( cpuABILower.equals(
"ia64") ) {
145 }
else if( cpuABILower.equals(
"aarch64") ) {
147 }
else if( cpuABILower.startsWith(
"arm") ) {
148 if( cpuABILower.equals(
"armv8-a") ||
149 cpuABILower.equals(
"arm-v8-a") ||
150 cpuABILower.equals(
"arm-8-a") ||
151 cpuABILower.equals(
"arm64-v8a") ) {
153 }
else if( cpuABILower.startsWith(
"arm64") ) {
155 }
else if( cpuABILower.startsWith(
"armv7") ||
156 cpuABILower.startsWith(
"arm-v7") ||
157 cpuABILower.startsWith(
"arm-7") ||
158 cpuABILower.startsWith(
"armeabi-v7") ) {
160 }
else if( cpuABILower.startsWith(
"armv5") ||
161 cpuABILower.startsWith(
"arm-v5") ||
162 cpuABILower.startsWith(
"arm-5") ) {
164 }
else if( cpuABILower.startsWith(
"armv6") ||
165 cpuABILower.startsWith(
"arm-v6") ||
166 cpuABILower.startsWith(
"arm-6") ) {
171 }
else if( cpuABILower.equals(
"sparcv9") ) {
173 }
else if( cpuABILower.equals(
"sparc") ) {
175 }
else if( cpuABILower.equals(
"pa_risc2.0") ) {
177 }
else if( cpuABILower.startsWith(
"ppc64") ) {
179 }
else if( cpuABILower.startsWith(
"ppc") ) {
181 }
else if( cpuABILower.startsWith(
"mips64") ) {
183 }
else if( cpuABILower.startsWith(
"mips") ) {
185 }
else if( cpuABILower.startsWith(
"superh") ) {
188 throw new RuntimeException(
"Please port CPUType detection to your platform (CPU_ABI string '" + cpuABILower +
"')");
212 if(
null == other ) {
215 return other ==
this;
220 if(
null == cpuType ) {
221 throw new IllegalArgumentException(
"Null cpuType");
222 }
else if(
null == cpuABILower ) {
223 throw new IllegalArgumentException(
"Null cpuABILower");
228 return EABI_GNU_ARMHF;
236 static final String os_name;
238 static final String os_arch;
239 private static final String user_dir;
240 private static final String java_user_lib_path;
241 private static final String java_boot_lib_path;
246 static final String os_and_arch;
247 static final OSType OS_TYPE;
248 private static final boolean isOSX;
250 private static final String prefix;
251 private static final String suffix;
255 final String[] props =
256 AccessController.doPrivileged(
new PrivilegedAction<String[]>() {
258 public String[] run() {
259 final String[] props =
new String[5];
261 props[i++] = System.getProperty(
"os.name").toLowerCase();
262 props[i++] = System.getProperty(
"os.arch").toLowerCase();
263 props[i++] = System.getProperty(
"user.dir");
264 props[i++] = System.getProperty(
"java.library.path");
265 props[i++] = System.getProperty(
"sun.boot.library.path");
270 os_name = props[i++];
271 final String _os_arch1 = props[i++];
272 user_dir = props[i++];
273 java_user_lib_path = props[i++];
274 java_boot_lib_path = props[i++];
276 final boolean LITTLE_ENDIAN = queryIsLittleEndianImpl();
277 final CPUType CPU_TYPE = CPUType.query(_os_arch1);
278 final ABIType ABI_TYPE = ABIType.query(CPU_TYPE, _os_arch1);
279 final String _os_arch2 = getArchName(CPU_TYPE, ABI_TYPE, LITTLE_ENDIAN);
280 os_arch =
null != _os_arch2 ? _os_arch2 : _os_arch1;
281 os_and_arch = os_name+
"-"+os_arch;
282 if( BTFactory.DEBUG ) {
283 System.err.println(
"PlatformToolkit: os_name "+os_name+
", os_arch ("+_os_arch1+
" -> "+_os_arch2+
" ->) "+os_arch+
" (final), "+
284 "CPU_TYPE "+CPU_TYPE+
", ABI_TYPE "+ABI_TYPE+
", LITTLE_ENDIAN "+LITTLE_ENDIAN);
288 if ( os_name.startsWith(
"mac os x") ||
289 os_name.startsWith(
"darwin") ) {
290 OS_TYPE = OSType.MACOS;
292 }
else if ( os_name.startsWith(
"ios") ) {
293 OS_TYPE = OSType.IOS;
295 }
else if ( os_name.startsWith(
"windows") ) {
296 OS_TYPE = OSType.WINDOWS;
299 OS_TYPE = OSType.UNIX;
323 private static final boolean queryIsLittleEndianImpl() {
324 final ByteBuffer tst_b = ByteBuffer.allocateDirect(4 ).order(ByteOrder.nativeOrder());
325 final IntBuffer tst_i = tst_b.asIntBuffer();
326 final ShortBuffer tst_s = tst_b.asShortBuffer();
327 tst_i.put(0, 0x0A0B0C0D);
328 return 0x0C0D == tst_s.get(0);
330 private static final String getArchName(
final CPUType cpuType,
final ABIType abiType,
final boolean littleEndian) {
348 return littleEndian ?
"mipsel" :
"mips";
357 return littleEndian ?
"ppc64le" :
"ppc64";
405 private static final List<String> enumerateLibraryPaths(
final String libBaseName,
406 final boolean searchSystemPath,
407 final boolean searchSystemPathFirst,
408 final ClassLoader loader) {
409 final List<String> paths =
new ArrayList<String>();
411 if ( libBaseName ==
null || libBaseName.length() == 0 ) {
415 final String libPlatformName = getPlatformName(libBaseName);
417 if( searchSystemPath && searchSystemPathFirst ) {
421 addPath(
"osx-1",
"/Library/Frameworks/" + libBaseName +
".framework", libPlatformName, paths);
423 addPath(
"osx-2",
"/System/Library/Frameworks/" + libBaseName +
".framework", libPlatformName, paths);
425 addMultiPaths(
"java-boot-libpath", java_boot_lib_path, libPlatformName, paths);
428 addPath(
"cwd.os_and_arch", user_dir+File.separator+os_and_arch, libPlatformName, paths);
429 addMultiPaths2(
"java-user-libpath.os_and_arch", java_user_lib_path, os_and_arch, libPlatformName, paths);
431 addPath(
"cwd", user_dir, libPlatformName, paths);
432 addMultiPaths(
"java-user-libpath", java_user_lib_path, libPlatformName, paths);
434 if( searchSystemPath && !searchSystemPathFirst ) {
438 addPath(
"osx-1",
"/Library/Frameworks/" + libBaseName +
".Framework", libPlatformName, paths);
440 addPath(
"osx-2",
"/System/Library/Frameworks/" + libBaseName +
".Framework", libPlatformName, paths);
442 addMultiPaths(
"java-boot-libpath", java_boot_lib_path, libPlatformName, paths);
449 private static final String getPlatformName(
final String libBaseName) {
450 return prefix + libBaseName + suffix;
452 private static final String getCanonicalPath(
final String path) {
453 return AccessController.doPrivileged(
new PrivilegedAction<String>() {
455 public String run() {
457 final File f =
new File(path);
459 return f.getCanonicalPath();
460 }
catch (
final Throwable t) {
461 if( BTFactory.DEBUG ) {
462 System.err.println(
"getAbsolutePath("+path+
") failed: "+t.getMessage());
468 private static final void addPath(
final String msg,
final String path,
final String platformName,
final List<String> paths) {
469 if(
null != path && path.length() > 0 ) {
470 final String fullpath = path + File.separator + platformName;
471 final String abspath = getCanonicalPath(fullpath);
472 if(
null != abspath ) {
473 final boolean isDup = paths.contains(abspath);
474 if( BTFactory.DEBUG ) {
475 System.err.println(
" "+abspath+
" (addPath "+msg+
", dropped duplicate "+isDup+
")");
483 private static final void addMultiPaths(
final String msg,
final String pathList,
final String platformName,
final List<String> paths) {
484 if(
null != pathList && pathList.length() > 0 ) {
485 final StringTokenizer tokenizer =
new StringTokenizer(pathList, File.pathSeparator);
487 while (tokenizer.hasMoreTokens()) {
488 addPath(msg+
":"+i, tokenizer.nextToken(), platformName, paths);
493 private static final void addMultiPaths2(
final String msg,
final String pathList,
final String subDir,
final String platformName,
final List<String> paths) {
494 if(
null != pathList && pathList.length() > 0 &&
null != subDir && subDir.length() > 0 ) {
495 final StringTokenizer tokenizer =
new StringTokenizer(pathList, File.pathSeparator);
497 while (tokenizer.hasMoreTokens()) {
498 final String path = tokenizer.nextToken() + File.separator + subDir;
499 addPath(msg+
":"+i, path, platformName, paths);
544 static boolean loadLibrary(
final String libBaseName,
final ClassLoader cl,
final Throwable[] t) {
545 if( BTFactory.DEBUG ) {
546 System.err.println();
547 System.err.println(
"PlatformToolkit.loadLibrary: libBaseName "+libBaseName+
":");
549 final List<String> possiblePaths = enumerateLibraryPaths(libBaseName,
true ,
false , cl);
550 if( BTFactory.DEBUG ) {
551 System.err.println();
555 for (
final Iterator<String> iter = possiblePaths.iterator(); iter.hasNext(); ) {
556 final String path = iter.next();
559 if( BTFactory.DEBUG ) {
560 System.err.println(
" "+path+
" success");
563 }
catch (
final Throwable t0) {
564 if( BTFactory.DEBUG ) {
565 System.err.println(
" "+path+
" failed: "+t0.getMessage());
573 System.loadLibrary(libBaseName);
574 if( BTFactory.DEBUG ) {
575 System.err.println(
" "+libBaseName+
" success");
578 }
catch (
final Throwable t0) {
579 if( BTFactory.DEBUG ) {
580 System.err.println(
" "+libBaseName+
" failed: "+t0.getMessage());