28import java.nio.ByteBuffer;
29import java.nio.ByteOrder;
30import java.nio.IntBuffer;
31import java.nio.ShortBuffer;
32import java.security.PrivilegedAction;
33import java.util.ArrayList;
34import java.util.Iterator;
36import java.util.StringTokenizer;
41final class PlatformToolkit {
43 UNIX, MACOS,
IOS, WINDOWS;
111 this.is32Bit = is32Bit;
119 if(
null == other ) {
121 }
else if( other ==
this ) {
124 return this.family == other.family &&
130 if(
null == cpuABILower ) {
131 throw new IllegalArgumentException(
"Null cpuABILower arg");
133 if( cpuABILower.equals(
"x86") ||
134 cpuABILower.equals(
"i386") ||
135 cpuABILower.equals(
"i486") ||
136 cpuABILower.equals(
"i586") ||
137 cpuABILower.equals(
"i686") ) {
139 }
else if( cpuABILower.equals(
"x86_64") ||
140 cpuABILower.equals(
"amd64") ) {
142 }
else if( cpuABILower.equals(
"ia64") ) {
144 }
else if( cpuABILower.equals(
"aarch64") ) {
146 }
else if( cpuABILower.startsWith(
"arm") ) {
147 if( cpuABILower.equals(
"armv8-a") ||
148 cpuABILower.equals(
"arm-v8-a") ||
149 cpuABILower.equals(
"arm-8-a") ||
150 cpuABILower.equals(
"arm64-v8a") ) {
152 }
else if( cpuABILower.startsWith(
"arm64") ) {
154 }
else if( cpuABILower.startsWith(
"armv7") ||
155 cpuABILower.startsWith(
"arm-v7") ||
156 cpuABILower.startsWith(
"arm-7") ||
157 cpuABILower.startsWith(
"armeabi-v7") ) {
159 }
else if( cpuABILower.startsWith(
"armv5") ||
160 cpuABILower.startsWith(
"arm-v5") ||
161 cpuABILower.startsWith(
"arm-5") ) {
163 }
else if( cpuABILower.startsWith(
"armv6") ||
164 cpuABILower.startsWith(
"arm-v6") ||
165 cpuABILower.startsWith(
"arm-6") ) {
170 }
else if( cpuABILower.equals(
"sparcv9") ) {
172 }
else if( cpuABILower.equals(
"sparc") ) {
174 }
else if( cpuABILower.equals(
"pa_risc2.0") ) {
176 }
else if( cpuABILower.startsWith(
"ppc64") ) {
178 }
else if( cpuABILower.startsWith(
"ppc") ) {
180 }
else if( cpuABILower.startsWith(
"mips64") ) {
182 }
else if( cpuABILower.startsWith(
"mips") ) {
184 }
else if( cpuABILower.startsWith(
"superh") ) {
187 throw new RuntimeException(
"Please port CPUType detection to your platform (CPU_ABI string '" + cpuABILower +
"')");
211 if(
null == other ) {
214 return other ==
this;
219 if(
null == cpuType ) {
220 throw new IllegalArgumentException(
"Null cpuType");
221 }
else if(
null == cpuABILower ) {
222 throw new IllegalArgumentException(
"Null cpuABILower");
227 return EABI_GNU_ARMHF;
235 static final String os_name;
237 static final String os_arch;
238 private static final String user_dir;
239 private static final String java_user_lib_path;
240 private static final String java_boot_lib_path;
245 static final String os_and_arch;
246 static final OSType OS_TYPE;
247 private static final boolean isOSX;
249 private static final String prefix;
250 private static final String suffix;
254 final String[] props =
257 public String[] run() {
258 final String[] props =
new String[5];
260 props[i++] = System.getProperty(
"os.name").toLowerCase();
261 props[i++] = System.getProperty(
"os.arch").toLowerCase();
262 props[i++] = System.getProperty(
"user.dir");
263 props[i++] = System.getProperty(
"java.library.path");
264 props[i++] = System.getProperty(
"sun.boot.library.path");
269 os_name = props[i++];
270 final String _os_arch1 = props[i++];
271 user_dir = props[i++];
272 java_user_lib_path = props[i++];
273 java_boot_lib_path = props[i++];
275 final boolean LITTLE_ENDIAN = queryIsLittleEndianImpl();
276 final CPUType CPU_TYPE = CPUType.query(_os_arch1);
277 final ABIType ABI_TYPE = ABIType.query(CPU_TYPE, _os_arch1);
278 final String _os_arch2 = getArchName(CPU_TYPE, ABI_TYPE, LITTLE_ENDIAN);
279 os_arch =
null != _os_arch2 ? _os_arch2 : _os_arch1;
280 os_and_arch = os_name+
"-"+os_arch;
281 if( BTFactory.DEBUG ) {
282 System.err.println(
"PlatformToolkit: os_name "+os_name+
", os_arch ("+_os_arch1+
" -> "+_os_arch2+
" ->) "+os_arch+
" (final), "+
283 "CPU_TYPE "+CPU_TYPE+
", ABI_TYPE "+ABI_TYPE+
", LITTLE_ENDIAN "+LITTLE_ENDIAN);
287 if ( os_name.startsWith(
"mac os x") ||
288 os_name.startsWith(
"darwin") ) {
289 OS_TYPE = OSType.MACOS;
291 }
else if ( os_name.startsWith(
"ios") ) {
292 OS_TYPE = OSType.IOS;
294 }
else if ( os_name.startsWith(
"windows") ) {
295 OS_TYPE = OSType.WINDOWS;
298 OS_TYPE = OSType.UNIX;
322 private static final boolean queryIsLittleEndianImpl() {
323 final ByteBuffer tst_b = ByteBuffer.allocateDirect(4 ).order(ByteOrder.nativeOrder());
324 final IntBuffer tst_i = tst_b.asIntBuffer();
325 final ShortBuffer tst_s = tst_b.asShortBuffer();
326 tst_i.put(0, 0x0A0B0C0D);
327 return 0x0C0D == tst_s.get(0);
329 private static final String getArchName(
final CPUType cpuType,
final ABIType abiType,
final boolean littleEndian) {
347 return littleEndian ?
"mipsel" :
"mips";
356 return littleEndian ?
"ppc64le" :
"ppc64";
404 private static final List<String> enumerateLibraryPaths(
final String libBaseName,
405 final boolean searchSystemPath,
406 final boolean searchSystemPathFirst,
407 final ClassLoader loader) {
408 final List<String> paths =
new ArrayList<String>();
410 if ( libBaseName ==
null || libBaseName.length() == 0 ) {
414 final String libPlatformName = getPlatformName(libBaseName);
416 if( searchSystemPath && searchSystemPathFirst ) {
420 addPath(
"osx-1",
"/Library/Frameworks/" + libBaseName +
".framework", libPlatformName, paths);
422 addPath(
"osx-2",
"/System/Library/Frameworks/" + libBaseName +
".framework", libPlatformName, paths);
424 addMultiPaths(
"java-boot-libpath", java_boot_lib_path, libPlatformName, paths);
427 addPath(
"cwd.os_and_arch", user_dir+File.separator+os_and_arch, libPlatformName, paths);
428 addMultiPaths2(
"java-user-libpath.os_and_arch", java_user_lib_path, os_and_arch, libPlatformName, paths);
430 addPath(
"cwd", user_dir, libPlatformName, paths);
431 addMultiPaths(
"java-user-libpath", java_user_lib_path, libPlatformName, paths);
433 if( searchSystemPath && !searchSystemPathFirst ) {
437 addPath(
"osx-1",
"/Library/Frameworks/" + libBaseName +
".Framework", libPlatformName, paths);
439 addPath(
"osx-2",
"/System/Library/Frameworks/" + libBaseName +
".Framework", libPlatformName, paths);
441 addMultiPaths(
"java-boot-libpath", java_boot_lib_path, libPlatformName, paths);
448 private static final String getPlatformName(
final String libBaseName) {
449 return prefix + libBaseName + suffix;
451 private static final String getCanonicalPath(
final String path) {
452 return BTFactory.doPrivileged(
new PrivilegedAction<String>() {
454 public String run() {
456 final File f =
new File(path);
458 return f.getCanonicalPath();
459 }
catch (
final Throwable t) {
460 if( BTFactory.DEBUG ) {
461 System.err.println(
"getAbsolutePath("+path+
") failed: "+t.getMessage());
467 private static final void addPath(
final String msg,
final String path,
final String platformName,
final List<String> paths) {
468 if(
null != path && path.length() > 0 ) {
469 final String fullpath = path + File.separator + platformName;
470 final String abspath = getCanonicalPath(fullpath);
471 if(
null != abspath ) {
472 final boolean isDup = paths.contains(abspath);
473 if( BTFactory.DEBUG ) {
474 System.err.println(
" "+abspath+
" (addPath "+msg+
", dropped duplicate "+isDup+
")");
482 private static final void addMultiPaths(
final String msg,
final String pathList,
final String platformName,
final List<String> paths) {
483 if(
null != pathList && pathList.length() > 0 ) {
484 final StringTokenizer tokenizer =
new StringTokenizer(pathList, File.pathSeparator);
486 while (tokenizer.hasMoreTokens()) {
487 addPath(msg+
":"+i, tokenizer.nextToken(), platformName, paths);
492 private static final void addMultiPaths2(
final String msg,
final String pathList,
final String subDir,
final String platformName,
final List<String> paths) {
493 if(
null != pathList && pathList.length() > 0 &&
null != subDir && subDir.length() > 0 ) {
494 final StringTokenizer tokenizer =
new StringTokenizer(pathList, File.pathSeparator);
496 while (tokenizer.hasMoreTokens()) {
497 final String path = tokenizer.nextToken() + File.separator + subDir;
498 addPath(msg+
":"+i, path, platformName, paths);
543 static boolean loadLibrary(
final String libBaseName,
final ClassLoader cl,
final Throwable[] t) {
544 if( BTFactory.DEBUG ) {
545 System.err.println();
546 System.err.println(
"PlatformToolkit.loadLibrary: libBaseName "+libBaseName+
":");
548 final List<String> possiblePaths = enumerateLibraryPaths(libBaseName,
true ,
false , cl);
549 if( BTFactory.DEBUG ) {
550 System.err.println();
554 for (
final Iterator<String> iter = possiblePaths.iterator(); iter.hasNext(); ) {
555 final String path = iter.next();
558 if( BTFactory.DEBUG ) {
559 System.err.println(
" "+path+
" success");
562 }
catch (
final Throwable t0) {
563 if( BTFactory.DEBUG ) {
564 System.err.println(
" "+path+
" failed: "+t0.getMessage());
572 System.loadLibrary(libBaseName);
573 if( BTFactory.DEBUG ) {
574 System.err.println(
" "+libBaseName+
" success");
577 }
catch (
final Throwable t0) {
578 if( BTFactory.DEBUG ) {
579 System.err.println(
" "+libBaseName+
" failed: "+t0.getMessage());
One stop BTManager API entry point.
static< T > T doPrivileged(final PrivilegedAction< T > o)
Deprecated call to java.security.AccessController#doPrivileged(PrivilegedAction) w/o warnings.