PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/sun/jna/Platform.java

http://github.com/twall/jna
Java | 350 lines | 278 code | 15 blank | 57 comment | 100 complexity | 61700350991ff687991991c8abd2d9f8 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. /*
  2. * The contents of this file is dual-licensed under 2
  3. * alternative Open Source/Free licenses: LGPL 2.1 or later and
  4. * Apache License 2.0. (starting with JNA version 4.0.0).
  5. *
  6. * You can freely decide which license you want to apply to
  7. * the project.
  8. *
  9. * You may obtain a copy of the LGPL License at:
  10. *
  11. * http://www.gnu.org/licenses/licenses.html
  12. *
  13. * A copy is also included in the downloadable source code package
  14. * containing JNA, in file "LGPL2.1".
  15. *
  16. * You may obtain a copy of the Apache License at:
  17. *
  18. * http://www.apache.org/licenses/
  19. *
  20. * A copy is also included in the downloadable source code package
  21. * containing JNA, in file "AL2.0".
  22. */
  23. package com.sun.jna;
  24. import java.io.File;
  25. import java.io.IOException;
  26. import java.util.logging.Level;
  27. import java.util.logging.Logger;
  28. /** Provide simplified platform information. */
  29. public final class Platform {
  30. public static final int UNSPECIFIED = -1;
  31. public static final int MAC = 0;
  32. public static final int LINUX = 1;
  33. public static final int WINDOWS = 2;
  34. public static final int SOLARIS = 3;
  35. public static final int FREEBSD = 4;
  36. public static final int OPENBSD = 5;
  37. public static final int WINDOWSCE = 6;
  38. public static final int AIX = 7;
  39. public static final int ANDROID = 8;
  40. public static final int GNU = 9;
  41. public static final int KFREEBSD = 10;
  42. public static final int NETBSD = 11;
  43. /** Whether read-only (final) fields within Structures are supported. */
  44. public static final boolean RO_FIELDS;
  45. /** Whether this platform provides NIO Buffers. */
  46. public static final boolean HAS_BUFFERS;
  47. /** Whether this platform provides the AWT Component class; also false if
  48. * running headless.
  49. */
  50. public static final boolean HAS_AWT;
  51. /** Whether this platform supports the JAWT library. */
  52. public static final boolean HAS_JAWT;
  53. /** Canonical name of this platform's math library. */
  54. public static final String MATH_LIBRARY_NAME;
  55. /** Canonical name of this platform's C runtime library. */
  56. public static final String C_LIBRARY_NAME;
  57. /** Whether in-DLL callbacks are supported. */
  58. public static final boolean HAS_DLL_CALLBACKS;
  59. /** Canonical resource prefix for the current platform. This value is
  60. * used to load bundled native libraries from the class path.
  61. */
  62. public static final String RESOURCE_PREFIX;
  63. private static final int osType;
  64. /** Current platform architecture. */
  65. public static final String ARCH;
  66. static {
  67. String osName = System.getProperty("os.name");
  68. if (osName.startsWith("Linux")) {
  69. if ("dalvik".equals(System.getProperty("java.vm.name").toLowerCase())) {
  70. osType = ANDROID;
  71. // Native libraries on android must be bundled with the APK
  72. System.setProperty("jna.nounpack", "true");
  73. }
  74. else {
  75. osType = LINUX;
  76. }
  77. }
  78. else if (osName.startsWith("AIX")) {
  79. osType = AIX;
  80. }
  81. else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
  82. osType = MAC;
  83. }
  84. else if (osName.startsWith("Windows CE")) {
  85. osType = WINDOWSCE;
  86. }
  87. else if (osName.startsWith("Windows")) {
  88. osType = WINDOWS;
  89. }
  90. else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
  91. osType = SOLARIS;
  92. }
  93. else if (osName.startsWith("FreeBSD")) {
  94. osType = FREEBSD;
  95. }
  96. else if (osName.startsWith("OpenBSD")) {
  97. osType = OPENBSD;
  98. }
  99. else if (osName.equalsIgnoreCase("gnu")) {
  100. osType = GNU;
  101. }
  102. else if (osName.equalsIgnoreCase("gnu/kfreebsd")) {
  103. osType = KFREEBSD;
  104. }
  105. else if (osName.equalsIgnoreCase("netbsd")) {
  106. osType = NETBSD;
  107. }
  108. else {
  109. osType = UNSPECIFIED;
  110. }
  111. boolean hasBuffers = false;
  112. try {
  113. Class.forName("java.nio.Buffer");
  114. hasBuffers = true;
  115. }
  116. catch(ClassNotFoundException e) {
  117. }
  118. // NOTE: we used to do Class.forName("java.awt.Component"), but that
  119. // has the unintended side effect of actually loading AWT native libs,
  120. // which can be problematic
  121. HAS_AWT = osType != WINDOWSCE && osType != ANDROID && osType != AIX;
  122. HAS_JAWT = HAS_AWT && osType != MAC;
  123. HAS_BUFFERS = hasBuffers;
  124. RO_FIELDS = osType != WINDOWSCE;
  125. C_LIBRARY_NAME = osType == WINDOWS ? "msvcrt" : osType == WINDOWSCE ? "coredll" : "c";
  126. MATH_LIBRARY_NAME = osType == WINDOWS ? "msvcrt" : osType == WINDOWSCE ? "coredll" : "m";
  127. ARCH = getCanonicalArchitecture(System.getProperty("os.arch"), osType);
  128. // Windows aarch64 callbacks disabled via ASMFN_OFF (no mingw support)
  129. HAS_DLL_CALLBACKS = osType == WINDOWS && !ARCH.startsWith("aarch");
  130. RESOURCE_PREFIX = getNativeLibraryResourcePrefix();
  131. }
  132. private Platform() { }
  133. public static final int getOSType() {
  134. return osType;
  135. }
  136. public static final boolean isMac() {
  137. return osType == MAC;
  138. }
  139. public static final boolean isAndroid() {
  140. return osType == ANDROID;
  141. }
  142. public static final boolean isLinux() {
  143. return osType == LINUX;
  144. }
  145. public static final boolean isAIX() {
  146. return osType == AIX;
  147. }
  148. public static final boolean isWindowsCE() {
  149. return osType == WINDOWSCE;
  150. }
  151. /** Returns true for any windows variant. */
  152. public static final boolean isWindows() {
  153. return osType == WINDOWS || osType == WINDOWSCE;
  154. }
  155. public static final boolean isSolaris() {
  156. return osType == SOLARIS;
  157. }
  158. public static final boolean isFreeBSD() {
  159. return osType == FREEBSD;
  160. }
  161. public static final boolean isOpenBSD() {
  162. return osType == OPENBSD;
  163. }
  164. public static final boolean isNetBSD() {
  165. return osType == NETBSD;
  166. }
  167. public static final boolean isGNU() {
  168. return osType == GNU;
  169. }
  170. public static final boolean iskFreeBSD() {
  171. return osType == KFREEBSD;
  172. }
  173. public static final boolean isX11() {
  174. // TODO: check filesystem for /usr/X11 or some other X11-specific test
  175. return !Platform.isWindows() && !Platform.isMac();
  176. }
  177. public static final boolean hasRuntimeExec() {
  178. if (isWindowsCE() && "J9".equals(System.getProperty("java.vm.name")))
  179. return false;
  180. return true;
  181. }
  182. public static final boolean is64Bit() {
  183. String model = System.getProperty("sun.arch.data.model",
  184. System.getProperty("com.ibm.vm.bitmode"));
  185. if (model != null) {
  186. return "64".equals(model);
  187. }
  188. if ("x86-64".equals(ARCH)
  189. || "ia64".equals(ARCH)
  190. || "ppc64".equals(ARCH) || "ppc64le".equals(ARCH)
  191. || "sparcv9".equals(ARCH)
  192. || "mips64".equals(ARCH) || "mips64el".equals(ARCH)
  193. || "amd64".equals(ARCH)
  194. || "aarch64".equals(ARCH)) {
  195. return true;
  196. }
  197. return Native.POINTER_SIZE == 8;
  198. }
  199. public static final boolean isIntel() {
  200. if (ARCH.startsWith("x86")) {
  201. return true;
  202. }
  203. return false;
  204. }
  205. public static final boolean isPPC() {
  206. if (ARCH.startsWith("ppc")) {
  207. return true;
  208. }
  209. return false;
  210. }
  211. public static final boolean isARM() {
  212. return ARCH.startsWith("arm") || ARCH.startsWith("aarch");
  213. }
  214. public static final boolean isSPARC() {
  215. return ARCH.startsWith("sparc");
  216. }
  217. public static final boolean isMIPS() {
  218. if (ARCH.equals("mips")
  219. || ARCH.equals("mips64")
  220. || ARCH.equals("mipsel")
  221. || ARCH.equals("mips64el")) {
  222. return true;
  223. }
  224. return false;
  225. }
  226. static String getCanonicalArchitecture(String arch, int platform) {
  227. arch = arch.toLowerCase().trim();
  228. if ("powerpc".equals(arch)) {
  229. arch = "ppc";
  230. }
  231. else if ("powerpc64".equals(arch)) {
  232. arch = "ppc64";
  233. }
  234. else if ("i386".equals(arch) || "i686".equals(arch)) {
  235. arch = "x86";
  236. }
  237. else if ("x86_64".equals(arch) || "amd64".equals(arch)) {
  238. arch = "x86-64";
  239. }
  240. else if ("zarch_64".equals(arch)) {
  241. arch = "s390x";
  242. }
  243. // Work around OpenJDK mis-reporting os.arch
  244. // https://bugs.openjdk.java.net/browse/JDK-8073139
  245. if ("ppc64".equals(arch) && "little".equals(System.getProperty("sun.cpu.endian"))) {
  246. arch = "ppc64le";
  247. }
  248. // Map arm to armel if the binary is running as softfloat build
  249. if("arm".equals(arch) && platform == Platform.LINUX && isSoftFloat()) {
  250. arch = "armel";
  251. }
  252. return arch;
  253. }
  254. static boolean isSoftFloat() {
  255. try {
  256. File self = new File("/proc/self/exe");
  257. if (self.exists()) {
  258. ELFAnalyser ahfd = ELFAnalyser.analyse(self.getCanonicalPath());
  259. return ! ahfd.isArmHardFloat();
  260. }
  261. } catch (IOException ex) {
  262. // asume hardfloat
  263. Logger.getLogger(Platform.class.getName()).log(Level.INFO, "Failed to read '/proc/self/exe' or the target binary.", ex);
  264. } catch (SecurityException ex) {
  265. // asume hardfloat
  266. Logger.getLogger(Platform.class.getName()).log(Level.INFO, "SecurityException while analysing '/proc/self/exe' or the target binary.", ex);
  267. }
  268. return false;
  269. }
  270. /** Generate a canonical String prefix based on the current OS
  271. type/arch/name.
  272. */
  273. static String getNativeLibraryResourcePrefix() {
  274. String prefix = System.getProperty("jna.prefix");
  275. if(prefix != null) {
  276. return prefix;
  277. } else {
  278. return getNativeLibraryResourcePrefix(getOSType(), System.getProperty("os.arch"), System.getProperty("os.name"));
  279. }
  280. }
  281. /** Generate a canonical String prefix based on the given OS
  282. type/arch/name.
  283. @param osType from {@link #getOSType()}
  284. @param arch from <code>os.arch</code> System property
  285. @param name from <code>os.name</code> System property
  286. */
  287. static String getNativeLibraryResourcePrefix(int osType, String arch, String name) {
  288. String osPrefix;
  289. arch = getCanonicalArchitecture(arch, osType);
  290. switch(osType) {
  291. case Platform.ANDROID:
  292. if (arch.startsWith("arm")) {
  293. arch = "arm";
  294. }
  295. osPrefix = "android-" + arch;
  296. break;
  297. case Platform.WINDOWS:
  298. osPrefix = "win32-" + arch;
  299. break;
  300. case Platform.WINDOWSCE:
  301. osPrefix = "w32ce-" + arch;
  302. break;
  303. case Platform.MAC:
  304. osPrefix = "darwin-" + arch;
  305. break;
  306. case Platform.LINUX:
  307. osPrefix = "linux-" + arch;
  308. break;
  309. case Platform.SOLARIS:
  310. osPrefix = "sunos-" + arch;
  311. break;
  312. case Platform.FREEBSD:
  313. osPrefix = "freebsd-" + arch;
  314. break;
  315. case Platform.OPENBSD:
  316. osPrefix = "openbsd-" + arch;
  317. break;
  318. case Platform.NETBSD:
  319. osPrefix = "netbsd-" + arch;
  320. break;
  321. case Platform.KFREEBSD:
  322. osPrefix = "kfreebsd-" + arch;
  323. break;
  324. default:
  325. osPrefix = name.toLowerCase();
  326. int space = osPrefix.indexOf(" ");
  327. if (space != -1) {
  328. osPrefix = osPrefix.substring(0, space);
  329. }
  330. osPrefix += "-" + arch;
  331. break;
  332. }
  333. return osPrefix;
  334. }
  335. }