Change the prototypes of the JNA library interface in order to take advantage of the CString class. This removes a fair amount of code in the org.libvirt.Library class and puts the decoding of C string data into a single place. --- src/main/java/org/libvirt/Connect.java | 20 +++++++------- src/main/java/org/libvirt/Device.java | 7 +++-- src/main/java/org/libvirt/Domain.java | 6 ++-- src/main/java/org/libvirt/Library.java | 44 ++++++++---------------------- src/main/java/org/libvirt/StoragePool.java | 7 +++-- src/main/java/org/libvirt/jna/Libvirt.java | 26 +++++++++--------- 6 files changed, 46 insertions(+), 64 deletions(-) diff --git a/src/main/java/org/libvirt/Connect.java b/src/main/java/org/libvirt/Connect.java index 437f423..1d37c22 100644 --- a/src/main/java/org/libvirt/Connect.java +++ b/src/main/java/org/libvirt/Connect.java @@ -1183,7 +1183,7 @@ public class Connect { public String[] listDefinedDomains() throws LibvirtException { int maxnames = numOfDefinedDomains(); if (maxnames > 0) { - final Pointer[] names = new Pointer[maxnames]; + final CString[] names = new CString[maxnames]; final int n = processError(libvirt.virConnectListDefinedDomains(VCP, names, maxnames)); return Library.toStringArray(names, n); } else { @@ -1201,7 +1201,7 @@ public class Connect { public String[] listDefinedInterfaces() throws LibvirtException { final int max = numOfDefinedInterfaces(); if (max > 0) { - final Pointer[] ifs = new Pointer[max]; + final CString[] ifs = new CString[max]; final int n = processError(libvirt.virConnectListDefinedInterfaces(VCP, ifs, max)); return Library.toStringArray(ifs, n); } else { @@ -1219,7 +1219,7 @@ public class Connect { public String[] listDefinedNetworks() throws LibvirtException { int maxnames = numOfDefinedNetworks(); if (maxnames > 0) { - final Pointer[] names = new Pointer[maxnames]; + final CString[] names = new CString[maxnames]; final int n = processError(libvirt.virConnectListDefinedNetworks(VCP, names, maxnames)); return Library.toStringArray(names, n); } else { @@ -1237,7 +1237,7 @@ public class Connect { public String[] listDefinedStoragePools() throws LibvirtException { int num = numOfDefinedStoragePools(); if (num > 0) { - Pointer[] pools = new Pointer[num]; + CString[] pools = new CString[num]; final int n = processError(libvirt.virConnectListDefinedStoragePools(VCP, pools, num)); return Library.toStringArray(pools, n); } else { @@ -1254,7 +1254,7 @@ public class Connect { public String[] listDevices(String capabilityName) throws LibvirtException { int maxDevices = numOfDevices(capabilityName); if (maxDevices > 0) { - Pointer[] names = new Pointer[maxDevices]; + CString[] names = new CString[maxDevices]; final int n = processError(libvirt.virNodeListDevices(VCP, capabilityName, names, maxDevices, 0)); return Library.toStringArray(names, n); } else { @@ -1288,7 +1288,7 @@ public class Connect { public String[] listInterfaces() throws LibvirtException { int num = numOfInterfaces(); if (num > 0) { - Pointer[] ifs = new Pointer[num]; + CString[] ifs = new CString[num]; final int n = processError(libvirt.virConnectListInterfaces(VCP, ifs, num)); return Library.toStringArray(ifs, n); } else { @@ -1305,7 +1305,7 @@ public class Connect { public String[] listNetworkFilters() throws LibvirtException { int maxnames = numOfNetworkFilters(); if (maxnames > 0) { - Pointer[] names = new Pointer[maxnames]; + CString[] names = new CString[maxnames]; final int n = processError(libvirt.virConnectListNWFilters(VCP, names, maxnames)); return Library.toStringArray(names, n); } else { @@ -1323,7 +1323,7 @@ public class Connect { public String[] listNetworks() throws LibvirtException { int maxnames = numOfNetworks(); if (maxnames > 0) { - Pointer[] names = new Pointer[maxnames]; + CString[] names = new CString[maxnames]; final int n = processError(libvirt.virConnectListNetworks(VCP, names, maxnames)); return Library.toStringArray(names, n); } else { @@ -1340,7 +1340,7 @@ public class Connect { public String[] listSecrets() throws LibvirtException { int num = numOfSecrets(); if (num > 0) { - Pointer[] returnValue = new Pointer[num]; + CString[] returnValue = new CString[num]; final int n = processError(libvirt.virConnectListSecrets(VCP, returnValue, num)); return Library.toStringArray(returnValue, n); } else { @@ -1358,7 +1358,7 @@ public class Connect { public String[] listStoragePools() throws LibvirtException { int num = numOfStoragePools(); if (num > 0) { - Pointer[] returnValue = new Pointer[num]; + CString[] returnValue = new CString[num]; final int n = processError(libvirt.virConnectListStoragePools(VCP, returnValue, num)); return Library.toStringArray(returnValue, n); } else { diff --git a/src/main/java/org/libvirt/Device.java b/src/main/java/org/libvirt/Device.java index 04f373e..6becbca 100644 --- a/src/main/java/org/libvirt/Device.java +++ b/src/main/java/org/libvirt/Device.java @@ -1,5 +1,6 @@ package org.libvirt; +import org.libvirt.jna.CString; import org.libvirt.jna.DevicePointer; import static org.libvirt.Library.libvirt; import static org.libvirt.ErrorHandler.processError; @@ -130,10 +131,10 @@ public class Device { int maxCaps = getNumberOfCapabilities(); if (maxCaps > 0) { - Pointer[] ptrs = new Pointer[maxCaps]; - int got = processError(libvirt.virNodeDeviceListCaps(VDP, ptrs, maxCaps)); + CString[] strings = new CString[maxCaps]; + int got = processError(libvirt.virNodeDeviceListCaps(VDP, strings, maxCaps)); - return Library.toStringArray(ptrs, got); + return Library.toStringArray(strings, got); } else { return Library.NO_STRINGS; } diff --git a/src/main/java/org/libvirt/Domain.java b/src/main/java/org/libvirt/Domain.java index 087a06f..ed6690c 100644 --- a/src/main/java/org/libvirt/Domain.java +++ b/src/main/java/org/libvirt/Domain.java @@ -1437,10 +1437,10 @@ public class Domain { public String[] snapshotListNames(int flags) throws LibvirtException { int num = snapshotNum(); if (num > 0) { - Pointer[] ptrs = new Pointer[num]; - int got = processError(libvirt.virDomainSnapshotListNames(VDP, ptrs, num, flags)); + CString[] names = new CString[num]; + int got = processError(libvirt.virDomainSnapshotListNames(VDP, names, num, flags)); - return Library.toStringArray(ptrs, got); + return Library.toStringArray(names, got); } else { return Library.NO_STRINGS; } diff --git a/src/main/java/org/libvirt/Library.java b/src/main/java/org/libvirt/Library.java index ac89de4..7ce986d 100644 --- a/src/main/java/org/libvirt/Library.java +++ b/src/main/java/org/libvirt/Library.java @@ -2,6 +2,7 @@ package org.libvirt; import org.libvirt.jna.Libvirt; import org.libvirt.jna.Libvirt.VirEventTimeoutCallback; +import org.libvirt.jna.CString; import static org.libvirt.ErrorHandler.processError; import com.sun.jna.Native; @@ -71,46 +72,25 @@ public final class Library { } /** - * Convert the data pointed to by {@code ptr} to a String. - */ - static String getString(Pointer ptr) { - final long len = ptr.indexOf(0, (byte)0); - assert (len != -1): "C-Strings must be \\0 terminated."; - - final byte[] data = ptr.getByteArray(0, (int)len); - try { - return new String(data, "utf-8"); - } catch (java.io.UnsupportedEncodingException e) { - throw new RuntimeException("Libvirt problem: UTF-8 decoding error.", e); - } - } - - /** - * Calls {@link #toStringArray(Pointer[], int)}. - */ - static String[] toStringArray(Pointer[] ptrArr) { - return toStringArray(ptrArr, ptrArr.length); - } - - /** - * Convert the given array of native pointers to "char" in - * UTF-8 encoding to an array of Strings. + * Convert the given array of UTF-8 encoded C-Strings to an array + * of Strings. * * \note The memory used by the elements of the original array - * is freed and ptrArr is modified. + * is freed. */ - static String[] toStringArray(Pointer[] ptrArr, final int size) { + static String[] toStringArray(CString[] cstrarr, final int size) { + int i = 0; try { final String[] result = new String[size]; - for (int i = 0; i < size; ++i) { - result[i] = Library.getString(ptrArr[i]); + for (; i < size; ++i) { + result[i] = cstrarr[i].toString(); } return result; - } finally { - for (int i = 0; i < size; ++i) { - Library.free(ptrArr[i]); - ptrArr[i] = null; + } catch (Exception e) { + for (; i < size; ++i) { + if (cstrarr[i] != null) cstrarr[i].free(); } + throw e; } } diff --git a/src/main/java/org/libvirt/StoragePool.java b/src/main/java/org/libvirt/StoragePool.java index 8caf9f5..04870bf 100644 --- a/src/main/java/org/libvirt/StoragePool.java +++ b/src/main/java/org/libvirt/StoragePool.java @@ -1,5 +1,6 @@ package org.libvirt; +import org.libvirt.jna.CString; import org.libvirt.jna.Libvirt; import org.libvirt.jna.StoragePoolPointer; import org.libvirt.jna.StorageVolPointer; @@ -247,11 +248,11 @@ public class StoragePool { public String[] listVolumes() throws LibvirtException { int num = numOfVolumes(); if (num > 0) { - Pointer[] ptrs = new Pointer[num]; + CString[] names = new CString[num]; - int got = processError(libvirt.virStoragePoolListVolumes(VSPP, ptrs, num)); + int got = processError(libvirt.virStoragePoolListVolumes(VSPP, names, num)); - return Library.toStringArray(ptrs, got); + return Library.toStringArray(names, got); } else { return Library.NO_STRINGS; } diff --git a/src/main/java/org/libvirt/jna/Libvirt.java b/src/main/java/org/libvirt/jna/Libvirt.java index c6b7153..3589525 100644 --- a/src/main/java/org/libvirt/jna/Libvirt.java +++ b/src/main/java/org/libvirt/jna/Libvirt.java @@ -184,16 +184,16 @@ public interface Libvirt extends Library { String virConnectGetType(ConnectionPointer virConnectPtr); CString virConnectGetURI(ConnectionPointer virConnectPtr); int virConnectGetVersion(ConnectionPointer virConnectPtr, LongByReference hvVer); - int virConnectListDefinedDomains(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); - int virConnectListDefinedNetworks(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); - int virConnectListDefinedStoragePools(ConnectionPointer virConnectPtr, Pointer[] names, int maxnames); - int virConnectListDefinedInterfaces(ConnectionPointer virConnectPtr, Pointer[] name, int maxNames); + int virConnectListDefinedDomains(ConnectionPointer virConnectPtr, CString[] name, int maxnames); + int virConnectListDefinedNetworks(ConnectionPointer virConnectPtr, CString[] name, int maxnames); + int virConnectListDefinedStoragePools(ConnectionPointer virConnectPtr, CString[] names, int maxnames); + int virConnectListDefinedInterfaces(ConnectionPointer virConnectPtr, CString[] name, int maxNames); int virConnectListDomains(ConnectionPointer virConnectPtr, int[] ids, int maxnames); - int virConnectListInterfaces(ConnectionPointer virConnectPtr, Pointer[] name, int maxNames); - int virConnectListNetworks(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); - int virConnectListNWFilters(ConnectionPointer virConnectPtr, Pointer[] name, int maxnames); - int virConnectListSecrets(ConnectionPointer virConnectPtr, Pointer[] uids, int maxUids); - int virConnectListStoragePools(ConnectionPointer virConnectPtr, Pointer[] names, int maxnames); + int virConnectListInterfaces(ConnectionPointer virConnectPtr, CString[] name, int maxNames); + int virConnectListNetworks(ConnectionPointer virConnectPtr, CString[] name, int maxnames); + int virConnectListNWFilters(ConnectionPointer virConnectPtr, CString[] name, int maxnames); + int virConnectListSecrets(ConnectionPointer virConnectPtr, CString[] uids, int maxUids); + int virConnectListStoragePools(ConnectionPointer virConnectPtr, CString[] names, int maxnames); int virConnectNumOfDefinedDomains(ConnectionPointer virConnectPtr); int virConnectNumOfDefinedNetworks(ConnectionPointer virConnectPtr); int virConnectNumOfDefinedInterfaces(ConnectionPointer virConnectPtr); @@ -343,13 +343,13 @@ public interface Libvirt extends Library { // Node/Device functions int virNodeNumOfDevices(ConnectionPointer virConnectPtr, String capabilityName, int flags); - int virNodeListDevices(ConnectionPointer virConnectPtr, String capabilityName, Pointer[] names, int maxnames, + int virNodeListDevices(ConnectionPointer virConnectPtr, String capabilityName, CString[] names, int maxnames, int flags); DevicePointer virNodeDeviceLookupByName(ConnectionPointer virConnectPtr, String name); String virNodeDeviceGetName(DevicePointer virDevicePointer); String virNodeDeviceGetParent(DevicePointer virDevicePointer); int virNodeDeviceNumOfCaps(DevicePointer virDevicePointer); - int virNodeDeviceListCaps(DevicePointer virDevicePointer, Pointer[] names, int maxNames); + int virNodeDeviceListCaps(DevicePointer virDevicePointer, CString[] names, int maxNames); CString virNodeDeviceGetXMLDesc(DevicePointer virDevicePointer, int flags); int virNodeDeviceFree(DevicePointer virDevicePointer); int virNodeDeviceDettach(DevicePointer virDevicePointer); @@ -372,7 +372,7 @@ public interface Libvirt extends Library { int virStoragePoolGetUUID(StoragePoolPointer storagePoolPtr, byte[] uuidString); int virStoragePoolGetUUIDString(StoragePoolPointer storagePoolPtr, byte[] uuidString); CString virStoragePoolGetXMLDesc(StoragePoolPointer storagePoolPtr, int flags); - int virStoragePoolListVolumes(StoragePoolPointer storagePoolPtr, Pointer[] names, int maxnames); + int virStoragePoolListVolumes(StoragePoolPointer storagePoolPtr, CString[] names, int maxnames); int virStoragePoolIsActive(StoragePoolPointer storagePoolPtr); int virStoragePoolIsPersistent(StoragePoolPointer storagePoolPtr); StoragePoolPointer virStoragePoolLookupByName(ConnectionPointer virConnectPtr, String name); @@ -450,7 +450,7 @@ public interface Libvirt extends Library { int virDomainSnapshotDelete(DomainSnapshotPointer virDomainSnapshotPtr, int flags); CString virDomainSnapshotGetXMLDesc(DomainSnapshotPointer virDomainSnapshotPtr, int flags); int virDomainSnapshotFree(DomainSnapshotPointer virDomainSnapshotPtr); - int virDomainSnapshotListNames(DomainPointer virDomainPtr, Pointer[] names, int nameslen, int flags); + int virDomainSnapshotListNames(DomainPointer virDomainPtr, CString[] names, int nameslen, int flags); DomainSnapshotPointer virDomainSnapshotLookupByName(DomainPointer virDomainPtr, String name, int flags); int virDomainSnapshotNum(DomainPointer virDomainPtr, int flags); -- 2.2.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list