From a8a26ed3c40c7a929b20ba0987b2728b4d525530 Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Thu, 5 May 2022 14:47:50 +0200 Subject: [PATCH] Add CFEqual, CFDictionaryRef.ByReference, CFStringRef.ByReference to CoreFoundation --- CHANGES.md | 1 + .../sun/jna/platform/mac/CoreFoundation.java | 53 +++++++++++++++++++ .../jna/platform/mac/CoreFoundationTest.java | 52 ++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index cf3560a904..40442a5e41 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Next Release (5.12.0) Features -------- +* [#1433](https://github.com/java-native-access/jna/pull/1433): Add `CFEqual`, `CFDictionaryRef.ByReference`, `CFStringRef.ByReference` to `c.s.j.p.mac.CoreFoundation` - [@shalupov](https://github.com/shalupov) Bug Fixes --------- 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 7301ae6cc9..34c54fe78d 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java @@ -377,6 +377,29 @@ public Pointer getBytePtr() { * A reference to an immutable {@code CFDictionary} object. */ class CFDictionaryRef extends CFTypeRef { + + /** + * Placeholder for a reference to a {@code CFDictionary} object. + */ + public static class ByReference extends PointerByReference { + public ByReference() { + super(); + } + + public ByReference(CoreFoundation.CFStringRef value) { + super(value.getPointer()); + } + + public CoreFoundation.CFDictionaryRef getDictionaryRefValue() { + Pointer value = super.getValue(); + if (value == null) { + return null; + } + + return new CoreFoundation.CFDictionaryRef(value); + } + } + public CFDictionaryRef() { super(); } @@ -460,6 +483,28 @@ public void setValue(PointerType key, PointerType value) { * the characteristics and behavior of {@code CFString} objects. */ class CFStringRef extends CFTypeRef { + + /** + * Placeholder for a reference to a {@code CFString} object. + */ + public static class ByReference extends PointerByReference { + public ByReference() { + } + + public ByReference(CoreFoundation.CFStringRef value) { + super(value.getPointer()); + } + + public CoreFoundation.CFStringRef getStringRefValue() { + Pointer value = super.getValue(); + if (value == null) { + return null; + } + + return new CoreFoundation.CFStringRef(value); + } + } + public CFStringRef() { super(); } @@ -974,6 +1019,14 @@ CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef alloc, CFIndex c */ CFIndex CFStringGetMaximumSizeForEncoding(CFIndex length, int encoding); + /** + * Determines whether two Core Foundation objects are considered equal. + * @param cf1 A CFType object to compare to cf2. + * @param cf2 A CFType object to compare to cf1. + * @return true if cf1 and cf2 are of the same type and considered equal, otherwise false. + */ + boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2); + /** * Gets the default allocator object for the current thread. * 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 ee5b949d00..039a53d5c2 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 java.util.List; import java.util.Random; +import com.sun.jna.platform.mac.CoreFoundation.CFDictionaryRef; import org.junit.Test; import com.sun.jna.Memory; @@ -248,4 +249,55 @@ public void testCFDictionary() { cfOne.release(); dict.release(); } + + @Test + public void testCFStringRefByReference() { + CFStringRef key = CFStringRef.createCFString("key"); + CFStringRef value = CFStringRef.createCFString("value"); + + CFMutableDictionaryRef dict = CF.CFDictionaryCreateMutable(null, new CFIndex(2), null, null); + dict.setValue(key, value); + + CFStringRef.ByReference byRef = new CFStringRef.ByReference(); + assertTrue(dict.getValueIfPresent(key, byRef)); + assertTrue(CF.CFEqual(value, byRef.getStringRefValue())); + } + + @Test + public void testCFDictionaryRefByReference() { + CFStringRef key = CFStringRef.createCFString("key"); + + CFMutableDictionaryRef value = CF.CFDictionaryCreateMutable(null, new CFIndex(2), null, null); + value.setValue(CFStringRef.createCFString("1"), CFStringRef.createCFString("2")); + + CFMutableDictionaryRef dict = CF.CFDictionaryCreateMutable(null, new CFIndex(2), null, null); + dict.setValue(key, value); + + CFDictionaryRef.ByReference byRef = new CFDictionaryRef.ByReference(); + assertTrue(dict.getValueIfPresent(key, byRef)); + assertTrue(CF.CFEqual(value, byRef.getDictionaryRefValue())); + } + + @Test + public void testCFEqual() { + CFAllocatorRef alloc = CF.CFAllocatorGetDefault(); + + CFStringRef s1 = CFStringRef.createCFString("s1"); + + assertTrue(CF.CFEqual(s1, s1)); + assertTrue(CF.CFEqual(s1, CFStringRef.createCFString("s1"))); + + assertFalse(CF.CFEqual(s1, CFStringRef.createCFString("s2"))); + + CFMutableDictionaryRef dict1 = CF.CFDictionaryCreateMutable(alloc, new CFIndex(2), null, null); + dict1.setValue(s1, s1); + CFMutableDictionaryRef dict2 = CF.CFDictionaryCreateMutable(alloc, new CFIndex(2), null, null); + dict2.setValue(s1, s1); + + assertNotEquals(dict1.getPointer(), dict2.getPointer()); + assertTrue(CF.CFEqual(dict1, dict2)); + + dict2.setValue(s1, CFStringRef.createCFString("s2")); + assertFalse(CF.CFEqual(dict1, dict2)); + } }