From be82280a6568b33a6ae8f8847fae61042cda6949 Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Mon, 2 Sep 2019 22:43:53 -0700 Subject: [PATCH] Better type mappings --- .../sun/jna/platform/mac/CoreFoundation.java | 77 ++++++++++++++++--- .../jna/platform/mac/CoreFoundationUtil.java | 41 ++++++---- .../jna/platform/mac/CoreFoundationTest.java | 55 ++++++++----- .../jna/platform/mac/DiskArbitrationTest.java | 26 +++++-- .../com/sun/jna/platform/mac/IOKitTest.java | 62 +++++++++------ 5 files changed, 190 insertions(+), 71 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java b/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java index 488c7144f9..52af0f4ab7 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java @@ -70,6 +70,13 @@ public interface CoreFoundation extends Library { * Foundation objects. */ class CFTypeRef extends PointerType { + public CFTypeRef() { + super(); + } + + public CFTypeRef(Pointer p) { + super(p); + } } /** @@ -84,6 +91,13 @@ class CFAllocatorRef extends CFTypeRef { * A reference to a {@code CFNumber} object. */ class CFNumberRef extends CFTypeRef { + public CFNumberRef() { + super(); + } + + public CFNumberRef(Pointer p) { + super(p); + } } /** @@ -102,6 +116,13 @@ enum CFNumberType { * A reference to a {@code CFBoolean} object. */ class CFBooleanRef extends CFTypeRef { + public CFBooleanRef() { + super(); + } + + public CFBooleanRef(Pointer p) { + super(p); + } } /** @@ -112,24 +133,52 @@ class CFBooleanRef extends CFTypeRef { * parameter, you can pass in a {@link #CFArrayRef}. */ class CFArrayRef extends CFTypeRef { + public CFArrayRef() { + super(); + } + + public CFArrayRef(Pointer p) { + super(p); + } } /** * A reference to an immutable {@code CFData} object. */ class CFDataRef extends CFTypeRef { + public CFDataRef() { + super(); + } + + public CFDataRef(Pointer p) { + super(p); + } } /** * A reference to an immutable {@code CFDictionary} object. */ class CFDictionaryRef extends CFTypeRef { + public CFDictionaryRef() { + super(); + } + + public CFDictionaryRef(Pointer p) { + super(p); + } } /** * A reference to a mutable {@code CFDictionary} object. */ class CFMutableDictionaryRef extends CFDictionaryRef { + public CFMutableDictionaryRef() { + super(); + } + + public CFMutableDictionaryRef(Pointer p) { + super(p); + } } /** @@ -138,6 +187,14 @@ class CFMutableDictionaryRef extends CFDictionaryRef { * the characteristics and behavior of {@code CFString} objects. */ class CFStringRef extends CFTypeRef { + public CFStringRef() { + super(); + } + + public CFStringRef(Pointer p) { + super(p); + } + /** * Convenience function which calls {@link #CFStringCreateWithCharacters} to * create a new {@code CFString} from the given Java {@link java.lang.String} @@ -314,7 +371,7 @@ public static CFStringRef toCFString(String s) { * @return A new dictionary, or {@code null} if there was a problem creating the * object. */ - CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capacity, Pointer keyCallBacks, + CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capacity, PointerType keyCallBacks, Pointer valueCallBacks); /** @@ -394,7 +451,7 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * {@link #CFDictionaryGetValueIfPresent} to distinguish between a value * that is not found, and a {@code null} value. */ - CFTypeRef CFDictionaryGetValue(CFTypeRef theDict, CFStringRef key); + Pointer CFDictionaryGetValue(CFTypeRef theDict, PointerType key); /** * Returns a boolean value that indicates whether a given value for a given key @@ -420,7 +477,7 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * was present). * @return {@code true} if a matching key was found, otherwise {@code false}. */ - boolean CFDictionaryGetValueIfPresent(CFDictionaryRef theDict, CFStringRef key, PointerType value); + boolean CFDictionaryGetValueIfPresent(CFDictionaryRef theDict, PointerType key, PointerByReference value); /** * Sets the value corresponding to a given key. @@ -447,7 +504,7 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * released. {@code value} must be of the type expected by the retain * and release callbacks. */ - void CFDictionarySetValue(CFMutableDictionaryRef theDict, CFTypeRef key, CFTypeRef value); + void CFDictionarySetValue(CFMutableDictionaryRef theDict, PointerType key, PointerType value); /** * Copies the character contents of a string to a local C string buffer after @@ -503,7 +560,7 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * @return A constant that indicates the data type of the value contained in * number. See {@link CFNumberType} for a list of possible values. */ - int CFNumberGetType(CFTypeRef number); + int CFNumberGetType(CFNumberRef number); /** * Obtains the value of a {@code CFNumber} object cast to a specified type. @@ -515,8 +572,10 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * {@link CFNumberType} for a list of possible values. * @param On * return, contains the value of {@code number}. + * @return {@code true} if the operation was successful, otherwise + * {@code false}. */ - void CFNumberGetValue(CFTypeRef number, int theType, ByReference valuePtr); + boolean CFNumberGetValue(CFNumberRef number, int theType, ByReference valuePtr); /** * Returns the number (in terms of UTF-16 code pairs) of Unicode characters in a @@ -527,7 +586,7 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * @return The number (in terms of UTF-16 code pairs) of characters stored in * {@code theString}. */ - long CFStringGetLength(CFTypeRef theString); + long CFStringGetLength(CFStringRef theString); /** * Returns the maximum number of bytes a string of a specified length (in @@ -560,7 +619,7 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * The {@code CFData} object to examine. * @return An index that specifies the number of bytes in {@code theData}. */ - long CFDataGetLength(CFTypeRef theData); + long CFDataGetLength(CFDataRef theData); /** * Returns a read-only pointer to the bytes of a {@code CFData} object. @@ -569,5 +628,5 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, int capac * The {@code CFData} object to examine. * @return A read-only pointer to the bytes associated with {@code theData}. */ - PointerByReference CFDataGetBytePtr(CFTypeRef theData); + PointerByReference CFDataGetBytePtr(CFDataRef theData); } diff --git a/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundationUtil.java b/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundationUtil.java index 632ff74f7a..3d4f997cd0 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundationUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundationUtil.java @@ -29,7 +29,10 @@ import java.util.Collection; import com.sun.jna.Memory; +import com.sun.jna.platform.mac.CoreFoundation.CFBooleanRef; +import com.sun.jna.platform.mac.CoreFoundation.CFNumberRef; import com.sun.jna.platform.mac.CoreFoundation.CFNumberType; +import com.sun.jna.platform.mac.CoreFoundation.CFStringRef; import com.sun.jna.platform.mac.CoreFoundation.CFTypeRef; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; @@ -45,13 +48,18 @@ private CoreFoundationUtil() { } /** - * Convert a reference to a Core Foundations LongLong into its {@code long} + * Convert a reference to a Core Foundations LongLong into its {@code long}. + *

+ * This method assumes a 64-bit number is stored and does not do type checking. + * If the argument type differs from the return type, and the conversion is + * lossy or the return value is out of range, then this function passes back an + * approximate value. * * @param theLong * The pointer to a 64-bit integer * @return The corresponding {@code long} */ - public static long cfPointerToLong(CFTypeRef theLong) { + public static long cfPointerToLong(CFNumberRef theLong) { LongByReference lbr = new LongByReference(); CF.CFNumberGetValue(theLong, CFNumberType.kCFNumberLongLongType.ordinal(), lbr); return lbr.getValue(); @@ -59,48 +67,53 @@ public static long cfPointerToLong(CFTypeRef theLong) { /** * Convert a reference to a Core Foundations Int into its {@code int} + *

+ * This method assumes a 32-bit number is stored and does not do type checking. + * If the argument type differs from the return type, and the conversion is + * lossy or the return value is out of range, then this function passes back an + * approximate value. * - * @param p + * @param theInt * The pointer to an integer * @return The corresponding {@code int} */ - public static int cfPointerToInt(CFTypeRef p) { + public static int cfPointerToInt(CFNumberRef theInt) { IntByReference ibr = new IntByReference(); - CF.CFNumberGetValue(p, CFNumberType.kCFNumberIntType.ordinal(), ibr); + CF.CFNumberGetValue(theInt, CFNumberType.kCFNumberIntType.ordinal(), ibr); return ibr.getValue(); } /** * Convert a reference to a Core Foundations Boolean into its {@code boolean} * - * @param cfBoolean + * @param theBoolean * The pointer to a boolean * @return The corresponding {@code boolean} */ - public static boolean cfPointerToBoolean(CFTypeRef cfBoolean) { - return CF.CFBooleanGetValue(cfBoolean); + public static boolean cfPointerToBoolean(CFBooleanRef theBoolean) { + return CF.CFBooleanGetValue(theBoolean); } /** * Convert a reference to a Core Foundations String into its * {@link java.lang.String} * - * @param cfTypeRef + * @param theString * The pointer to a CFString * @return The corresponding {@link java.lang.String} */ - public static String cfPointerToString(CFTypeRef cfTypeRef) { - if (cfTypeRef == null) { + public static String cfPointerToString(CFStringRef theString) { + if (theString == null) { return "null"; } - long length = CF.CFStringGetLength(cfTypeRef); + long length = CF.CFStringGetLength(theString); long maxSize = CF.CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); if (maxSize == CoreFoundation.kCFNotFound) { maxSize = 4 * (length + 1); } Memory buf = new Memory(maxSize); - CF.CFStringGetCString(cfTypeRef, buf, maxSize, kCFStringEncodingUTF8); - return buf.getString(0); + CF.CFStringGetCString(theString, buf, maxSize, kCFStringEncodingUTF8); + return buf.getString(0, "UTF8"); } /** diff --git a/contrib/platform/test/com/sun/jna/platform/mac/CoreFoundationTest.java b/contrib/platform/test/com/sun/jna/platform/mac/CoreFoundationTest.java index ebba50c95b..50765f49b0 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/CoreFoundationTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/CoreFoundationTest.java @@ -38,6 +38,7 @@ import com.sun.jna.Memory; import com.sun.jna.Native; +import com.sun.jna.Pointer; import com.sun.jna.platform.mac.CoreFoundation.CFAllocatorRef; import com.sun.jna.platform.mac.CoreFoundation.CFArrayRef; import com.sun.jna.platform.mac.CoreFoundation.CFDataRef; @@ -57,18 +58,18 @@ public class CoreFoundationTest { @Test public void testCFStringRef() { - String awesome = "JNA is awesome"; + String awesome = "ǝɯosǝʍɐ sı ∀Nſ"; // Unicode CFStringRef cfAwesome = CFStringRef.toCFString(awesome); assertEquals(awesome.length(), CF.CFStringGetLength(cfAwesome)); assertEquals(awesome, CoreFoundationUtil.cfPointerToString(cfAwesome)); - Memory mem = new Memory(awesome.length() + 1); + Memory mem = new Memory(awesome.getBytes().length + 1); mem.clear(); assertTrue(CF.CFStringGetCString(cfAwesome, mem, mem.size(), CoreFoundation.kCFStringEncodingUTF8)); byte[] awesomeBytes = mem.getByteArray(0, (int) mem.size() - 1); - char[] awesomeArr = awesome.toCharArray(); + byte[] awesomeArr = awesome.getBytes(); for (int i = 0; i < awesomeArr.length; i++) { - assertEquals((byte) awesomeArr[i], awesomeBytes[i]); + assertEquals(awesomeArr[i], awesomeBytes[i]); } // Essentially a toString, can't rely on format but should contain the string CFStringRef desc = CF.CFCopyDescription(cfAwesome); @@ -89,10 +90,11 @@ public void testCFNumberRef() { IntByReference one = new IntByReference(1); CFNumberRef cfZero = CF.CFNumberCreate(null, CFNumberType.kCFNumberIntType.ordinal(), zero); CFNumberRef cfOne = CF.CFNumberCreate(null, CFNumberType.kCFNumberIntType.ordinal(), one); + assertEquals(0, CoreFoundationUtil.cfPointerToInt(cfZero)); assertEquals(1, CoreFoundationUtil.cfPointerToInt(cfOne)); - assertEquals(false, CoreFoundationUtil.cfPointerToBoolean(cfZero)); - assertEquals(true, CoreFoundationUtil.cfPointerToBoolean(cfOne)); + // assertEquals(false, CoreFoundationUtil.cfPointerToBoolean(cfZero)); + // assertEquals(true, CoreFoundationUtil.cfPointerToBoolean(cfOne)); release(cfZero); release(cfOne); } @@ -138,7 +140,8 @@ public void testCFArray() { assertEquals(refArray.length, CF.CFArrayGetCount(cfPtrArray)); for (int i = 0; i < refArray.length; i++) { - CFTypeRef numRef = CF.CFArrayGetValueAtIndex(cfPtrArray, i); + CFTypeRef result = CF.CFArrayGetValueAtIndex(cfPtrArray, i); + CFNumberRef numRef = new CFNumberRef(result.getPointer()); assertEquals(i, CoreFoundationUtil.cfPointerToInt(numRef)); } @@ -168,28 +171,42 @@ public void testCFData() { public void testCFDictionary() { CFAllocatorRef alloc = CF.CFAllocatorGetDefault(); CFMutableDictionaryRef dict = CF.CFDictionaryCreateMutable(alloc, 2, null, null); - CFStringRef oneKey = CFStringRef.toCFString("one"); + CFStringRef oneStr = CFStringRef.toCFString("one"); // Key does not exist, returns null - assertFalse(CF.CFDictionaryGetValueIfPresent(dict, oneKey, null)); - CFTypeRef cfNull = CF.CFDictionaryGetValue(dict, oneKey); + assertFalse(CF.CFDictionaryGetValueIfPresent(dict, oneStr, null)); + Pointer cfNull = CF.CFDictionaryGetValue(dict, oneStr); assertNull(cfNull); // Store and retrieve null value - CF.CFDictionarySetValue(dict, oneKey, null); - assertTrue(CF.CFDictionaryGetValueIfPresent(dict, oneKey, null)); - CFTypeRef cfNullValue = CF.CFDictionaryGetValue(dict, oneKey); + CF.CFDictionarySetValue(dict, oneStr, null); + assertTrue(CF.CFDictionaryGetValueIfPresent(dict, oneStr, null)); + Pointer cfNullValue = CF.CFDictionaryGetValue(dict, oneStr); assertNull(cfNullValue); // Store (replace the null) and retrieve integer value IntByReference one = new IntByReference(1); CFNumberRef cfOne = CF.CFNumberCreate(null, CFNumberType.kCFNumberIntType.ordinal(), one); - CF.CFDictionarySetValue(dict, oneKey, cfOne); - assertTrue(CF.CFDictionaryGetValueIfPresent(dict, oneKey, null)); - CFTypeRef cfValue = CF.CFDictionaryGetValue(dict, oneKey); - assertEquals(1, CoreFoundationUtil.cfPointerToInt(cfValue)); - - release(oneKey); + CF.CFDictionarySetValue(dict, oneStr, cfOne); + + assertTrue(CF.CFDictionaryGetValueIfPresent(dict, oneStr, null)); + Pointer result = CF.CFDictionaryGetValue(dict, oneStr); + CFNumberRef numRef = new CFNumberRef(result); + assertEquals(1, CoreFoundationUtil.cfPointerToInt(numRef)); + + PointerByReference resultPtr = new PointerByReference(); + assertTrue(CF.CFDictionaryGetValueIfPresent(dict, oneStr, resultPtr)); + numRef = new CFNumberRef(resultPtr.getValue()); + assertEquals(1, CoreFoundationUtil.cfPointerToInt(numRef)); + + // Test non-CF type as key + IntByReference onePtr = new IntByReference(1); + CF.CFDictionarySetValue(dict, onePtr, oneStr); + result = CF.CFDictionaryGetValue(dict, onePtr); + CFStringRef strRef = new CFStringRef(result); + assertEquals("one", CoreFoundationUtil.cfPointerToString(strRef)); + + release(oneStr); release(cfOne); release(dict); } diff --git a/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java b/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java index bb21a09718..0843892948 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/DiskArbitrationTest.java @@ -26,6 +26,7 @@ import static com.sun.jna.platform.mac.CoreFoundationUtil.release; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -35,8 +36,11 @@ import org.junit.Test; +import com.sun.jna.Pointer; +import com.sun.jna.platform.mac.CoreFoundation.CFBooleanRef; import com.sun.jna.platform.mac.CoreFoundation.CFDictionaryRef; import com.sun.jna.platform.mac.CoreFoundation.CFMutableDictionaryRef; +import com.sun.jna.platform.mac.CoreFoundation.CFNumberRef; import com.sun.jna.platform.mac.CoreFoundation.CFStringRef; import com.sun.jna.platform.mac.CoreFoundation.CFTypeRef; import com.sun.jna.platform.mac.DiskArbitration.DADiskRef; @@ -58,6 +62,7 @@ public void testDiskCreate() { // Create some keys we'll need CFStringRef daMediaBSDName = CFStringRef.toCFString("DAMediaBSDName"); CFStringRef daMediaWhole = CFStringRef.toCFString("DAMediaWhole"); + CFStringRef daMediaLeaf = CFStringRef.toCFString("DAMediaLeaf"); CFStringRef daMediaSize = CFStringRef.toCFString("DAMediaSize"); CFStringRef daMediaBlockSize = CFStringRef.toCFString("DAMediaBlockSize"); @@ -78,8 +83,8 @@ public void testDiskCreate() { CFTypeRef cfWhole = IO.IORegistryEntryCreateCFProperty(media, wholeKey, CF.CFAllocatorGetDefault(), 0); CoreFoundationUtil.release(wholeKey); assertNotNull(cfWhole); - - if (CoreFoundationUtil.cfPointerToBoolean(cfWhole)) { + CFBooleanRef cfWholeBool = new CFBooleanRef(cfWhole.getPointer()); + if (CoreFoundationUtil.cfPointerToBoolean(cfWholeBool)) { DADiskRef disk = DA.DADiskCreateFromIOMedia(CF.CFAllocatorGetDefault(), session, media); bsdNames.add(DA.DADiskGetBSDName(disk)); release(disk); @@ -103,15 +108,23 @@ public void testDiskCreate() { assertNotNull(diskInfo); // Since we looked up "whole" BSD disks these should match - CFTypeRef bsdNamePtr = CF.CFDictionaryGetValue(diskInfo, daMediaBSDName); + Pointer result = CF.CFDictionaryGetValue(diskInfo, daMediaBSDName); + CFStringRef bsdNamePtr = new CFStringRef(result); assertEquals(bsdName, CoreFoundationUtil.cfPointerToString(bsdNamePtr)); - CFTypeRef bsdWholePtr = CF.CFDictionaryGetValue(diskInfo, daMediaWhole); + result = CF.CFDictionaryGetValue(diskInfo, daMediaWhole); + CFBooleanRef bsdWholePtr = new CFBooleanRef(result); assertTrue(CoreFoundationUtil.cfPointerToBoolean(bsdWholePtr)); + result = CF.CFDictionaryGetValue(diskInfo, daMediaLeaf); + CFBooleanRef bsdLeafPtr = new CFBooleanRef(result); + assertFalse(CoreFoundationUtil.cfPointerToBoolean(bsdLeafPtr)); + // Size is a multiple of block size - CFTypeRef sizePtr = CF.CFDictionaryGetValue(diskInfo, daMediaSize); + result = CF.CFDictionaryGetValue(diskInfo, daMediaSize); + CFNumberRef sizePtr = new CFNumberRef(result); long size = CoreFoundationUtil.cfPointerToLong(sizePtr); - CFTypeRef blockSizePtr = CF.CFDictionaryGetValue(diskInfo, daMediaBlockSize); + result = CF.CFDictionaryGetValue(diskInfo, daMediaBlockSize); + CFNumberRef blockSizePtr = new CFNumberRef(result); long blockSize = CoreFoundationUtil.cfPointerToLong(blockSizePtr); assertEquals(0, size % blockSize); @@ -120,6 +133,7 @@ public void testDiskCreate() { } release(daMediaBSDName); release(daMediaWhole); + release(daMediaLeaf); release(daMediaSize); release(daMediaBlockSize); diff --git a/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java b/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java index 9525d011de..11ef7d706f 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/IOKitTest.java @@ -38,9 +38,12 @@ import org.junit.Test; import com.sun.jna.Memory; +import com.sun.jna.Pointer; import com.sun.jna.platform.mac.CoreFoundation.CFArrayRef; +import com.sun.jna.platform.mac.CoreFoundation.CFBooleanRef; import com.sun.jna.platform.mac.CoreFoundation.CFDictionaryRef; import com.sun.jna.platform.mac.CoreFoundation.CFMutableDictionaryRef; +import com.sun.jna.platform.mac.CoreFoundation.CFNumberRef; import com.sun.jna.platform.mac.CoreFoundation.CFStringRef; import com.sun.jna.platform.mac.CoreFoundation.CFTypeRef; import com.sun.jna.ptr.IntByReference; @@ -61,7 +64,8 @@ public void testMatching() { String match = "matching BSD Name"; CFMutableDictionaryRef dict = IO.IOBSDNameMatching(masterPort, 0, match); CFStringRef bsdNameKey = CFStringRef.toCFString("BSD Name"); - CFTypeRef cfBsdName = CF.CFDictionaryGetValue(dict, bsdNameKey); + Pointer result = CF.CFDictionaryGetValue(dict, bsdNameKey); + CFStringRef cfBsdName = new CFStringRef(result); assertEquals(match, CoreFoundationUtil.cfPointerToString(cfBsdName)); release(bsdNameKey); release(dict); @@ -69,7 +73,8 @@ public void testMatching() { match = "matching IOClass Name"; dict = IO.IOServiceNameMatching(match); CFStringRef classNameKey = CFStringRef.toCFString("IONameMatch"); - CFTypeRef cfClassName = CF.CFDictionaryGetValue(dict, classNameKey); + result = CF.CFDictionaryGetValue(dict, classNameKey); + CFStringRef cfClassName = new CFStringRef(result); assertEquals(match, CoreFoundationUtil.cfPointerToString(cfClassName)); release(classNameKey); release(dict); @@ -77,7 +82,8 @@ public void testMatching() { match = "IOPlatformExpertDevice"; dict = IO.IOServiceMatching(match); CFStringRef classKey = CFStringRef.toCFString("IOProviderClass"); - CFTypeRef cfClass = CF.CFDictionaryGetValue(dict, classKey); + result = CF.CFDictionaryGetValue(dict, classKey); + CFStringRef cfClass = new CFStringRef(result); assertEquals(match, CoreFoundationUtil.cfPointerToString(cfClass)); release(classKey); @@ -86,11 +92,12 @@ public void testMatching() { assertNotEquals(0, platformExpert); // Get a single key CFStringRef serialKey = CFStringRef.toCFString("IOPlatformSerialNumber"); - CFTypeRef cfSerial = IO.IORegistryEntryCreateCFProperty(platformExpert, serialKey, CF.CFAllocatorGetDefault(), - 0); - assertNotNull(cfSerial); + CFTypeRef cfSerialAsType = IO.IORegistryEntryCreateCFProperty(platformExpert, serialKey, + CF.CFAllocatorGetDefault(), 0); + assertNotNull(cfSerialAsType); + CFStringRef cfSerial = new CFStringRef(cfSerialAsType.getPointer()); String serialNumber = CoreFoundationUtil.cfPointerToString(cfSerial); - release(cfSerial); + release(cfSerialAsType); assertEquals(12, serialNumber.length()); // Get all the keys PointerByReference properties = new PointerByReference(); @@ -99,7 +106,8 @@ public void testMatching() { dict = new CFMutableDictionaryRef(); dict.setPointer(properties.getValue()); assertTrue(CF.CFDictionaryGetValueIfPresent(dict, serialKey, null)); - cfSerial = CF.CFDictionaryGetValue(dict, serialKey); + result = CF.CFDictionaryGetValue(dict, serialKey); + cfSerial = new CFStringRef(result); assertEquals(serialNumber, CoreFoundationUtil.cfPointerToString(cfSerial)); release(dict); assertEquals(0, IO.IOObjectRelease(platformExpert)); @@ -107,15 +115,17 @@ public void testMatching() { // Get a single key from a nested entry long root = IO.IORegistryGetRootEntry(masterPort); assertNotEquals(0, root); - cfSerial = IO.IORegistryEntrySearchCFProperty(root, "IOService", serialKey, CF.CFAllocatorGetDefault(), 0); + cfSerialAsType = IO.IORegistryEntrySearchCFProperty(root, "IOService", serialKey, CF.CFAllocatorGetDefault(), + 0); // without recursive search should be null - assertNull(cfSerial); - cfSerial = IO.IORegistryEntrySearchCFProperty(root, "IOService", serialKey, CF.CFAllocatorGetDefault(), + assertNull(cfSerialAsType); + cfSerialAsType = IO.IORegistryEntrySearchCFProperty(root, "IOService", serialKey, CF.CFAllocatorGetDefault(), IOKit.kIORegistryIterateRecursively); // with recursive search should return a match + cfSerial = new CFStringRef(cfSerialAsType.getPointer()); assertEquals(serialNumber, CoreFoundationUtil.cfPointerToString(cfSerial)); release(serialKey); - release(cfSerial); + release(cfSerialAsType); assertEquals(0, IO.IOObjectRelease(root)); assertEquals(0, IO.IOObjectRelease(masterPort)); @@ -239,18 +249,24 @@ public void testPowerSources() { // Get values from dictionary (See IOPSKeys.h) // Skip if not present - CFTypeRef isPresentRef = CF.CFDictionaryGetValue(dictionary, isPresentKey); - if (isPresentRef != null && CF.CFBooleanGetValue(isPresentRef)) { - // Remaining Capacity = current / max - IntByReference currentCapacity = new IntByReference(); - if (!CF.CFDictionaryGetValueIfPresent(dictionary, currentCapacityKey, currentCapacity)) { - currentCapacity.setValue(0); - } - IntByReference maxCapacity = new IntByReference(); - if (!CF.CFDictionaryGetValueIfPresent(dictionary, maxCapacityKey, maxCapacity)) { - maxCapacity.setValue(1); + Pointer result = CF.CFDictionaryGetValue(dictionary, isPresentKey); + if (result != null) { + CFBooleanRef isPresentRef = new CFBooleanRef(result); + if (CF.CFBooleanGetValue(isPresentRef)) { + int currentCapacity = 0; + if (CF.CFDictionaryGetValueIfPresent(dictionary, currentCapacityKey, null)) { + result = CF.CFDictionaryGetValue(dictionary, currentCapacityKey); + CFNumberRef cap = new CFNumberRef(result); + currentCapacity = CoreFoundationUtil.cfPointerToInt(cap); + } + int maxCapacity = 100; + if (CF.CFDictionaryGetValueIfPresent(dictionary, maxCapacityKey, null)) { + result = CF.CFDictionaryGetValue(dictionary, maxCapacityKey); + CFNumberRef cap = new CFNumberRef(result); + maxCapacity = CoreFoundationUtil.cfPointerToInt(cap); + } + assertTrue(currentCapacity <= maxCapacity); } - assertTrue(currentCapacity.getValue() <= maxCapacity.getValue()); } } release(isPresentKey);