This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new d97377ab14 Simplify fetching `MethodHandle` by storing the linker as a 
`NativeFunctions` field. Get the method handles for `move` and `delete` 
operations optional.
d97377ab14 is described below

commit d97377ab1435ea0aa617ad6a394769cbdb5617c1
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sat Sep 21 12:08:52 2024 +0200

    Simplify fetching `MethodHandle` by storing the linker as a 
`NativeFunctions` field.
    Get the method handles for `move` and `delete` operations optional.
---
 .../main/org/apache/sis/storage/gdal/Driver.java   | 152 ++++++++++++---------
 .../main/org/apache/sis/storage/gdal/GDAL.java     | 128 +++++++----------
 .../apache/sis/storage/gdal/GDALStoreProvider.java |  13 +-
 .../main/org/apache/sis/storage/gdal/Opener.java   |  12 +-
 .../apache/sis/storage/panama/NativeFunctions.java |  27 ++--
 .../main/org/apache/sis/storage/gsf/GSF.java       |  68 +++++----
 6 files changed, 197 insertions(+), 203 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
index 84cbda2c3b..ffa4d9c3d2 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
@@ -18,13 +18,14 @@ package org.apache.sis.storage.gdal;
 
 import java.util.List;
 import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Optional;
 import java.util.Objects;
 import java.net.URI;
 import java.nio.file.Path;
 import java.io.IOException;
 import java.lang.foreign.Arena;
 import java.lang.foreign.FunctionDescriptor;
-import java.lang.foreign.Linker;
 import java.lang.foreign.MemorySegment;
 import java.lang.foreign.ValueLayout;
 import java.lang.invoke.MethodHandle;
@@ -171,15 +172,35 @@ public final class Driver {
 
     /**
      * List of files of a <abbr>GDAL</abbr> data set, together with methods 
for copying or deleting them.
+     * The list of files is fetched in advance by the caller because the list 
needs to stay available after
+     * {@link GDALStore} has been closed. This class overrides the {@link 
#copy(Path)} and {@link #delete()}
+     * methods for delegating the operation to <abbr>GDAL</abbr> when 
possible. If not possible, this class
+     * fallbacks on the default Java implementation.
      */
     final class FileList extends Resource.FileSet {
-        /** Location of the data store as a path. */
+        /**
+         * Location of the data store as a path. It should be the first 
element of {@link #getPaths()},
+         * but is stored anyway because we have no guarantee that 
<abbr>GDAL</abbr> includes that file
+         * or puts it first in its list of files. May be {@code null} if not 
available.
+         *
+         * @see GDALStore#path
+         */
         private final Path path;
 
-        /** Location of the data store as a URL. */
+        /**
+         * Location of the data store as a <abbr>URL</abbr>. Should never be 
null.
+         *
+         * @see GDALStore#location
+         */
         private final URI location;
 
-        /** Creates a new file set for the given files. */
+        /**
+         * Creates a new {@code FileSet} for the given files.
+         *
+         * @param  paths     the files to be returned by {@link #getPaths()}.
+         * @param  path      the main file, or {@code null} if not available.
+         * @param  location  location of the data store as a <abbr>URL</abbr>.
+         */
         FileList(final Path[] paths, final Path path, final URI location) {
             super(paths);
             this.path = path;
@@ -187,81 +208,77 @@ public final class Driver {
         }
 
         /**
-         * Returns the URL (<abbr>GDAL</abbr> syntax) to the data set.
-         */
-        private String getURL() {
-            return Opener.toURL(location, path, true);
-        }
-
-        /**
-         * Copies the files to the given directory. The source should be an 
<abbr>URL</abbr> recognized
-         * by <abbr>GDAL</abbr> because {@code FileList} can be returned only 
by {@link GDALStore}.
-         * However, the destination could be a pure-Java file system.
+         * Copies the files to the given directory. The source should be a 
<abbr>URL</abbr> recognized
+         * by <abbr>GDAL</abbr> because this {@code FileList} can be returned 
only by {@link GDALStore}.
+         * However, the destination directory given in argument to this method 
may be a Java file system.
+         * In the latter case, this method delegates on the Java 
implementation instead of <abbr>GDAL</abbr>.
          */
         @Override
         public Path copy(final Path destDir) throws IOException {
-            final Path   dest   = destDir.resolve(path.getFileName());
-            final String target = Opener.toURL(dest.toUri(), dest, false);
-            if (target != null) try {
-                copyDataSet(getURL(), target);
-                return dest;
-            } catch (DataStoreException e) {
-                throw new IOException(e);
-            } else {
-                return super.copy(destDir);
+            final Path   file   = destDir.resolve(path.getFileName());
+            final String target = Opener.toURL(file.toUri(), file, false);
+            if (target != null && invoke("copy", "GDALCopyDatasetFiles", 
target)) {
+                return file;
             }
+            return super.copy(destDir);
         }
 
         /**
-         * Deletes the files of the data set.
+         * Deletes the files of the data set. This method delegates to 
<abbr>GDAL</abbr>,
+         * but fallbacks on Java code if the <abbr>GDAL</abbr> function fails.
          */
         @Override
         public void delete() throws IOException {
-            try {
-                deleteDataSet(getURL());
-            } catch (DataStoreException e) {
-                throw new IOException(e);
+            if (!invoke("delete", "GDALDeleteDataset", null)) {
+                super.delete();
             }
         }
-    }
 
-    /**
-     * Copies the files of a data set managed by this driver.
-     * It is caller responsibility to ensure that this driver is the correct 
one for the data set to copy.
-     * No {@link GDALStore} should be opened on the source at the time that 
this method is invoked.
-     *
-     * @param  source  path or <abbr>URL</abbr> (<abbr>GDAL</abbr> syntax) of 
the main file of the data set to copy.
-     * @param  target  path or <abbr>URL</abbr> (<abbr>GDAL</abbr> syntax) of 
the desired target file.
-     * @throws DataStoreException if an error occurred while invoking a 
<abbr>GDAL</abbr> function.
-     */
-    public void copyDataSet(final String source, final String target) throws 
DataStoreException {
-        final int err;
-        final var gdal = owner.GDAL().copyDataset;
-        try (var arena = Arena.ofConfined()) {
-            err = (int) gdal.invokeExact(handle, arena.allocateFrom(target), 
arena.allocateFrom(source));
-        } catch (Throwable e) {
-            throw GDAL.propagate(e);
-        }
-        ErrorHandler.checkCPLErr(err);
-    }
-
-    /**
-     * Deletes the files of a data set managed by this driver.
-     * It is caller responsibility to ensure that this driver is the correct 
one for the data set to delete.
-     * No {@link GDALStore} should be opened on the data set when this method 
is invoked.
-     *
-     * @param  dataset  path or <abbr>URL</abbr> (<abbr>GDAL</abbr> syntax) of 
the main file of the data set to delete.
-     * @throws DataStoreException if an error occurred while invoking a 
<abbr>GDAL</abbr> function.
-     */
-    public void deleteDataSet(final String dataset) throws DataStoreException {
-        final int err;
-        final var gdal = owner.GDAL().deleteDataset;
-        try (var arena = Arena.ofConfined()) {
-            err = (int) gdal.invokeExact(handle, arena.allocateFrom(dataset));
-        } catch (Throwable e) {
-            throw GDAL.propagate(e);
+        /**
+         * Optionally invokes the <abbr>GDAL</abbr> function for copying or 
deleting a data set.
+         * We fetch the method handle in this method rather than in the {@link 
GDAL} class
+         * because those methods should be rarely needed, and also because 
they are optional.
+         * The <abbr>GDAL</abbr> functions handled by this method are:
+         * <ul>
+         *   <li>{@code CPLErr GDALCopyDatasetFiles(GDALDriverH, const char 
*pszNewName, const char *pszOldName)}</li>
+         *   <li>{@code CPLErr GDALDeleteDataset(GDALDriverH, const 
char*)}</li>
+         * </ul>
+         *
+         * @param  caller    name of the Java method invoking this method, for 
logging purpose only.
+         * @param  function  name of the <abbr>GDAL</abbr> function to invoke.
+         * @param  target    the target directory if invoking the copy 
function, or null for the delete function.
+         * @return whether the operation has been successful.
+         */
+        @SuppressWarnings("restricted")
+        private boolean invoke(final String caller, final String function, 
final String target) {
+            Optional<MethodHandle> method = owner.tryGDAL(Driver.class, 
caller).flatMap((gdal) -> {
+                return gdal.symbols.find(function).map((address) -> {
+                    var signature = new ValueLayout[(target != null) ? 3 : 2];
+                    Arrays.fill(signature, ValueLayout.ADDRESS);
+                    return gdal.linker.downcallHandle(address, 
FunctionDescriptor.of(ValueLayout.JAVA_INT, signature));
+                });
+            });
+            if (method.isEmpty()) {
+                return false;
+            }
+            /*
+             * In both "GDALCopyDatasetFiles" and "GDALDeleteDataset" 
function, the driver
+             * handle is the first argument and the dataset URL is the last 
argument.
+             */
+            final String url = Opener.toURL(location, path, true);
+            final int err;
+            try (var arena = Arena.ofConfined()) {
+                final var source = arena.allocateFrom(url);
+                if (target != null) {
+                    err = (int) method.get().invokeExact(handle, 
arena.allocateFrom(target), source);
+                } else {
+                    err = (int) method.get().invokeExact(handle, source);
+                }
+            } catch (Throwable e) {
+                throw GDAL.propagate(e);
+            }
+            return err == 0;
         }
-        ErrorHandler.checkCPLErr(err);
     }
 
     /**
@@ -313,11 +330,10 @@ public final class Driver {
         if (gdal == null || (address = 
gdal.symbols.find("GDALGetDriver").orElse(null)) == null) {
             return List.of();
         }
-        final Linker linker = Linker.nativeLinker();
         @SuppressWarnings("restricted")
-        final MethodHandle getDriver = linker.downcallHandle(address,
+        final MethodHandle getDriver = gdal.linker.downcallHandle(address,
                 FunctionDescriptor.of(ValueLayout.ADDRESS, 
ValueLayout.JAVA_INT));
-        final int count = gdal.invokeGetInt(linker, 
"GDALGetDriverCount").orElse(0);
+        final int count = gdal.invokeGetInt("GDALGetDriverCount").orElse(0);
         return new AbstractList<Driver>() {
             /** Returns the number of drivers. */
             @Override public int size() {
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
index a8a6d2ee6e..89ad84b4ba 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
@@ -24,7 +24,6 @@ import java.util.NoSuchElementException;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.lang.foreign.Arena;
-import java.lang.foreign.Linker;
 import java.lang.foreign.ValueLayout;
 import java.lang.foreign.SymbolLookup;
 import java.lang.foreign.MemorySegment;
@@ -93,18 +92,6 @@ final class GDAL extends NativeFunctions {
      */
     final MethodHandle identifyDriver;
 
-    /**
-     * <abbr>GDAL</abbr> {@code CPLErr GDALCopyDatasetFiles(GDALDriverH, const 
char *pszNewName, const char *pszOldName)}.
-     * Copy the files of a dataset.
-     */
-    final MethodHandle copyDataset;
-
-    /**
-     * <abbr>GDAL</abbr> {@code CPLErr GDALDeleteDataset(GDALDriverH, const 
char*)}.
-     * Delete named dataset.
-     */
-    final MethodHandle deleteDataset;
-
     /**
      * <abbr>GDAL</abbr> {@code GDALDatasetH GDALOpenEx(const char 
*pszFilename, …)}.
      * Opens a raster or vector file by invoking the open method of each 
driver in turn.
@@ -299,37 +286,25 @@ final class GDAL extends NativeFunctions {
         final var acceptPointerReturnInt     = 
FunctionDescriptor.of(ValueLayout.JAVA_INT,    ValueLayout.ADDRESS);
         final var acceptTwoPtrsReturnDouble  = 
FunctionDescriptor.of(ValueLayout.JAVA_DOUBLE, ValueLayout.ADDRESS, 
ValueLayout.ADDRESS);
         final var acceptTwoPtrsReturnPointer = 
FunctionDescriptor.of(ValueLayout.ADDRESS,     ValueLayout.ADDRESS, 
ValueLayout.ADDRESS);
-        final Linker linker = Linker.nativeLinker();
 
         // Memory management
-        free    = lookup(linker, "VSIFree",    
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS));
-        destroy = lookup(linker, "CSLDestroy", 
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS));
+        free    = lookup("VSIFree",    
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS));
+        destroy = lookup("CSLDestroy", 
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS));
 
         // For Driver and/or all major objects
-        identifyDriver  = lookup(linker, "GDALIdentifyDriver",     
acceptTwoPtrsReturnPointer);
-        getName         = lookup(linker, "GDALGetDriverLongName",  
acceptPointerReturnPointer);
-        getIdentifier   = lookup(linker, "GDALGetDriverShortName", 
acceptPointerReturnPointer);
-        getMetadata     = lookup(linker, "GDALGetMetadata",        
acceptTwoPtrsReturnPointer);
-        getMetadataItem = lookup(linker, "GDALGetMetadataItem", 
FunctionDescriptor.of(
+        identifyDriver  = lookup("GDALIdentifyDriver",     
acceptTwoPtrsReturnPointer);
+        getName         = lookup("GDALGetDriverLongName",  
acceptPointerReturnPointer);
+        getIdentifier   = lookup("GDALGetDriverShortName", 
acceptPointerReturnPointer);
+        getMetadata     = lookup("GDALGetMetadata",        
acceptTwoPtrsReturnPointer);
+        getMetadataItem = lookup("GDALGetMetadataItem", FunctionDescriptor.of(
                 ValueLayout.ADDRESS,    // const char* (return type)
                 ValueLayout.ADDRESS,    // GDALMajorObject
                 ValueLayout.ADDRESS,    // const char* name
                 ValueLayout.ADDRESS));  // const char* domain
 
-        copyDataset = lookup(linker, "GDALCopyDatasetFiles", 
FunctionDescriptor.of(
-                ValueLayout.JAVA_INT,   // CPLErr (return type)
-                ValueLayout.ADDRESS,    // GDALDriverH
-                ValueLayout.ADDRESS,    // const char* pszNewName
-                ValueLayout.ADDRESS));  // const char* pszOldName
-
-        deleteDataset = lookup(linker, "GDALDeleteDataset", 
FunctionDescriptor.of(
-                ValueLayout.JAVA_INT,   // CPLErr (return type)
-                ValueLayout.ADDRESS,    // GDALDriverH
-                ValueLayout.ADDRESS));  // const char* pszName
-
         // For Opener
-        close = lookup(linker, "GDALClose",  acceptPointerReturnInt);
-        open  = lookup(linker, "GDALOpenEx", 
FunctionDescriptor.of(ValueLayout.ADDRESS,
+        close = lookup("GDALClose",  acceptPointerReturnInt);
+        open  = lookup("GDALOpenEx", FunctionDescriptor.of(ValueLayout.ADDRESS,
                 ValueLayout.ADDRESS,        // const char *pszFilename
                 ValueLayout.JAVA_INT,       // unsigned int nOpenFlags
                 ValueLayout.ADDRESS,        // const char *const 
*papszAllowedDrivers
@@ -337,60 +312,60 @@ final class GDAL extends NativeFunctions {
                 ValueLayout.ADDRESS));      // const char *const 
*papszSiblingFiles
 
         // For all data sets
-        getFileList      = lookup(linker, "GDALGetFileList",      
acceptPointerReturnPointer);
-        getDatasetDriver = lookup(linker, "GDALGetDatasetDriver", 
acceptPointerReturnPointer);
-        getSpatialRef    = lookup(linker, "GDALGetSpatialRef",    
acceptPointerReturnPointer);
-        getGCPSpatialRef = lookup(linker, "GDALGetGCPSpatialRef", 
acceptPointerReturnPointer);
-        exportToWkt      = lookup(linker, "OSRExportToWktEx",     
FunctionDescriptor.of(
+        getFileList      = lookup("GDALGetFileList",      
acceptPointerReturnPointer);
+        getDatasetDriver = lookup("GDALGetDatasetDriver", 
acceptPointerReturnPointer);
+        getSpatialRef    = lookup("GDALGetSpatialRef",    
acceptPointerReturnPointer);
+        getGCPSpatialRef = lookup("GDALGetGCPSpatialRef", 
acceptPointerReturnPointer);
+        exportToWkt      = lookup("OSRExportToWktEx",     
FunctionDescriptor.of(
                 ValueLayout.JAVA_INT,       // CPLErr error code (return value)
                 ValueLayout.ADDRESS,        // OGRSpatialReferenceH
                 ValueLayout.ADDRESS,        // char **ppszWKT
                 ValueLayout.ADDRESS));      // const char *const *papszOptions
 
-        getDataAxisToCRSAxis = lookup(linker, 
"OSRGetDataAxisToSRSAxisMapping", acceptTwoPtrsReturnPointer);
+        getDataAxisToCRSAxis = lookup("OSRGetDataAxisToSRSAxisMapping", 
acceptTwoPtrsReturnPointer);
 
         // For TiledResource (GDAL Raster)
-        getGeoTransform = lookup(linker, "GDALGetGeoTransform", 
FunctionDescriptor.of(
+        getGeoTransform = lookup("GDALGetGeoTransform", FunctionDescriptor.of(
                 ValueLayout.JAVA_INT,       // CPLErr error code (return value)
                 ValueLayout.ADDRESS,        // GDALDataSetH dataset
                 ValueLayout.ADDRESS));      // double *padfTransform
 
-        getRasterXSize     = lookup(linker, "GDALGetRasterXSize",     
acceptPointerReturnInt);
-        getRasterYSize     = lookup(linker, "GDALGetRasterYSize",     
acceptPointerReturnInt);
-        getRasterCount     = lookup(linker, "GDALGetRasterCount",     
acceptPointerReturnInt);
-        getRasterBandXSize = lookup(linker, "GDALGetRasterBandXSize", 
acceptPointerReturnInt);
-        getRasterBandYSize = lookup(linker, "GDALGetRasterBandYSize", 
acceptPointerReturnInt);
-        getRasterBand      = lookup(linker, "GDALGetRasterBand", 
FunctionDescriptor.of(
+        getRasterXSize     = lookup("GDALGetRasterXSize",     
acceptPointerReturnInt);
+        getRasterYSize     = lookup("GDALGetRasterYSize",     
acceptPointerReturnInt);
+        getRasterCount     = lookup("GDALGetRasterCount",     
acceptPointerReturnInt);
+        getRasterBandXSize = lookup("GDALGetRasterBandXSize", 
acceptPointerReturnInt);
+        getRasterBandYSize = lookup("GDALGetRasterBandYSize", 
acceptPointerReturnInt);
+        getRasterBand      = lookup("GDALGetRasterBand", FunctionDescriptor.of(
                 ValueLayout.ADDRESS,        // GDALRasterBandH (return value)
                 ValueLayout.ADDRESS,        // GDALDataSetH dataset
                 ValueLayout.JAVA_INT));     // Band index, starting with 1.
 
         // For Band
-        getBandNumber          = lookup(linker, "GDALGetBandNumber",           
     acceptPointerReturnInt);
-        getColorInterpretation = lookup(linker, 
"GDALGetRasterColorInterpretation", acceptPointerReturnInt);
-        getRasterDataType      = lookup(linker, "GDALGetRasterDataType",       
     acceptPointerReturnInt);
-        getRasterMinimum       = lookup(linker, "GDALGetRasterMinimum",        
     acceptTwoPtrsReturnDouble);
-        getRasterMaximum       = lookup(linker, "GDALGetRasterMaximum",        
     acceptTwoPtrsReturnDouble);
-        getRasterNoDataValue   = lookup(linker, "GDALGetRasterNoDataValue",    
     acceptTwoPtrsReturnDouble);
-        getRasterScale         = lookup(linker, "GDALGetRasterScale",          
     acceptTwoPtrsReturnDouble);
-        getRasterOffset        = lookup(linker, "GDALGetRasterOffset",         
     acceptTwoPtrsReturnDouble);
-        getRasterUnitType      = lookup(linker, "GDALGetRasterUnitType",       
     acceptPointerReturnPointer);
-        getRasterCategoryNames = lookup(linker, "GDALGetRasterCategoryNames",  
     acceptPointerReturnPointer);
-        getRasterColorTable    = lookup(linker, "GDALGetRasterColorTable",     
     acceptPointerReturnPointer);
-        getColorEntryCount     = lookup(linker, "GDALGetColorEntryCount",      
     acceptPointerReturnInt);
-        getColorEntryAsRGB     = lookup(linker, "GDALGetColorEntryAsRGB", 
FunctionDescriptor.of(
+        getBandNumber          = lookup("GDALGetBandNumber",                
acceptPointerReturnInt);
+        getColorInterpretation = lookup("GDALGetRasterColorInterpretation", 
acceptPointerReturnInt);
+        getRasterDataType      = lookup("GDALGetRasterDataType",            
acceptPointerReturnInt);
+        getRasterMinimum       = lookup("GDALGetRasterMinimum",             
acceptTwoPtrsReturnDouble);
+        getRasterMaximum       = lookup("GDALGetRasterMaximum",             
acceptTwoPtrsReturnDouble);
+        getRasterNoDataValue   = lookup("GDALGetRasterNoDataValue",         
acceptTwoPtrsReturnDouble);
+        getRasterScale         = lookup("GDALGetRasterScale",               
acceptTwoPtrsReturnDouble);
+        getRasterOffset        = lookup("GDALGetRasterOffset",              
acceptTwoPtrsReturnDouble);
+        getRasterUnitType      = lookup("GDALGetRasterUnitType",            
acceptPointerReturnPointer);
+        getRasterCategoryNames = lookup("GDALGetRasterCategoryNames",       
acceptPointerReturnPointer);
+        getRasterColorTable    = lookup("GDALGetRasterColorTable",          
acceptPointerReturnPointer);
+        getColorEntryCount     = lookup("GDALGetColorEntryCount",           
acceptPointerReturnInt);
+        getColorEntryAsRGB     = lookup("GDALGetColorEntryAsRGB", 
FunctionDescriptor.of(
                 ValueLayout.JAVA_INT,
                 ValueLayout.ADDRESS,
                 ValueLayout.JAVA_INT,
                 ValueLayout.ADDRESS));
 
         // Band I/O
-        getBlockSize = lookup(linker, "GDALGetBlockSize", 
FunctionDescriptor.ofVoid(
+        getBlockSize = lookup("GDALGetBlockSize", FunctionDescriptor.ofVoid(
                 ValueLayout.ADDRESS,        // GDALRasterBandH
                 ValueLayout.ADDRESS,        // int *pnXSize
                 ValueLayout.ADDRESS));      // int *pnYSize
 
-        rasterIO = lookup(linker, "GDALRasterIO", FunctionDescriptor.of(
+        rasterIO = lookup("GDALRasterIO", FunctionDescriptor.of(
                 ValueLayout.JAVA_INT,       // CPLErr error code (return value)
                 ValueLayout.ADDRESS,        // GDALRasterBandH hRBand
                 ValueLayout.JAVA_INT,       // GDALRWFlag eRWFlag
@@ -405,7 +380,7 @@ final class GDAL extends NativeFunctions {
                 ValueLayout.JAVA_INT,       // int nPixelSpace
                 ValueLayout.JAVA_INT));     // int nLineSpace
 
-        adviseRead = lookup(linker, "GDALRasterAdviseRead", 
FunctionDescriptor.of(
+        adviseRead = lookup("GDALRasterAdviseRead", FunctionDescriptor.of(
                 ValueLayout.JAVA_INT,       // CPLErr error code (return value)
                 ValueLayout.ADDRESS,        // GDALRasterBandH hRBand
                 ValueLayout.JAVA_INT,       // int nDSXOff
@@ -418,11 +393,11 @@ final class GDAL extends NativeFunctions {
                 ValueLayout.ADDRESS));      // CSLConstList papszOptions
 
         // Set error handling first in order to redirect initialization 
warnings.
-        setErrorHandler(linker, null);
+        setErrorHandler(null);
 
         // Initialize GDAL after we found all functions.
         if (!invoke("GDALAllRegister")) {
-            log("open", new LogRecord(Level.WARNING, "Could not initialize 
GDAL."));
+            log(GDAL.class, "<init>", new LogRecord(Level.WARNING, "Could not 
initialize GDAL."));
         }
     }
 
@@ -446,7 +421,7 @@ final class GDAL extends NativeFunctions {
             if (global != null) {
                 if (GDALStoreProvider.LOGGER.isLoggable(Level.CONFIG)) {
                     global.version("--version").ifPresent((version) -> {
-                        log("open", new LogRecord(Level.CONFIG, version));
+                        log(GDAL.class, "<init>", new LogRecord(Level.CONFIG, 
version));
                     });
                 }
             }
@@ -492,12 +467,13 @@ final class GDAL extends NativeFunctions {
     /**
      * Same as {@link #global}, but logs a warning instead of throwing an 
exception in case of error.
      *
-     * @param  caller  the name of the method which is invoking this method.
+     * @param  classe  the class which is invoking this method (for logging 
purpose).
+     * @param  method  the name of the method which is invoking this method 
(for logging purpose).
      * @return handles to native functions needed by this module, or empty if 
not available.
      */
-    static synchronized Optional<GDAL> tryGlobal(final String caller) {
+    static synchronized Optional<GDAL> tryGlobal(final Class<?> classe, final 
String method) {
         if (globalStatus == null) {
-            load(true).getError(GDALStoreProvider.NAME).ifPresent((record) -> 
log(caller, record));
+            load(true).getError(GDALStoreProvider.NAME).ifPresent((record) -> 
log(classe, method, record));
         }
         return Optional.ofNullable(global);
     }
@@ -510,7 +486,6 @@ final class GDAL extends NativeFunctions {
      * <p><b>The error handler is valid only during the lifetime of the 
{@linkplain #arena() arena}.</b>
      * The error handle shall be uninstalled before the arena is closed.</p>
      *
-     * @param  linker  the linker to use. Should be {@link 
Linker#nativeLinker()}.
      * @param  target  the function to set as an error handler, or {@link 
MemorySegment#NULL} for the GDAL default.
      *                 If {@code null}, the function handle will be created by 
this method.
      * @return the previous error handler, or {@link MemorySegment#NULL} it it 
was the <abbr>GDAL</abbr> default.
@@ -519,7 +494,7 @@ final class GDAL extends NativeFunctions {
      * @see GDALStoreProvider#fatalError()
      */
     @SuppressWarnings("restricted")
-    private MemorySegment setErrorHandler(final Linker linker, MemorySegment 
target) {
+    private MemorySegment setErrorHandler(MemorySegment target) {
         final MemorySegment setter = 
symbols.find("CPLSetErrorHandler").orElse(null);
         if (setter == null) {
             return MemorySegment.NULL;
@@ -540,11 +515,12 @@ final class GDAL extends NativeFunctions {
     /**
      * Logs the given record as if was produced by the {@link 
GDALStoreProvider}, which is the public class.
      *
-     * @param  caller  the method name to report as the caller.
+     * @param  classe  the class which is invoking this method (for logging 
purpose).
+     * @param  method  the name of the method which is invoking this method 
(for logging purpose).
      * @param  record  the error to log.
      */
-    private static void log(final String caller, final LogRecord record) {
-        Logging.completeAndLog(GDALStoreProvider.LOGGER, 
GDALStoreProvider.class, caller, record);
+    private static void log(final Class<?> classe, final String method, final 
LogRecord record) {
+        Logging.completeAndLog(GDALStoreProvider.LOGGER, classe, method, 
record);
     }
 
     /**
@@ -561,7 +537,7 @@ final class GDAL extends NativeFunctions {
      * @return the <abbr>GDAL</abbr> version, or a message saying that the 
library was not found.
      */
     final Optional<String> version(final String request) {
-        return invokeGetString(Linker.nativeLinker(), "GDALVersionInfo", 
request);
+        return invokeGetString("GDALVersionInfo", request);
     }
 
     /**
@@ -618,7 +594,7 @@ final class GDAL extends NativeFunctions {
     public void run() {
         try {
             // Clear the error handler because the arena will be closed.
-            setErrorHandler(Linker.nativeLinker(), MemorySegment.NULL);
+            setErrorHandler(MemorySegment.NULL);
             invoke("GDALDestroy");
         } finally {
             super.run();
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
index ff505bb631..ed6e781348 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
@@ -154,12 +154,13 @@ public class GDALStoreProvider extends DataStoreProvider {
      * Tries to load <abbr>GDAL</abbr> if not already done, without throwing 
an exception in case of error.
      * Instead, the error is logged and {@code null} is returned. This is used 
for probing.
      *
-     * @param  caller  the name of the method which is invoking this method.
+     * @param  classe  the class which is invoking this method (for logging 
purpose).
+     * @param  method  the name of the method which is invoking this method 
(for logging purpose).
      * @return the set of native functions, or {@code null} if not available.
      */
-    final synchronized Optional<GDAL> tryGDAL(final String caller) {
+    final synchronized Optional<GDAL> tryGDAL(final Class<?> classe, final 
String method) {
         if (status == null) {
-            return GDAL.tryGlobal(caller);
+            return GDAL.tryGlobal(classe, method);
         }
         return Optional.ofNullable(nativeFunctions);
     }
@@ -196,7 +197,7 @@ public class GDALStoreProvider extends DataStoreProvider {
      * @return the version information computed from the string provided by 
GDAL.
      */
     private <V> Optional<V> version(final String caller, final String request, 
final Function<String, V> mapper) {
-        return tryGDAL(caller).flatMap((gdal) -> 
gdal.version(request)).map(mapper);
+        return tryGDAL(GDALStoreProvider.class, caller).flatMap((gdal) -> 
gdal.version(request)).map(mapper);
     }
 
     /**
@@ -237,7 +238,7 @@ public class GDALStoreProvider extends DataStoreProvider {
      * @return all <abbr>GDAL</abbr> drivers, or an empty list if the 
<abbr>GDAL</abbr> library has not been found.
      */
     public List<Driver> getDrivers() {
-        return Driver.list(this, tryGDAL("getDrivers").orElse(null));
+        return Driver.list(this, tryGDAL(GDALStoreProvider.class, 
"getDrivers").orElse(null));
     }
 
     /**
@@ -257,7 +258,7 @@ public class GDALStoreProvider extends DataStoreProvider {
      * @throws DataStoreException if an error occurred while querying 
<abbr>GDAL</abbr> metadata.
      */
     public TreeTable configuration() throws DataStoreException {
-        return Driver.configuration(this, 
tryGDAL("configuration").orElse(null));
+        return Driver.configuration(this, tryGDAL(GDALStoreProvider.class, 
"configuration").orElse(null));
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Opener.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Opener.java
index 642e30d89d..45e4314a30 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Opener.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Opener.java
@@ -155,14 +155,14 @@ final class Opener implements Runnable {
             url = connector.getStorageAs(String.class);
         }
         if (url != null) {
-            final GDAL gdal = owner.tryGDAL("probeContent").orElse(null);
+            final GDAL gdal = owner.tryGDAL(GDALStoreProvider.class, 
"probeContent").orElse(null);
             if (gdal != null) {
                 try (var arena = Arena.ofConfined()) {
-                    final var driver = (MemorySegment) 
gdal.identifyDriver.invokeExact(
-                            arena.allocateFrom(url), MemorySegment.NULL);
+                    var strPtr = arena.allocateFrom(url);
+                    var driver = (MemorySegment) 
gdal.identifyDriver.invokeExact(strPtr, MemorySegment.NULL);
                     if (!GDAL.isNull(driver)) {
-                        MemorySegment mimeType = (MemorySegment) 
gdal.getMetadataItem.invokeExact(
-                                driver, arena.allocateFrom("DMD_MIMETYPE"), 
MemorySegment.NULL);
+                        strPtr = arena.allocateFrom("DMD_MIMETYPE");
+                        var mimeType = (MemorySegment) 
gdal.getMetadataItem.invokeExact(driver, strPtr, MemorySegment.NULL);
                         return new ProbeResult(true, GDAL.toString(mimeType), 
null);
                     }
                 } catch (Throwable e) {
@@ -183,7 +183,7 @@ final class Opener implements Runnable {
     @Override
     public void run() {
         if (handle != null) {
-            owner.tryGDAL("close").ifPresent((gdal) -> {
+            owner.tryGDAL(GDALStore.class, "close").ifPresent((gdal) -> {
                 final int err;
                 try {
                     err = (int) gdal.close.invokeExact(handle);
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/NativeFunctions.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/NativeFunctions.java
index 4227212271..d4458030db 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/NativeFunctions.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/NativeFunctions.java
@@ -55,6 +55,12 @@ public abstract class NativeFunctions implements Runnable, 
Callable<Object> {
      */
     public final SymbolLookup symbols;
 
+    /**
+     * The linker to use for fetching method handles from the {@linkplain 
#symbols}.
+     * In current version, this is always {@link Linker#nativeLinker()}.
+     */
+    public final Linker linker;
+
     /**
      * Creates a new set of handles to native functions.
      *
@@ -64,6 +70,7 @@ public abstract class NativeFunctions implements Runnable, 
Callable<Object> {
         libraryName = loader.filename;
         arena       = loader.arena;
         symbols     = loader.symbols;
+        linker      = Linker.nativeLinker();
     }
 
     /**
@@ -77,14 +84,13 @@ public abstract class NativeFunctions implements Runnable, 
Callable<Object> {
      * Returns the method handler for the <abbr>GDAL</abbr> function of given 
name and signature.
      * This is a convenience method for initialization of fields in subclasses.
      *
-     * @param  linker     {@link Linker#nativeLinker()} (should be fetched 
only once).
      * @param  function   name of the C/C++ <abbr>GDAL</abbr> function to 
invoke.
      * @param  signature  type of arguments and return type.
      * @return method handler for the <abbr>GDAL</abbr> function.
      * @throws IllegalArgumentException if the given function has not been 
found.
      */
     @SuppressWarnings("restricted")
-    protected final MethodHandle lookup(final Linker linker, final String 
function, final FunctionDescriptor signature) {
+    protected final MethodHandle lookup(final String function, final 
FunctionDescriptor signature) {
         return symbols.find(function).map((method) -> 
linker.downcallHandle(method, signature)).orElseThrow();
     }
 
@@ -93,16 +99,14 @@ public abstract class NativeFunctions implements Runnable, 
Callable<Object> {
      * This method should be used only for rarely invoked C/C++ functions, 
because it fetches the
      * method handler and create a confined arena on every calls.
      *
-     * @param  linker    {@link Linker#nativeLinker()} (should be fetched only 
once).
      * @param  function  name of the C/C++ <abbr>GDAL</abbr> function to 
invoke.
      * @param  arg       the argument.
      * @return whether the return value, or empty if the method was not found 
or returned {@code null}.
      */
-    protected final Optional<String> invokeGetString(final Linker linker, 
final String function, final String arg) {
+    protected final Optional<String> invokeGetString(final String function, 
final String arg) {
         return symbols.find(function).map((method) -> {
-            final MethodHandle handle = lookup(linker, function,
-                    FunctionDescriptor.of(ValueLayout.ADDRESS, 
ValueLayout.ADDRESS));
-            final MemorySegment result;
+            MethodHandle handle = lookup(function, 
FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS));
+            MemorySegment result;
             try (Arena local = Arena.ofConfined()) {
                 result = (MemorySegment) 
handle.invokeExact(local.allocateFrom(arg));
             } catch (Throwable e) {
@@ -115,14 +119,13 @@ public abstract class NativeFunctions implements 
Runnable, Callable<Object> {
     /**
      * Invokes a C/C++ function which expects no argument and returns an 
integer.
      * This method should be used only for rarely invoked C/C++ functions,
-     * because it fetches the method handler on every calls.
+     * because it fetches the method handle on every calls.
      *
-     * @param  linker    {@link Linker#nativeLinker()} (should be fetched only 
once).
      * @param  function  name of the C/C++ <abbr>GDAL</abbr> function to 
invoke.
      * @return whether the return value, or empty if the method was not found.
      */
     @SuppressWarnings("restricted")
-    public final OptionalInt invokeGetInt(final Linker linker, final String 
function) {
+    public final OptionalInt invokeGetInt(final String function) {
         final Optional<MemorySegment> method = symbols.find(function);
         if (method.isEmpty()) {
             return OptionalInt.empty();
@@ -140,7 +143,7 @@ public abstract class NativeFunctions implements Runnable, 
Callable<Object> {
     /**
      * Invokes a C/C++ function which expects no argument and returns no value.
      * This method should be used only for rarely invoked C/C++ functions,
-     * because it fetches the linker and method handler on every calls.
+     * because it fetches the method handle on every calls.
      *
      * @param  function  name of the C/C++ <abbr>GDAL</abbr> function to 
invoke.
      * @return whether the function has been found and executed.
@@ -151,7 +154,7 @@ public abstract class NativeFunctions implements Runnable, 
Callable<Object> {
         if (method.isEmpty()) {
             return false;
         }
-        final MethodHandle handle = 
Linker.nativeLinker().downcallHandle(method.get(), FunctionDescriptor.ofVoid());
+        final MethodHandle handle = linker.downcallHandle(method.get(), 
FunctionDescriptor.ofVoid());
         try {
             handle.invokeExact();
         } catch (Throwable e) {
diff --git 
a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
 
b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
index a2e94688e8..fbaa11ff68 100644
--- 
a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
+++ 
b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
@@ -19,7 +19,6 @@ package org.apache.sis.storage.gsf;
 import java.lang.foreign.AddressLayout;
 import java.lang.foreign.Arena;
 import java.lang.foreign.FunctionDescriptor;
-import java.lang.foreign.Linker;
 import java.lang.foreign.MemoryLayout;
 import java.lang.foreign.MemorySegment;
 import java.lang.foreign.ValueLayout;
@@ -687,7 +686,6 @@ public class GSF extends NativeFunctions {
      */
     private GSF(final LibraryLoader<GSF> loader) {
         super(loader);
-        final Linker linker = Linker.nativeLinker();
 
         final FunctionDescriptor p = FunctionDescriptor.of(GSF.C_POINTER);
         final FunctionDescriptor i_i = FunctionDescriptor.of(GSF.C_INT, 
GSF.C_INT);
@@ -696,39 +694,39 @@ public class GSF extends NativeFunctions {
         final FunctionDescriptor i_p_p_p = FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER, GSF.C_POINTER, GSF.C_POINTER);
         final FunctionDescriptor i_i_p = FunctionDescriptor.of(GSF.C_INT, 
GSF.C_INT, GSF.C_POINTER);
 
-        gsfOpen                                 = lookup(linker, "gsfOpen",    
                             FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, 
GSF.C_INT, GSF.C_POINTER));
-        gsfOpenBuffered                         = lookup(linker, 
"gsfOpenBuffered",                         FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER, GSF.C_INT, GSF.C_POINTER, GSF.C_INT));
-        gsfClose                                = lookup(linker, "gsfClose",   
                             i_i);
-        gsfSeek                                 = lookup(linker, "gsfSeek",    
                             i_i_i);
-        gsfRead                                 = lookup(linker, "gsfRead",    
                             FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, 
GSF.C_INT, GSF.C_POINTER, GSF.C_POINTER, GSF.C_POINTER, GSF.C_INT));
-        gsfWrite                                = lookup(linker, "gsfWrite",   
                             FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, 
GSF.C_POINTER, GSF.C_POINTER));
-        gsfLoadScaleFactor                      = lookup(linker, 
"gsfLoadScaleFactor",                      FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER, GSF.C_INT, GSF.C_CHAR, GSF.C_DOUBLE, GSF.C_INT));
-        gsfGetScaleFactor                       = lookup(linker, 
"gsfGetScaleFactor",                       FunctionDescriptor.of(GSF.C_INT, 
GSF.C_INT, GSF.C_INT, GSF.C_POINTER, GSF.C_POINTER, GSF.C_POINTER));
-        gsfFree                                 = lookup(linker, "gsfFree",    
                             FunctionDescriptor.ofVoid(GSF.C_POINTER));
-        gsfPrintError                           = lookup(linker, 
"gsfPrintError",                           p);
-        gsfIntError                             = lookup(linker, 
"gsfIntError",                             FunctionDescriptor.of(GSF.C_INT));
-        gsfStringError                          = lookup(linker, 
"gsfStringError",                          p);
-        gsfIndexTime                            = lookup(linker, 
"gsfIndexTime",                            FunctionDescriptor.of(GSF.C_INT, 
GSF.C_INT, GSF.C_INT, GSF.C_INT, GSF.C_POINTER, GSF.C_POINTER));
-        gsfPercent                              = lookup(linker, "gsfPercent", 
                             i_i);
-        gsfGetNumberRecords                     = lookup(linker, 
"gsfGetNumberRecords",                     i_i_i);
-        gsfCopyRecords                          = lookup(linker, 
"gsfCopyRecords",                          i_p_p);
-        gsfPutMBParams                          = lookup(linker, 
"gsfPutMBParams",                          FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER, GSF.C_POINTER, GSF.C_INT, GSF.C_INT));
-        gsfGetMBParams                          = lookup(linker, 
"gsfGetMBParams",                          i_p_p_p);
-        gsfGetSwathBathyBeamWidths              = lookup(linker, 
"gsfGetSwathBathyBeamWidths",              i_p_p_p);
-        gsfIsStarboardPing                      = lookup(linker, 
"gsfIsStarboardPing",                      FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER));
-        gsfLoadDepthScaleFactorAutoOffset       = lookup(linker, 
"gsfLoadDepthScaleFactorAutoOffset",       FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER, GSF.C_INT, GSF.C_INT, GSF.C_DOUBLE, GSF.C_DOUBLE, GSF.C_POINTER, 
GSF.C_CHAR, GSF.C_DOUBLE));
-        gsfGetSwathBathyArrayMinMax             = lookup(linker, 
"gsfGetSwathBathyArrayMinMax",             FunctionDescriptor.of(GSF.C_INT, 
GSF.C_POINTER, GSF.C_INT, GSF.C_POINTER, GSF.C_POINTER));
-        gsfGetSonarTextName                     = lookup(linker, 
"gsfGetSonarTextName",                     FunctionDescriptor.of(GSF.C_POINTER, 
GSF.C_POINTER));
-        gsfFileSupportsRecalculateXYZ           = lookup(linker, 
"gsfFileSupportsRecalculateXYZ",           i_i_p);
-        gsfFileSupportsRecalculateTPU           = lookup(linker, 
"gsfFileSupportsRecalculateTPU",           i_i_p);
-        gsfFileSupportsRecalculateNominalDepth  = lookup(linker, 
"gsfFileSupportsRecalculateNominalDepth",  i_i_p);
-        gsfFileContainsMBAmplitude              = lookup(linker, 
"gsfFileContainsMBAmplitude",              i_i_p);
-        gsfFileContainsMBImagery                = lookup(linker, 
"gsfFileContainsMBImagery",                i_i_p);
-        gsfIsNewSurveyLine                      = lookup(linker, 
"gsfIsNewSurveyLine",                      FunctionDescriptor.of(GSF.C_INT, 
GSF.C_INT, GSF.C_POINTER, GSF.C_DOUBLE, GSF.C_POINTER));
-        gsfInitializeMBParams                   = lookup(linker, 
"gsfInitializeMBParams",                   p);
-        gsfStat                                 = lookup(linker, "gsfStat",    
                             i_p_p);
-        gsfGetPositionDestination               = lookup(linker, 
"gsfGetPositionDestination",               FunctionDescriptor.of(GSF.C_POINTER, 
Position.LAYOUT, PositionOffsets.LAYOUT, GSF.C_DOUBLE, GSF.C_DOUBLE));
-        gsfGetPositionOffsets                   = lookup(linker, 
"gsfGetPositionOffsets",                   FunctionDescriptor.of(GSF.C_POINTER, 
Position.LAYOUT, Position.LAYOUT, GSF.C_DOUBLE, GSF.C_DOUBLE));
+        gsfOpen                                 = lookup("gsfOpen",            
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, GSF.C_INT, 
GSF.C_POINTER));
+        gsfOpenBuffered                         = lookup("gsfOpenBuffered",    
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, GSF.C_INT, 
GSF.C_POINTER, GSF.C_INT));
+        gsfClose                                = lookup("gsfClose",           
                     i_i);
+        gsfSeek                                 = lookup("gsfSeek",            
                     i_i_i);
+        gsfRead                                 = lookup("gsfRead",            
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, GSF.C_INT, 
GSF.C_POINTER, GSF.C_POINTER, GSF.C_POINTER, GSF.C_INT));
+        gsfWrite                                = lookup("gsfWrite",           
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, GSF.C_POINTER, 
GSF.C_POINTER));
+        gsfLoadScaleFactor                      = lookup("gsfLoadScaleFactor", 
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, GSF.C_INT, 
GSF.C_CHAR, GSF.C_DOUBLE, GSF.C_INT));
+        gsfGetScaleFactor                       = lookup("gsfGetScaleFactor",  
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, GSF.C_INT, 
GSF.C_POINTER, GSF.C_POINTER, GSF.C_POINTER));
+        gsfFree                                 = lookup("gsfFree",            
                     FunctionDescriptor.ofVoid(GSF.C_POINTER));
+        gsfPrintError                           = lookup("gsfPrintError",      
                     p);
+        gsfIntError                             = lookup("gsfIntError",        
                     FunctionDescriptor.of(GSF.C_INT));
+        gsfStringError                          = lookup("gsfStringError",     
                     p);
+        gsfIndexTime                            = lookup("gsfIndexTime",       
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, GSF.C_INT, 
GSF.C_INT, GSF.C_POINTER, GSF.C_POINTER));
+        gsfPercent                              = lookup("gsfPercent",         
                     i_i);
+        gsfGetNumberRecords                     = 
lookup("gsfGetNumberRecords",                     i_i_i);
+        gsfCopyRecords                          = lookup("gsfCopyRecords",     
                     i_p_p);
+        gsfPutMBParams                          = lookup("gsfPutMBParams",     
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, 
GSF.C_POINTER, GSF.C_INT, GSF.C_INT));
+        gsfGetMBParams                          = lookup("gsfGetMBParams",     
                     i_p_p_p);
+        gsfGetSwathBathyBeamWidths              = 
lookup("gsfGetSwathBathyBeamWidths",              i_p_p_p);
+        gsfIsStarboardPing                      = lookup("gsfIsStarboardPing", 
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER));
+        gsfLoadDepthScaleFactorAutoOffset       = 
lookup("gsfLoadDepthScaleFactorAutoOffset",       
FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, GSF.C_INT, GSF.C_INT, 
GSF.C_DOUBLE, GSF.C_DOUBLE, GSF.C_POINTER, GSF.C_CHAR, GSF.C_DOUBLE));
+        gsfGetSwathBathyArrayMinMax             = 
lookup("gsfGetSwathBathyArrayMinMax",             
FunctionDescriptor.of(GSF.C_INT, GSF.C_POINTER, GSF.C_INT, GSF.C_POINTER, 
GSF.C_POINTER));
+        gsfGetSonarTextName                     = 
lookup("gsfGetSonarTextName",                     
FunctionDescriptor.of(GSF.C_POINTER, GSF.C_POINTER));
+        gsfFileSupportsRecalculateXYZ           = 
lookup("gsfFileSupportsRecalculateXYZ",           i_i_p);
+        gsfFileSupportsRecalculateTPU           = 
lookup("gsfFileSupportsRecalculateTPU",           i_i_p);
+        gsfFileSupportsRecalculateNominalDepth  = 
lookup("gsfFileSupportsRecalculateNominalDepth",  i_i_p);
+        gsfFileContainsMBAmplitude              = 
lookup("gsfFileContainsMBAmplitude",              i_i_p);
+        gsfFileContainsMBImagery                = 
lookup("gsfFileContainsMBImagery",                i_i_p);
+        gsfIsNewSurveyLine                      = lookup("gsfIsNewSurveyLine", 
                     FunctionDescriptor.of(GSF.C_INT, GSF.C_INT, GSF.C_POINTER, 
GSF.C_DOUBLE, GSF.C_POINTER));
+        gsfInitializeMBParams                   = 
lookup("gsfInitializeMBParams",                   p);
+        gsfStat                                 = lookup("gsfStat",            
                     i_p_p);
+        gsfGetPositionDestination               = 
lookup("gsfGetPositionDestination",               
FunctionDescriptor.of(GSF.C_POINTER, Position.LAYOUT, PositionOffsets.LAYOUT, 
GSF.C_DOUBLE, GSF.C_DOUBLE));
+        gsfGetPositionOffsets                   = 
lookup("gsfGetPositionOffsets",                   
FunctionDescriptor.of(GSF.C_POINTER, Position.LAYOUT, Position.LAYOUT, 
GSF.C_DOUBLE, GSF.C_DOUBLE));
     }
 
     public Arena getArena() {

Reply via email to