From 5d377ac05266c3a189073bc1adfdc072576f0fcd Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Sat, 25 Apr 2020 09:32:50 -0700 Subject: [PATCH] Add toString to classes extending ByReference --- CHANGES.md | 1 + .../src/com/sun/jna/platform/unix/X11.java | 10 + .../com/sun/jna/platform/win32/BaseTSD.java | 5 + .../HighLevelMonitorConfigurationAPI.java | 10 + .../LowLevelMonitorConfigurationAPI.java | 5 + .../src/com/sun/jna/platform/win32/OaIdl.java | 71 ++++--- .../com/sun/jna/platform/win32/WTypes.java | 13 +- .../com/sun/jna/platform/win32/WinDef.java | 55 ++++++ .../src/com/sun/jna/platform/win32/WinNT.java | 15 ++ .../com/sun/jna/platform/win32/WinReg.java | 5 + .../ByReferencePlatformToStringTest.java | 174 ++++++++++++++++++ src/com/sun/jna/ptr/ByReference.java | 17 ++ src/com/sun/jna/ptr/ByteByReference.java | 6 + src/com/sun/jna/ptr/DoubleByReference.java | 6 + src/com/sun/jna/ptr/FloatByReference.java | 6 + src/com/sun/jna/ptr/IntByReference.java | 7 + src/com/sun/jna/ptr/LongByReference.java | 7 + .../sun/jna/ptr/NativeLongByReference.java | 12 ++ src/com/sun/jna/ptr/PointerByReference.java | 5 + src/com/sun/jna/ptr/ShortByReference.java | 6 + test/com/sun/jna/ByReferenceToStringTest.java | 102 ++++++++++ 21 files changed, 512 insertions(+), 26 deletions(-) create mode 100644 contrib/platform/test/com/sun/jna/platform/ByReferencePlatformToStringTest.java create mode 100644 test/com/sun/jna/ByReferenceToStringTest.java diff --git a/CHANGES.md b/CHANGES.md index 03e5d33130..59a5f80b7f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Features * [#1168](https://github.com/java-native-access/jna/pull/1168): Add `c.s.j.p.win32.Kernel32#SetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis). * [#1169](https://github.com/java-native-access/jna/issues/1169): Wait for process in getLinuxLdPaths - [@rdesgroppes](https://github.com/rdesgroppes). * [#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). +* [#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). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/unix/X11.java b/contrib/platform/src/com/sun/jna/platform/unix/X11.java index f07f7b5a71..212583e5b9 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/X11.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/X11.java @@ -172,6 +172,11 @@ public Atom getValue() { NativeLong value = getPointer().getNativeLong(0); return (Atom)new Atom().fromNative(value, null); } + + @Override + public String toString() { + return super.toString(getValue()); + } } class Colormap extends XID { private static final long serialVersionUID = 1L; @@ -251,6 +256,11 @@ public Window getValue() { NativeLong value = getPointer().getNativeLong(0); return value.longValue() == X11.None ? Window.None : new Window(value.longValue()); } + + @Override + public String toString() { + return super.toString(getValue()); + } } class Pixmap extends Drawable { private static final long serialVersionUID = 1L; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java b/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java index 011c617074..d754215c2b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/BaseTSD.java @@ -107,6 +107,11 @@ public ULONG_PTR getValue() { ? getPointer().getInt(0) : getPointer().getLong(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java b/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java index e519a42ec8..322afcb974 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/HighLevelMonitorConfigurationAPI.java @@ -274,6 +274,11 @@ public void setValue(MC_DISPLAY_TECHNOLOGY_TYPE value) { public MC_DISPLAY_TECHNOLOGY_TYPE getValue() { return EnumUtils.fromInteger(getPointer().getInt(0), MC_DISPLAY_TECHNOLOGY_TYPE.class); } + + @Override + public String toString() { + return super.toString(getValue()); + } } } @@ -440,6 +445,11 @@ public void setValue(MC_COLOR_TEMPERATURE value) { public MC_COLOR_TEMPERATURE getValue() { return EnumUtils.fromInteger(getPointer().getInt(0), MC_COLOR_TEMPERATURE.class); } + + @Override + public String toString() { + return super.toString(getValue()); + } } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java b/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java index a091340c89..2122aa2a6f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/LowLevelMonitorConfigurationAPI.java @@ -111,6 +111,11 @@ public void setValue(MC_VCP_CODE_TYPE value) { public MC_VCP_CODE_TYPE getValue() { return EnumUtils.fromInteger(getPointer().getInt(0), MC_VCP_CODE_TYPE.class); } + + @Override + public String toString() { + return super.toString(getValue()); + } } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java b/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java index b74cb5c16b..6d8a7898c7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java @@ -22,7 +22,29 @@ */ package com.sun.jna.platform.win32; -import java.util.List; +import static com.sun.jna.platform.win32.Variant.VT_BOOL; +import static com.sun.jna.platform.win32.Variant.VT_BSTR; +import static com.sun.jna.platform.win32.Variant.VT_CY; +import static com.sun.jna.platform.win32.Variant.VT_DATE; +import static com.sun.jna.platform.win32.Variant.VT_DECIMAL; +import static com.sun.jna.platform.win32.Variant.VT_DISPATCH; +import static com.sun.jna.platform.win32.Variant.VT_ERROR; +import static com.sun.jna.platform.win32.Variant.VT_I1; +import static com.sun.jna.platform.win32.Variant.VT_I2; +import static com.sun.jna.platform.win32.Variant.VT_I4; +import static com.sun.jna.platform.win32.Variant.VT_INT; +import static com.sun.jna.platform.win32.Variant.VT_R4; +import static com.sun.jna.platform.win32.Variant.VT_R8; +import static com.sun.jna.platform.win32.Variant.VT_RECORD; +import static com.sun.jna.platform.win32.Variant.VT_UI1; +import static com.sun.jna.platform.win32.Variant.VT_UI2; +import static com.sun.jna.platform.win32.Variant.VT_UI4; +import static com.sun.jna.platform.win32.Variant.VT_UINT; +import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN; +import static com.sun.jna.platform.win32.Variant.VT_VARIANT; + +import java.io.Closeable; +import java.util.Date; import com.sun.jna.IntegerType; import com.sun.jna.Memory; @@ -32,8 +54,6 @@ import com.sun.jna.Structure.FieldOrder; import com.sun.jna.Union; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; -import com.sun.jna.platform.win32.COM.COMUtils; -import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.platform.win32.Variant.VARIANT; import com.sun.jna.platform.win32.Variant.VariantArg; @@ -53,32 +73,12 @@ import com.sun.jna.platform.win32.WinDef.ULONGLONG; import com.sun.jna.platform.win32.WinDef.USHORT; import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.TypeComp; import com.sun.jna.platform.win32.COM.Unknown; -import static com.sun.jna.platform.win32.Variant.VT_BOOL; -import static com.sun.jna.platform.win32.Variant.VT_BSTR; -import static com.sun.jna.platform.win32.Variant.VT_CY; -import static com.sun.jna.platform.win32.Variant.VT_DATE; -import static com.sun.jna.platform.win32.Variant.VT_DECIMAL; -import static com.sun.jna.platform.win32.Variant.VT_DISPATCH; -import static com.sun.jna.platform.win32.Variant.VT_ERROR; -import static com.sun.jna.platform.win32.Variant.VT_I1; -import static com.sun.jna.platform.win32.Variant.VT_I2; -import static com.sun.jna.platform.win32.Variant.VT_I4; -import static com.sun.jna.platform.win32.Variant.VT_INT; -import static com.sun.jna.platform.win32.Variant.VT_R4; -import static com.sun.jna.platform.win32.Variant.VT_R8; -import static com.sun.jna.platform.win32.Variant.VT_RECORD; -import static com.sun.jna.platform.win32.Variant.VT_UI1; -import static com.sun.jna.platform.win32.Variant.VT_UI2; -import static com.sun.jna.platform.win32.Variant.VT_UI4; -import static com.sun.jna.platform.win32.Variant.VT_UINT; -import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN; -import static com.sun.jna.platform.win32.Variant.VT_VARIANT; import com.sun.jna.ptr.ByReference; import com.sun.jna.ptr.PointerByReference; -import java.io.Closeable; -import java.util.Date; /** * The Interface OaIdl. @@ -200,6 +200,11 @@ public void setValue(VARIANT_BOOL value) { public VARIANT_BOOL getValue() { return new VARIANT_BOOL(getPointer().getShort(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } public static class _VARIANT_BOOLByReference extends ByReference { @@ -219,6 +224,11 @@ public void setValue(VARIANT_BOOL value) { public VARIANT_BOOL getValue() { return new VARIANT_BOOL(getPointer().getShort(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } @FieldOrder({"date"}) @@ -311,6 +321,11 @@ public void setValue(DISPID value) { public DISPID getValue() { return new DISPID(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } public static class MEMBERID extends DISPID { @@ -342,6 +357,11 @@ public void setValue(MEMBERID value) { public MEMBERID getValue() { return new MEMBERID(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } // The Collect property. You use this property if the method you are calling @@ -895,6 +915,7 @@ public void destroy() { /** * Implemented to satisfy Closeable interface, delegates to destroy. */ + @Override public void close() { destroy(); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java b/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java index 72b4ba84c9..137256d1db 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WTypes.java @@ -24,6 +24,8 @@ */ package com.sun.jna.platform.win32; +import java.io.UnsupportedEncodingException; + import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; @@ -31,7 +33,6 @@ import com.sun.jna.Structure; import com.sun.jna.platform.win32.WinDef.USHORT; import com.sun.jna.ptr.ByReference; -import java.io.UnsupportedEncodingException; /** * Constant defined in WTypes.h @@ -170,6 +171,11 @@ public BSTR getValue() { public String getString() { return this.getValue().getValue(); } + + @Override + public String toString() { + return super.toString(getValue()); + } } public static class LPSTR extends PointerType { @@ -317,5 +323,10 @@ public void setValue(VARTYPE value) { public VARTYPE getValue() { return new VARTYPE(getPointer().getShort(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java index 5cf8e179e5..8f5075d9fe 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinDef.java @@ -117,6 +117,11 @@ public void setValue(WORD value) { public WORD getValue() { return new WORD(getPointer().getShort(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -207,6 +212,11 @@ public void setValue(DWORD value) { public DWORD getValue() { return new DWORD(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -278,6 +288,11 @@ public void setValue(LONG value) { public LONG getValue() { return new LONG(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -349,6 +364,11 @@ public void setValue(LONGLONG value) { public LONGLONG getValue() { return new LONGLONG(getPointer().getLong(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -906,6 +926,11 @@ public void setValue(ULONG value) { public ULONG getValue() { return new ULONG(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -977,6 +1002,11 @@ public void setValue(ULONGLONG value) { public ULONGLONG getValue() { return new ULONGLONG(getPointer().getLong(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -1254,6 +1284,11 @@ public void setValue(USHORT value) { public USHORT getValue() { return new USHORT(getPointer().getShort(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -1357,6 +1392,11 @@ public void setValue(UINT value) { public UINT getValue() { return new UINT(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -1421,6 +1461,11 @@ public void setValue(SCODE value) { public SCODE getValue() { return new SCODE(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -1592,6 +1637,11 @@ public void setValue(BOOL value) { public BOOL getValue() { return new BOOL(getPointer().getInt(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -1728,6 +1778,11 @@ public void setValue(CHAR value) { public CHAR getValue() { return new CHAR(getPointer().getChar(0)); } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 25b611a182..8755be1f47 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -398,6 +398,11 @@ public PSID getValue() { return new PSID(p); } } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -1362,6 +1367,11 @@ public HANDLE getValue() { h.setPointer(p); return h; } + + @Override + public String toString() { + return super.toString(getValue()); + } } /** @@ -2562,6 +2572,11 @@ public ACL getValue() { return new ACL(p); } } + + @Override + public String toString() { + return super.toString(getValue()); + } } @FieldOrder({"Revision", "Sbz1", "Control", "Owner", "Group", "Sacl", "Dacl"}) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java b/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java index 5dc2da513b..bb8758ebdd 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinReg.java @@ -67,6 +67,11 @@ public HKEY getValue() { h.setPointer(p); return h; } + + @Override + public String toString() { + return super.toString(getValue()); + } } HKEY HKEY_CLASSES_ROOT = new HKEY(0x80000000); diff --git a/contrib/platform/test/com/sun/jna/platform/ByReferencePlatformToStringTest.java b/contrib/platform/test/com/sun/jna/platform/ByReferencePlatformToStringTest.java new file mode 100644 index 0000000000..bcfad409c9 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/ByReferencePlatformToStringTest.java @@ -0,0 +1,174 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform; + +import org.junit.Test; + +import com.sun.jna.ByReferenceToStringTest; +import com.sun.jna.Memory; +import com.sun.jna.platform.unix.X11.AtomByReference; +import com.sun.jna.platform.unix.X11.WindowByReference; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTRByReference; +import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_COLOR_TEMPERATURE; +import com.sun.jna.platform.win32.HighLevelMonitorConfigurationAPI.MC_DISPLAY_TECHNOLOGY_TYPE; +import com.sun.jna.platform.win32.LowLevelMonitorConfigurationAPI.MC_VCP_CODE_TYPE; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.MEMBERID; +import com.sun.jna.platform.win32.OaIdl.MEMBERIDByReference; +import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOL; +import com.sun.jna.platform.win32.OaIdl.VARIANT_BOOLByReference; +import com.sun.jna.platform.win32.OaIdl._VARIANT_BOOLByReference; +import com.sun.jna.platform.win32.WTypes.BSTR; +import com.sun.jna.platform.win32.WTypes.BSTRByReference; +import com.sun.jna.platform.win32.WTypes.VARTYPE; +import com.sun.jna.platform.win32.WTypes.VARTYPEByReference; +import com.sun.jna.platform.win32.WinDef.BOOL; +import com.sun.jna.platform.win32.WinDef.BOOLByReference; +import com.sun.jna.platform.win32.WinDef.CHAR; +import com.sun.jna.platform.win32.WinDef.CHARByReference; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinDef.LONG; +import com.sun.jna.platform.win32.WinDef.LONGByReference; +import com.sun.jna.platform.win32.WinDef.LONGLONG; +import com.sun.jna.platform.win32.WinDef.LONGLONGByReference; +import com.sun.jna.platform.win32.WinDef.SCODE; +import com.sun.jna.platform.win32.WinDef.SCODEByReference; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinDef.UINTByReference; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinDef.ULONGLONG; +import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference; +import com.sun.jna.platform.win32.WinDef.USHORT; +import com.sun.jna.platform.win32.WinDef.USHORTByReference; +import com.sun.jna.platform.win32.WinDef.WORD; +import com.sun.jna.platform.win32.WinDef.WORDByReference; +import com.sun.jna.platform.win32.WinNT.ACL; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.platform.win32.WinNT.HANDLEByReference; +import com.sun.jna.platform.win32.WinNT.PACLByReference; +import com.sun.jna.platform.win32.WinNT.PSID; +import com.sun.jna.platform.win32.WinNT.PSIDByReference; +import com.sun.jna.platform.win32.WinReg.HKEY; +import com.sun.jna.platform.win32.WinReg.HKEYByReference; + +public class ByReferencePlatformToStringTest extends ByReferenceToStringTest { + @Test + public void testPlatformToStrings() { + BOOLByReference boolbr = new BOOLByReference(new BOOL(true)); + parseAndTest(boolbr.toString(), "BOOL", "true"); + + BSTRByReference bstrbr = new BSTRByReference(new BSTR("bstr")); + parseAndTest(bstrbr.toString(), "BSTR", "bstr"); + + CHARByReference cbr = new CHARByReference(new CHAR(42)); + parseAndTest(cbr.toString(), "CHAR", "42"); + + DISPIDByReference dispidbr = new DISPIDByReference(new DISPID(42)); + parseAndTest(dispidbr.toString(), "DISPID", "42"); + + DWORDByReference dwbr = new DWORDByReference(new DWORD(42)); + parseAndTest(dwbr.toString(), "DWORD", "42"); + + HANDLEByReference handlebr = new HANDLEByReference(new HANDLE(new Memory(1))); + parseAndTest(handlebr.toString(), "HANDLE", "allocated"); + + HKEYByReference hkeybr = new HKEYByReference(new HKEY(0)); + parseAndTest(hkeybr.toString(), "HKEY", "native"); + + LONGByReference longbr = new LONGByReference(new LONG(42)); + parseAndTest(longbr.toString(), "LONG", "42"); + + LONGLONGByReference longlongbr = new LONGLONGByReference(new LONGLONG(42)); + parseAndTest(longlongbr.toString(), "LONGLONG", "42"); + + MC_COLOR_TEMPERATURE.ByReference mccbr = new MC_COLOR_TEMPERATURE.ByReference( + MC_COLOR_TEMPERATURE.MC_COLOR_TEMPERATURE_UNKNOWN); + parseAndTest(mccbr.toString(), "MC_COLOR_TEMPERATURE", "MC_COLOR_TEMPERATURE_UNKNOWN"); + + MC_DISPLAY_TECHNOLOGY_TYPE.ByReference mcdbr = new MC_DISPLAY_TECHNOLOGY_TYPE.ByReference( + MC_DISPLAY_TECHNOLOGY_TYPE.MC_SHADOW_MASK_CATHODE_RAY_TUBE); + parseAndTest(mcdbr.toString(), "MC_DISPLAY_TECHNOLOGY_TYPE", "MC_SHADOW_MASK_CATHODE_RAY_TUBE"); + + MC_VCP_CODE_TYPE.ByReference mcvbr = new MC_VCP_CODE_TYPE.ByReference(MC_VCP_CODE_TYPE.MC_MOMENTARY); + parseAndTest(mcvbr.toString(), "MC_VCP_CODE_TYPE", "MC_MOMENTARY"); + + MEMBERIDByReference memberidbr = new MEMBERIDByReference(new MEMBERID(42)); + parseAndTest(memberidbr.toString(), "MEMBERID", "42"); + + PACLByReference paclbr = new PACLByReference(new ACL()); + parseAndTest(paclbr.toString(), "PACL", "WinNT$ACL(native"); + + PSIDByReference psidbr = new PSIDByReference(new PSID()); + parseAndTest(psidbr.toString(), "PSID", "WinNT$PSID(native"); + + SCODEByReference scodebr = new SCODEByReference(new SCODE(42)); + parseAndTest(scodebr.toString(), "SCODE", "42"); + + UINTByReference uibr = new UINTByReference(new UINT(42)); + parseAndTest(uibr.toString(), "UINT", "42"); + + ULONG_PTRByReference ulpbr = new ULONG_PTRByReference(new ULONG_PTR(42)); + parseAndTest(ulpbr.toString(), "ULONG_PTR", "42"); + + ULONGByReference ulbr = new ULONGByReference(new ULONG(42)); + parseAndTest(ulbr.toString(), "ULONG", "42"); + + ULONGLONGByReference ullbr = new ULONGLONGByReference(new ULONGLONG(42)); + parseAndTest(ullbr.toString(), "ULONGLONG", "42"); + + USHORTByReference usbr = new USHORTByReference(new USHORT(42)); + parseAndTest(usbr.toString(), "USHORT", "42"); + + VARIANT_BOOLByReference vboolbr = new VARIANT_BOOLByReference(new VARIANT_BOOL(1)); + parseAndTest(vboolbr.toString(), "VARIANT_BOOL", "1"); + + _VARIANT_BOOLByReference vboolbr2 = new _VARIANT_BOOLByReference(new VARIANT_BOOL(1)); + parseAndTest(vboolbr2.toString(), "VARIANT_BOOL", "1"); + + VARTYPEByReference varbr = new VARTYPEByReference(new VARTYPE(42)); + parseAndTest(varbr.toString(), "VARTYPE", "0"); + + WORDByReference wbr = new WORDByReference(new WORD(42)); + parseAndTest(wbr.toString(), "WORD", "42"); + + // No way to set value on these without native code + AtomByReference abr = new AtomByReference(); + // always null + assertTrue(abr.toString().startsWith("null@0x")); + + WindowByReference windowbr = new WindowByReference(); + // either null or a random NativeLong hex string + String windowStr = windowbr.toString(); + if (windowbr.getValue() == null) { + assertTrue(windowStr.startsWith("null@0x")); + } else { + assertTrue(windowStr.startsWith("Window@0x")); + assertTrue(windowStr.contains("=0x")); + } + } +} diff --git a/src/com/sun/jna/ptr/ByReference.java b/src/com/sun/jna/ptr/ByReference.java index 178eb25587..c9a711a5cf 100644 --- a/src/com/sun/jna/ptr/ByReference.java +++ b/src/com/sun/jna/ptr/ByReference.java @@ -24,6 +24,7 @@ package com.sun.jna.ptr; import com.sun.jna.Memory; +import com.sun.jna.Pointer; import com.sun.jna.PointerType; /** Provides generic "pointer to type" functionality, often used in C @@ -41,4 +42,20 @@ public abstract class ByReference extends PointerType { protected ByReference(int dataSize) { setPointer(new Memory(dataSize)); } + + /** + * Express this reference and the value it points to. + * + * @param value + * The value to display. Callers should pass the result of + * {@code getValue()}. + * @return A formatted string containing the object type, reference address, and + * value + */ + protected String toString(Object value) { + if (value == null) { + return String.format("null@0x%x", Pointer.nativeValue(getPointer())); + } + return String.format("%s@0x%x=%s", value.getClass().getSimpleName(), Pointer.nativeValue(getPointer()), value); + } } diff --git a/src/com/sun/jna/ptr/ByteByReference.java b/src/com/sun/jna/ptr/ByteByReference.java index 1da1abe418..45fb085cec 100644 --- a/src/com/sun/jna/ptr/ByteByReference.java +++ b/src/com/sun/jna/ptr/ByteByReference.java @@ -23,6 +23,8 @@ */ package com.sun.jna.ptr; +import com.sun.jna.Pointer; + public class ByteByReference extends ByReference { public ByteByReference() { @@ -42,4 +44,8 @@ public byte getValue() { return getPointer().getByte(0); } + @Override + public String toString() { + return String.format("byte@0x%x=0x%x (%d)", Pointer.nativeValue(getPointer()), getValue(), getValue()); + } } diff --git a/src/com/sun/jna/ptr/DoubleByReference.java b/src/com/sun/jna/ptr/DoubleByReference.java index 09e8ba621d..9f6d705e2d 100644 --- a/src/com/sun/jna/ptr/DoubleByReference.java +++ b/src/com/sun/jna/ptr/DoubleByReference.java @@ -23,6 +23,8 @@ */ package com.sun.jna.ptr; +import com.sun.jna.Pointer; + public class DoubleByReference extends ByReference { public DoubleByReference() { this(0d); @@ -41,4 +43,8 @@ public double getValue() { return getPointer().getDouble(0); } + @Override + public String toString() { + return String.format("double@0x%x=%s", Pointer.nativeValue(getPointer()), Double.toString(getValue())); + } } diff --git a/src/com/sun/jna/ptr/FloatByReference.java b/src/com/sun/jna/ptr/FloatByReference.java index e16f66190c..2361ebf326 100644 --- a/src/com/sun/jna/ptr/FloatByReference.java +++ b/src/com/sun/jna/ptr/FloatByReference.java @@ -23,6 +23,8 @@ */ package com.sun.jna.ptr; +import com.sun.jna.Pointer; + public class FloatByReference extends ByReference { public FloatByReference() { this(0f); @@ -41,4 +43,8 @@ public float getValue() { return getPointer().getFloat(0); } + @Override + public String toString() { + return String.format("float@0x%x=%s", Pointer.nativeValue(getPointer()), Float.toString(getValue())); + } } diff --git a/src/com/sun/jna/ptr/IntByReference.java b/src/com/sun/jna/ptr/IntByReference.java index 570368d2cf..3fb4cd1463 100644 --- a/src/com/sun/jna/ptr/IntByReference.java +++ b/src/com/sun/jna/ptr/IntByReference.java @@ -23,6 +23,8 @@ */ package com.sun.jna.ptr; +import com.sun.jna.Pointer; + public class IntByReference extends ByReference { public IntByReference() { @@ -41,4 +43,9 @@ public void setValue(int value) { public int getValue() { return getPointer().getInt(0); } + + @Override + public String toString() { + return String.format("int@0x%x=0x%x (%d)", Pointer.nativeValue(getPointer()), getValue(), getValue()); + } } diff --git a/src/com/sun/jna/ptr/LongByReference.java b/src/com/sun/jna/ptr/LongByReference.java index f1bce0fcca..617441a916 100644 --- a/src/com/sun/jna/ptr/LongByReference.java +++ b/src/com/sun/jna/ptr/LongByReference.java @@ -23,6 +23,8 @@ */ package com.sun.jna.ptr; +import com.sun.jna.Pointer; + public class LongByReference extends ByReference { public LongByReference() { this(0L); @@ -40,4 +42,9 @@ public void setValue(long value) { public long getValue() { return getPointer().getLong(0); } + + @Override + public String toString() { + return String.format("long@0x%x=0x%x (%d)", Pointer.nativeValue(getPointer()), getValue(), getValue()); + } } diff --git a/src/com/sun/jna/ptr/NativeLongByReference.java b/src/com/sun/jna/ptr/NativeLongByReference.java index 27f6d47ad8..bf673eb04e 100644 --- a/src/com/sun/jna/ptr/NativeLongByReference.java +++ b/src/com/sun/jna/ptr/NativeLongByReference.java @@ -24,6 +24,7 @@ package com.sun.jna.ptr; import com.sun.jna.NativeLong; +import com.sun.jna.Pointer; public class NativeLongByReference extends ByReference { public NativeLongByReference() { @@ -42,4 +43,15 @@ public void setValue(NativeLong value) { public NativeLong getValue() { return getPointer().getNativeLong(0); } + + @Override + public String toString() { + if (NativeLong.SIZE > 4) { + return String.format("NativeLong@0x%x=0x%x (%d)", Pointer.nativeValue(getPointer()), getValue().longValue(), + getValue().longValue()); + } else { + return String.format("NativeLong@0x%x=0x%x (%d)", Pointer.nativeValue(getPointer()), getValue().intValue(), + getValue().intValue()); + } + } } diff --git a/src/com/sun/jna/ptr/PointerByReference.java b/src/com/sun/jna/ptr/PointerByReference.java index 645c2595e1..22a9565fab 100644 --- a/src/com/sun/jna/ptr/PointerByReference.java +++ b/src/com/sun/jna/ptr/PointerByReference.java @@ -48,4 +48,9 @@ public void setValue(Pointer value) { public Pointer getValue() { return getPointer().getPointer(0); } + + @Override + public String toString() { + return super.toString(getValue()); + } } diff --git a/src/com/sun/jna/ptr/ShortByReference.java b/src/com/sun/jna/ptr/ShortByReference.java index 52a9562cde..08780c0d14 100644 --- a/src/com/sun/jna/ptr/ShortByReference.java +++ b/src/com/sun/jna/ptr/ShortByReference.java @@ -23,6 +23,8 @@ */ package com.sun.jna.ptr; +import com.sun.jna.Pointer; + public class ShortByReference extends ByReference { public ShortByReference() { @@ -42,4 +44,8 @@ public short getValue() { return getPointer().getShort(0); } + @Override + public String toString() { + return String.format("short@0x%x=0x%x (%d)", Pointer.nativeValue(getPointer()), getValue(), getValue()); + } } diff --git a/test/com/sun/jna/ByReferenceToStringTest.java b/test/com/sun/jna/ByReferenceToStringTest.java new file mode 100644 index 0000000000..306259012c --- /dev/null +++ b/test/com/sun/jna/ByReferenceToStringTest.java @@ -0,0 +1,102 @@ +/* Copyright (c) 2020 Daniel Widdis, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna; + +import com.sun.jna.ptr.ByteByReference; +import com.sun.jna.ptr.DoubleByReference; +import com.sun.jna.ptr.FloatByReference; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.LongByReference; +import com.sun.jna.ptr.NativeLongByReference; +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.ptr.ShortByReference; + +import junit.framework.TestCase; + +public class ByReferenceToStringTest extends TestCase { + + public void testToStrings() { + LongByReference lbr = new LongByReference(42L); + parseAndTest(lbr.toString(), "long", "0x2a (42)"); + lbr = new LongByReference(-42L); + parseAndTest(lbr.toString(), "long", "0xffffffffffffffd6 (-42)"); + + IntByReference ibr = new IntByReference(42); + parseAndTest(ibr.toString(), "int", "0x2a (42)"); + ibr = new IntByReference(-42); + parseAndTest(ibr.toString(), "int", "0xffffffd6 (-42)"); + + ShortByReference sbr = new ShortByReference((short) 42); + parseAndTest(sbr.toString(), "short", "0x2a (42)"); + sbr = new ShortByReference((short) -42); + parseAndTest(sbr.toString(), "short", "0xffd6 (-42)"); + + ByteByReference bbr = new ByteByReference((byte) 42); + parseAndTest(bbr.toString(), "byte", "0x2a (42)"); + bbr = new ByteByReference((byte) -42); + parseAndTest(bbr.toString(), "byte", "0xd6 (-42)"); + + FloatByReference fbr = new FloatByReference(42f); + parseAndTest(fbr.toString(), "float", "42.0"); + fbr = new FloatByReference(-42f); + parseAndTest(fbr.toString(), "float", "-42.0"); + + DoubleByReference dbr = new DoubleByReference(42d); + parseAndTest(dbr.toString(), "double", "42.0"); + dbr = new DoubleByReference(-42d); + parseAndTest(dbr.toString(), "double", "-42.0"); + + NativeLongByReference nlbr = new NativeLongByReference(new NativeLong(42L)); + parseAndTest(nlbr.toString(), "NativeLong", "0x2a (42)"); + nlbr = new NativeLongByReference(new NativeLong(-42L)); + parseAndTest(nlbr.toString(), "NativeLong", + NativeLong.SIZE > 4 ? "0xffffffffffffffd6 (-42)" : "0xffffffd6 (-42)"); + + PointerByReference pbr = new PointerByReference(Pointer.NULL); + assertTrue(pbr.toString().startsWith("null@0x")); + pbr = new PointerByReference(new Memory(1)); + parseAndTest(pbr.toString(), "Memory", "allocated"); + pbr = new PointerByReference(new Pointer(42)); + parseAndTest(pbr.toString(), "Pointer", "native"); + } + + /** + * Parses a string "foo@0x123=bar" testing equality of fixed parts of the string + * + * @param s + * The string to test + * @param beforeAt + * The string which should match the portion before the first + * {@code @} + * @param afterEquals + * The string which should match the portion after the {@code =} + * sign, before any additional {@code @} + */ + protected void parseAndTest(String s, String beforeAt, String afterEquals) { + String[] atSplit = s.split("@"); + assertEquals("Incorrect type prefix", beforeAt, atSplit[0]); + String[] equalsSplit = atSplit[1].split("="); + assertEquals("Incorrect value string", afterEquals, equalsSplit[1]); + } +}