Skip to content

Commit 31b94c5

Browse files
Merge branch 'pr-1182'
Closes: #1182
2 parents c33d3f0 + dcc1631 commit 31b94c5

11 files changed

+391
-9
lines changed

CHANGES.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ Features
1313
* [#1169](https://github.com/java-native-access/jna/issues/1169): Wait for process in getLinuxLdPaths - [@rdesgroppes](https://github.com/rdesgroppes).
1414
* [#1178](https://github.com/java-native-access/jna/pull/1178): Add `c.s.j.p.win32.IPHlpAPI#GetTcpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetUdpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetTcpStatisticsEx` and `c.s.j.p.win32.IPHlpAPI#GetUdpStatisticsEx` - [@dbwiddis](https://github.com/dbwiddis).
1515
* [#1191](https://github.com/java-native-access/jna/pull/1191): Add `c.s.j.p.win32.Advapi32Util#getTokenPrimaryGroup` - [@dbwiddis](https://github.com/dbwiddis).
16+
* [#1182](https://github.com/java-native-access/jna/pull/1182): Add `toString` to classes extending `c.s.j.ptr.ByReference` - [@dbwiddis](https://github.com/dbwiddis).
1617

1718
Bug Fixes
1819
---------
1920
* [#1183](https://github.com/java-native-access/jna/pull/1183): `c.s.j.p.win32.WinDef.CHARByReference#getValue` should only read one byte - [@dbwiddis](https://github.com/dbwiddis).
2021
* [#1184](https://github.com/java-native-access/jna/pull/1184): `c.s.j.p.win32.WinDef.ULONGLONG` should always be 8 bytes - [@dbwiddis](https://github.com/dbwiddis).
2122

22-
2323
Release 5.5.0
2424
=============
2525

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna.platform;
25+
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertTrue;
28+
29+
import org.junit.Test;
30+
31+
import com.sun.jna.Pointer;
32+
import com.sun.jna.platform.unix.X11.AtomByReference;
33+
import com.sun.jna.platform.unix.X11.WindowByReference;
34+
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
35+
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTRByReference;
36+
import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_COLOR_TEMPERATURE;
37+
import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_DISPLAY_TECHNOLOGY_TYPE;
38+
import com.sun.jna.platform.win32.LowLevelMonitorConfigurationAPI.MC_VCP_CODE_TYPE;
39+
import com.sun.jna.platform.win32.OaIdl.DISPID;
40+
import com.sun.jna.platform.win32.OaIdl.DISPIDByReference;
41+
import com.sun.jna.platform.win32.OaIdl.MEMBERID;
42+
import com.sun.jna.platform.win32.OaIdl.MEMBERIDByReference;
43+
import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOL;
44+
import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOLByReference;
45+
import com.sun.jna.platform.win32.OaIdl._VARIANT_BOOLByReference;
46+
import com.sun.jna.platform.win32.WTypes.BSTR;
47+
import com.sun.jna.platform.win32.WTypes.BSTRByReference;
48+
import com.sun.jna.platform.win32.WTypes.VARTYPE;
49+
import com.sun.jna.platform.win32.WTypes.VARTYPEByReference;
50+
import com.sun.jna.platform.win32.WinDef.BOOL;
51+
import com.sun.jna.platform.win32.WinDef.BOOLByReference;
52+
import com.sun.jna.platform.win32.WinDef.CHAR;
53+
import com.sun.jna.platform.win32.WinDef.CHARByReference;
54+
import com.sun.jna.platform.win32.WinDef.DWORD;
55+
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
56+
import com.sun.jna.platform.win32.WinDef.LONG;
57+
import com.sun.jna.platform.win32.WinDef.LONGByReference;
58+
import com.sun.jna.platform.win32.WinDef.LONGLONG;
59+
import com.sun.jna.platform.win32.WinDef.LONGLONGByReference;
60+
import com.sun.jna.platform.win32.WinDef.SCODE;
61+
import com.sun.jna.platform.win32.WinDef.SCODEByReference;
62+
import com.sun.jna.platform.win32.WinDef.UINT;
63+
import com.sun.jna.platform.win32.WinDef.UINTByReference;
64+
import com.sun.jna.platform.win32.WinDef.ULONG;
65+
import com.sun.jna.platform.win32.WinDef.ULONGByReference;
66+
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
67+
import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference;
68+
import com.sun.jna.platform.win32.WinDef.USHORT;
69+
import com.sun.jna.platform.win32.WinDef.USHORTByReference;
70+
import com.sun.jna.platform.win32.WinDef.WORD;
71+
import com.sun.jna.platform.win32.WinDef.WORDByReference;
72+
import com.sun.jna.platform.win32.WinNT.ACL;
73+
import com.sun.jna.platform.win32.WinNT.HANDLE;
74+
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
75+
import com.sun.jna.platform.win32.WinNT.PACLByReference;
76+
import com.sun.jna.platform.win32.WinNT.PSID;
77+
import com.sun.jna.platform.win32.WinNT.PSIDByReference;
78+
import com.sun.jna.platform.win32.WinReg.HKEY;
79+
import com.sun.jna.platform.win32.WinReg.HKEYByReference;
80+
81+
public class ByReferencePlatformToStringTest {
82+
@Test
83+
public void testPlatformToStrings() {
84+
BOOLByReference boolbr = new BOOLByReference(new BOOL(true));
85+
parseAndTest(boolbr.toString(), "BOOL", "true");
86+
87+
BSTRByReference bstrbr = new BSTRByReference(new BSTR("bstr"));
88+
parseAndTest(bstrbr.toString(), "BSTR", "bstr");
89+
90+
CHARByReference cbr = new CHARByReference(new CHAR(42));
91+
parseAndTest(cbr.toString(), "CHAR", "42");
92+
93+
DISPIDByReference dispidbr = new DISPIDByReference(new DISPID(42));
94+
parseAndTest(dispidbr.toString(), "DISPID", "42");
95+
96+
DWORDByReference dwbr = new DWORDByReference(new DWORD(42));
97+
parseAndTest(dwbr.toString(), "DWORD", "42");
98+
99+
HANDLEByReference handlebr = new HANDLEByReference(new HANDLE(new Pointer(42)));
100+
parseAndTest(handlebr.toString(), "HANDLE", "native");
101+
102+
HKEYByReference hkeybr = new HKEYByReference(new HKEY(42));
103+
parseAndTest(hkeybr.toString(), "HKEY", "native");
104+
105+
LONGByReference longbr = new LONGByReference(new LONG(42));
106+
parseAndTest(longbr.toString(), "LONG", "42");
107+
108+
LONGLONGByReference longlongbr = new LONGLONGByReference(new LONGLONG(42));
109+
parseAndTest(longlongbr.toString(), "LONGLONG", "42");
110+
111+
MC_COLOR_TEMPERATURE.ByReference mccbr = new MC_COLOR_TEMPERATURE.ByReference(
112+
MC_COLOR_TEMPERATURE.MC_COLOR_TEMPERATURE_UNKNOWN);
113+
parseAndTest(mccbr.toString(), "MC_COLOR_TEMPERATURE", "MC_COLOR_TEMPERATURE_UNKNOWN");
114+
115+
MC_DISPLAY_TECHNOLOGY_TYPE.ByReference mcdbr = new MC_DISPLAY_TECHNOLOGY_TYPE.ByReference(
116+
MC_DISPLAY_TECHNOLOGY_TYPE.MC_SHADOW_MASK_CATHODE_RAY_TUBE);
117+
parseAndTest(mcdbr.toString(), "MC_DISPLAY_TECHNOLOGY_TYPE", "MC_SHADOW_MASK_CATHODE_RAY_TUBE");
118+
119+
MC_VCP_CODE_TYPE.ByReference mcvbr = new MC_VCP_CODE_TYPE.ByReference(MC_VCP_CODE_TYPE.MC_MOMENTARY);
120+
parseAndTest(mcvbr.toString(), "MC_VCP_CODE_TYPE", "MC_MOMENTARY");
121+
122+
MEMBERIDByReference memberidbr = new MEMBERIDByReference(new MEMBERID(42));
123+
parseAndTest(memberidbr.toString(), "MEMBERID", "42");
124+
125+
PACLByReference paclbr = new PACLByReference(new ACL());
126+
parseAndTest(paclbr.toString(), "PACL", "WinNT$ACL(native");
127+
128+
PSIDByReference psidbr = new PSIDByReference(new PSID());
129+
parseAndTest(psidbr.toString(), "PSID", "WinNT$PSID(native");
130+
131+
SCODEByReference scodebr = new SCODEByReference(new SCODE(42));
132+
parseAndTest(scodebr.toString(), "SCODE", "42");
133+
134+
UINTByReference uibr = new UINTByReference(new UINT(42));
135+
parseAndTest(uibr.toString(), "UINT", "42");
136+
137+
ULONG_PTRByReference ulpbr = new ULONG_PTRByReference(new ULONG_PTR(42));
138+
parseAndTest(ulpbr.toString(), "ULONG_PTR", "42");
139+
140+
ULONGByReference ulbr = new ULONGByReference(new ULONG(42));
141+
parseAndTest(ulbr.toString(), "ULONG", "42");
142+
143+
ULONGLONGByReference ullbr = new ULONGLONGByReference(new ULONGLONG(42));
144+
parseAndTest(ullbr.toString(), "ULONGLONG", "42");
145+
146+
USHORTByReference usbr = new USHORTByReference(new USHORT(42));
147+
parseAndTest(usbr.toString(), "USHORT", "42");
148+
149+
VARIANT_BOOLByReference vboolbr = new VARIANT_BOOLByReference(new VARIANT_BOOL(1));
150+
parseAndTest(vboolbr.toString(), "VARIANT_BOOL", "1");
151+
152+
_VARIANT_BOOLByReference vboolbr2 = new _VARIANT_BOOLByReference(new VARIANT_BOOL(1));
153+
parseAndTest(vboolbr2.toString(), "VARIANT_BOOL", "1");
154+
155+
VARTYPEByReference varbr = new VARTYPEByReference(new VARTYPE(42));
156+
parseAndTest(varbr.toString(), "VARTYPE", "42");
157+
158+
WORDByReference wbr = new WORDByReference(new WORD(42));
159+
parseAndTest(wbr.toString(), "WORD", "42");
160+
161+
// No way to set value on these without native code. Both methods read a random
162+
// NativeLong and return null if 0 or a random hex string otherwise
163+
AtomByReference abr = new AtomByReference();
164+
String atomStr = abr.toString();
165+
if (abr.getValue() == null) {
166+
assertTrue(abr.toString().startsWith("null@0x"));
167+
} else {
168+
assertTrue(atomStr.startsWith("Atom@0x"));
169+
assertTrue(atomStr.contains("=0x"));
170+
}
171+
172+
WindowByReference windowbr = new WindowByReference();
173+
String windowStr = windowbr.toString();
174+
if (windowbr.getValue() == null) {
175+
assertTrue(windowStr.startsWith("null@0x"));
176+
} else {
177+
assertTrue(windowStr.startsWith("Window@0x"));
178+
assertTrue(windowStr.contains("=0x"));
179+
}
180+
}
181+
182+
/**
183+
* Parses a string "foo@0x123=bar" testing equality of fixed parts of the string
184+
*
185+
* @param s
186+
* The string to test
187+
* @param beforeAt
188+
* The string which should match the portion before the first
189+
* {@code @}
190+
* @param afterEquals
191+
* The string which should match the portion after the {@code =}
192+
* sign, before any additional {@code @}
193+
*/
194+
private void parseAndTest(String s, String beforeAt, String afterEquals) {
195+
String[] atSplit = s.split("@");
196+
assertEquals("Incorrect type prefix", beforeAt, atSplit[0]);
197+
String[] equalsSplit = atSplit[1].split("=");
198+
assertEquals("Incorrect value string", afterEquals, equalsSplit[1]);
199+
}
200+
}

src/com/sun/jna/ptr/ByReference.java

+39-8
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,53 @@
2323
*/
2424
package com.sun.jna.ptr;
2525

26+
import java.lang.reflect.Method;
27+
2628
import com.sun.jna.Memory;
29+
import com.sun.jna.Pointer;
2730
import com.sun.jna.PointerType;
2831

29-
/** Provides generic "pointer to type" functionality, often used in C
30-
* code to return values to the caller in addition to a function result.
32+
/**
33+
* Provides generic "pointer to type" functionality, often used in C code to
34+
* return values to the caller in addition to a function result.
35+
* <p>
36+
* Derived classes must define <code>setValue(&lt;T&gt;)</code> and
37+
* <code>&lt;T&gt; getValue()</code> methods which write to/read from the
38+
* allocated memory.
39+
* <p>
40+
* This class derives from PointerType instead of Memory in order to restrict
41+
* the API to only <code>getValue/setValue</code>.
3142
* <p>
32-
* Derived classes should define <code>setValue(&lt;T&gt;)</code>
33-
* and <code>&lt;T&gt; getValue()</code> methods which write to/read from
34-
* memory.
35-
* <p>This class derives from PointerType instead of Memory in order to
36-
* restrict the API to only <code>getValue/setValue</code>.
37-
* <p>NOTE: this class would ideally be replaced by a generic.
43+
* NOTE: this class would ideally be replaced by a generic.
3844
*/
3945
public abstract class ByReference extends PointerType {
4046

47+
/**
48+
* Allocates memory at this pointer, to contain the pointed-to value.
49+
*
50+
* @param dataSize
51+
* The number of bytes to allocate. Must match the byte size of
52+
* <code>T</code> in the derived class
53+
* <code>setValue(&lt;T&gt;)</code> and
54+
* <code>&lt;T&gt; getValue()</code> methods.
55+
*/
4156
protected ByReference(int dataSize) {
4257
setPointer(new Memory(dataSize));
4358
}
59+
60+
@Override
61+
public String toString() {
62+
try {
63+
Method getValue = getClass().getMethod("getValue");
64+
Object value = getValue.invoke(this);
65+
if (value == null) {
66+
return String.format("null@0x%x", Pointer.nativeValue(getPointer()));
67+
}
68+
return String.format("%s@0x%x=%s", value.getClass().getSimpleName(), Pointer.nativeValue(getPointer()),
69+
value);
70+
} catch (Exception ex) {
71+
return String.format("ByReference Contract violated - %s#getValue raised exception: %s",
72+
getClass().getName(), ex.getMessage());
73+
}
74+
}
4475
}

src/com/sun/jna/ptr/ByteByReference.java

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
package com.sun.jna.ptr;
2525

26+
import com.sun.jna.Pointer;
27+
2628
public class ByteByReference extends ByReference {
2729

2830
public ByteByReference() {
@@ -42,4 +44,8 @@ public byte getValue() {
4244
return getPointer().getByte(0);
4345
}
4446

47+
@Override
48+
public String toString() {
49+
return String.format("byte@0x%1$x=0x%2$x (%2$d)", Pointer.nativeValue(getPointer()), getValue());
50+
}
4551
}

src/com/sun/jna/ptr/DoubleByReference.java

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
package com.sun.jna.ptr;
2525

26+
import com.sun.jna.Pointer;
27+
2628
public class DoubleByReference extends ByReference {
2729
public DoubleByReference() {
2830
this(0d);
@@ -41,4 +43,8 @@ public double getValue() {
4143
return getPointer().getDouble(0);
4244
}
4345

46+
@Override
47+
public String toString() {
48+
return String.format("double@0x%x=%s", Pointer.nativeValue(getPointer()), getValue());
49+
}
4450
}

src/com/sun/jna/ptr/FloatByReference.java

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
package com.sun.jna.ptr;
2525

26+
import com.sun.jna.Pointer;
27+
2628
public class FloatByReference extends ByReference {
2729
public FloatByReference() {
2830
this(0f);
@@ -41,4 +43,8 @@ public float getValue() {
4143
return getPointer().getFloat(0);
4244
}
4345

46+
@Override
47+
public String toString() {
48+
return String.format("float@0x%x=%s", Pointer.nativeValue(getPointer()), getValue());
49+
}
4450
}

src/com/sun/jna/ptr/IntByReference.java

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
package com.sun.jna.ptr;
2525

26+
import com.sun.jna.Pointer;
27+
2628
public class IntByReference extends ByReference {
2729

2830
public IntByReference() {
@@ -41,4 +43,9 @@ public void setValue(int value) {
4143
public int getValue() {
4244
return getPointer().getInt(0);
4345
}
46+
47+
@Override
48+
public String toString() {
49+
return String.format("int@0x%1$x=0x%2$x (%2$d)", Pointer.nativeValue(getPointer()), getValue());
50+
}
4451
}

src/com/sun/jna/ptr/LongByReference.java

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
package com.sun.jna.ptr;
2525

26+
import com.sun.jna.Pointer;
27+
2628
public class LongByReference extends ByReference {
2729
public LongByReference() {
2830
this(0L);
@@ -40,4 +42,9 @@ public void setValue(long value) {
4042
public long getValue() {
4143
return getPointer().getLong(0);
4244
}
45+
46+
@Override
47+
public String toString() {
48+
return String.format("long@0x%1$x=0x%2$x (%2$d)", Pointer.nativeValue(getPointer()), getValue());
49+
}
4350
}

src/com/sun/jna/ptr/NativeLongByReference.java

+13
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
package com.sun.jna.ptr;
2525

2626
import com.sun.jna.NativeLong;
27+
import com.sun.jna.Pointer;
2728

2829
public class NativeLongByReference extends ByReference {
2930
public NativeLongByReference() {
@@ -42,4 +43,16 @@ public void setValue(NativeLong value) {
4243
public NativeLong getValue() {
4344
return getPointer().getNativeLong(0);
4445
}
46+
47+
@Override
48+
public String toString() {
49+
// Can't mix types with ternary operator
50+
if (NativeLong.SIZE > 4) {
51+
return String.format("NativeLong@0x1$%x=0x%2$x (%2$d)", Pointer.nativeValue(getPointer()),
52+
getValue().longValue());
53+
} else {
54+
return String.format("NativeLong@0x1$%x=0x%2$x (%2$d)", Pointer.nativeValue(getPointer()),
55+
getValue().intValue());
56+
}
57+
}
4558
}

0 commit comments

Comments
 (0)