From 9129bd26cf10bcdc6d553c2afe39c8fcf6579d08 Mon Sep 17 00:00:00 2001 From: Thomas Bonfort Date: Tue, 3 Oct 2023 13:16:06 +0200 Subject: [PATCH] add RegisterPlugin --- errors.go | 4 ++++ godal.cpp | 13 +++++++++++++ godal.go | 14 +++++++++++++- godal.h | 1 + godal_test.go | 18 ++++++++++++++++++ options.go | 9 +++++++++ 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/errors.go b/errors.go index 8c7f939..5110432 100644 --- a/errors.go +++ b/errors.go @@ -152,6 +152,7 @@ func ErrLogger(fn ErrorHandler) interface { ClearStatisticsOption GridOption NearblackOption + RegisterPluginOption } { return errorCallback{fn} } @@ -372,6 +373,9 @@ func (ec errorCallback) setGridOpt(o *gridOpts) { func (ec errorCallback) setNearblackOpt(o *nearBlackOpts) { o.errorHandler = ec.fn } +func (ec errorCallback) setRegisterPluginOpt(o *registerPluginOpts) { + o.errorHandler = ec.fn +} type multiError struct { errs []error diff --git a/godal.cpp b/godal.cpp index d5ac897..3b6e2cc 100644 --- a/godal.cpp +++ b/godal.cpp @@ -200,6 +200,19 @@ void godalRegisterPlugins(){ #endif } +void godalRegisterPlugin(cctx *ctx, const char *name){ + godalWrap(ctx); +#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 8, 0) + CPLErr ret = GDALRegisterPlugin(name); + if (ret != 0) { + forceCPLError(ctx, ret); + } +#else + CPLError(CE_Failure, CPLE_NotSupported, "GDALRegisterPlugin is only supported in GDAL version >= 3.8"); +#endif + godalUnwrap(); +} + GDALDatasetH godalCreate(cctx *ctx, GDALDriverH drv, const char* name, int width, int height, int nbands, GDALDataType dtype, char **options) { godalWrap(ctx); diff --git a/godal.go b/godal.go index 4587758..b53fcfa 100644 --- a/godal.go +++ b/godal.go @@ -1253,10 +1253,22 @@ func RegisterAll() { C.GDALAllRegister() } -func GDALRegisterPlugins() { +func RegisterPlugins() { C.godalRegisterPlugins() } +func RegisterPlugin(name string, opts ...RegisterPluginOption) error { + ro := registerPluginOpts{} + for _, o := range opts { + o.setRegisterPluginOpt(&ro) + } + cgc := createCGOContext(nil, ro.errorHandler) + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + C.godalRegisterPlugin(cgc.cPointer(), cname) + return cgc.close() +} + // RegisterRaster registers a raster driver by name. // // Calling RegisterRaster(DriverName) with one of the predefined DriverNames provided by the library will diff --git a/godal.h b/godal.h index 31367ce..d586bd9 100644 --- a/godal.h +++ b/godal.h @@ -48,6 +48,7 @@ extern "C" { void godalClose(cctx *ctx, GDALDatasetH ds); int godalRegisterDriver(const char *funcname); void godalRegisterPlugins(); + void godalRegisterPlugin(cctx *ctx, const char *name); void godalRasterSize(GDALDatasetH ds, int *xsize, int *ysize); //returns a null terminated list of bands. the caller must free the returned list diff --git a/godal_test.go b/godal_test.go index e9f8bfd..2938e18 100644 --- a/godal_test.go +++ b/godal_test.go @@ -264,6 +264,24 @@ func TestRegisterDrivers(t *testing.T) { assert.True(t, ok) _, ok = VectorDriver("Mapinfo File") assert.True(t, ok) + + runtimeVersion := Version() + supported := runtimeVersion.Major() > 3 || + (runtimeVersion.Major() == 3 && runtimeVersion.Minor() >= 8) + + ehc := eh() + err = RegisterPlugin("foobarsljgsa", ErrLogger(ehc.ErrorHandler)) + assert.Error(t, err) + if !supported { + assert.Contains(t, err.Error(), "GDALRegisterPlugin is only supported") + } + err = RegisterPlugin("foobarsljgsa") + assert.Error(t, err) + err = RegisterPlugin("dehazer") + assert.NoError(t, err) + + //smoke test for RegisterPlugins + RegisterPlugins() } func TestVectorCreate(t *testing.T) { diff --git a/options.go b/options.go index 7446308..8e9aba5 100644 --- a/options.go +++ b/options.go @@ -1254,6 +1254,15 @@ type NearblackOption interface { setNearblackOpt(nbOpt *nearBlackOpts) } +type registerPluginOpts struct { + errorHandler ErrorHandler +} + +// RegisterPluginOption is an option that can be passed to RegisterPlugin() +type RegisterPluginOption interface { + setRegisterPluginOpt(rpOpt *registerPluginOpts) +} + // RasterizeGeometryOption is an option that can be passed tp Dataset.RasterizeGeometry() type RasterizeGeometryOption interface { setRasterizeGeometryOpt(o *rasterizeGeometryOpts)