Skip to content

Commit

Permalink
Add CFEqual, CFDictionaryRef.ByReference, CFStringRef.ByReference to …
Browse files Browse the repository at this point in the history
…CoreFoundation
  • Loading branch information
shalupov committed May 5, 2022
1 parent ca465ee commit a40cd59
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------
Expand Down
53 changes: 53 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -248,4 +249,69 @@ 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()));

CF.CFRelease(key);
CF.CFRelease(value);
CF.CFRelease(dict);
}

@Test
public void testCFDictionaryRefByReference() {
CFStringRef key = CFStringRef.createCFString("key");

CFMutableDictionaryRef value = CF.CFDictionaryCreateMutable(null, new CFIndex(2), null, null);
value.setValue(key, key);

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()));

CF.CFRelease(key);
CF.CFRelease(value);
CF.CFRelease(dict);
}

@Test
public void testCFEqual() {
CFStringRef s1 = CFStringRef.createCFString("s1");
CFStringRef s1_the_same = CFStringRef.createCFString("s1");
CFStringRef s2 = CFStringRef.createCFString("s2");

assertTrue(CF.CFEqual(s1, s1));
assertTrue(CF.CFEqual(s1, s1_the_same));

assertFalse(CF.CFEqual(s1, s2));

CFMutableDictionaryRef dict1 = CF.CFDictionaryCreateMutable(null, new CFIndex(2), null, null);
dict1.setValue(s1, s1);
CFMutableDictionaryRef dict2 = CF.CFDictionaryCreateMutable(null, new CFIndex(2), null, null);
dict2.setValue(s1, s1);

assertNotEquals(dict1.getPointer(), dict2.getPointer());
assertTrue(CF.CFEqual(dict1, dict2));

dict2.setValue(s1, s2);
assertFalse(CF.CFEqual(dict1, dict2));

CF.CFRelease(dict1);
CF.CFRelease(dict2);
CF.CFRelease(s1);
CF.CFRelease(s1_the_same);
CF.CFRelease(s2);
}
}

0 comments on commit a40cd59

Please sign in to comment.