Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CFEqual, CFDictionaryRef.ByReference, CFStringRef.ByReference to CoreFoundation #1433

Merged
merged 2 commits into from May 7, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
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
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());
shalupov marked this conversation as resolved.
Show resolved Hide resolved
}

public CoreFoundation.CFDictionaryRef getDictionaryRefValue() {
shalupov marked this conversation as resolved.
Show resolved Hide resolved
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());
shalupov marked this conversation as resolved.
Show resolved Hide resolved
}

public CoreFoundation.CFStringRef getStringRefValue() {
dbwiddis marked this conversation as resolved.
Show resolved Hide resolved
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
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);
}
}