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 <[email protected]>
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() {