[libvirt] [java] [PATCH 4/6] Use the CString class for Arrays of CStrings too

Claudio Bley claudio.bley at gmail.com
Wed Jan 28 20:45:45 UTC 2015


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




More information about the libvir-list mailing list