mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-21 08:39:46 +08:00
3ffe7be446
re: Discussion https://github.com/Unidata/netcdf-c/discussions/2214 The primary change is to support so-called "standard filters". A standard filter is one that is defined by the following netcdf-c API: ```` int nc_def_var_XXX(int ncid, int varid, size_t nparams, unsigned* params); int nc_inq_var_XXXX(int ncid, int varid, int* usefilterp, unsigned* params); ```` So for example, zstandard would be a standard filter by defining the functions *nc_def_var_zstandard* and *nc_inq_var_zstandard*. In order to define these functions, we need a new dispatch function: ```` int nc_inq_filter_avail(int ncid, unsigned filterid); ```` This function, combined with the existing filter API can be used to implement arbitrary standard filters using a simple code pattern. Note that I would have preferred that this function return a list of all available filters, but HDF5 does not support that functionality. So this PR implements the dispatch function and implements the following standard functions: + bzip2 + zstandard + blosc Specific test cases are also provided for HDF5 and NCZarr. Over time, other specific standard filters will be defined. ## Primary Changes * Add nc_inq_filter_avail() to netcdf-c API. * Add standard filter implementations to test use of *nc_inq_filter_avail*. * Bump the dispatch table version number and add to all the relevant dispatch tables (libsrc, libsrcp, etc). * Create a program to invoke nc_inq_filter_avail so that it is accessible to shell scripts. * Cleanup szip support to properly support szip when HDF5 is disabled. This involves detecting libsz separately from testing if HDF5 supports szip. * Integrate shuffle and fletcher32 into the existing filter API. This means that, for example, nc_def_var_fletcher32 is now a wrapper around nc_def_var_filter. * Extend the Codec defaulting to allow multiple default shared libraries. ## Misc. Changes * Modify configure.ac/CMakeLists.txt to look for the relevant libraries implementing standard filters. * Modify libnetcdf.settings to list available standard filters (including deflate and szip). * Add CMake test modules to locate libbz2 and libzstd. * Cleanup the HDF5 memory manager function use in the plugins. * remove unused file include//ncfilter.h * remove tests for the HDF5 memory operations e.g. H5allocate_memory. * Add flag to ncdump to force use of _Filter instead of _Deflate or _Shuffle or _Fletcher32. Used for testing.
1029 lines
24 KiB
C
1029 lines
24 KiB
C
/*********************************************************************
|
|
* Copyright 2018, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*********************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
#if defined(_WIN32) || defined(_WIN64)
|
|
#include <crtdbg.h>
|
|
#include <direct.h>
|
|
#endif
|
|
#include "ncd4dispatch.h"
|
|
#include "nc4internal.h"
|
|
#include "d4includes.h"
|
|
#include "d4curlfunctions.h"
|
|
|
|
#ifdef HAVE_GETRLIMIT
|
|
# ifdef HAVE_SYS_RESOURCE_H
|
|
# include <sys/time.h>
|
|
# endif
|
|
# ifdef HAVE_SYS_RESOURCE_H
|
|
# include <sys/resource.h>
|
|
# endif
|
|
#endif
|
|
|
|
#if 0
|
|
/* Define the set of protocols known to be constrainable */
|
|
static char* constrainableprotocols[] = {"http", "https",NULL};
|
|
#endif
|
|
|
|
static int ncd4initialized = 0;
|
|
|
|
static const NC_Dispatch NCD4_dispatch_base;
|
|
|
|
const NC_Dispatch* NCD4_dispatch_table = NULL; /* moved here from ddispatch.c */
|
|
|
|
/**************************************************/
|
|
/* Define a structure defining reserved attributes */
|
|
|
|
/** @internal List of reserved attributes. */
|
|
static const NC_reservedatt NCD4_reserved[] = {
|
|
{D4CHECKSUMATTR, READONLYFLAG|NAMEONLYFLAG}, /*_DAP4_Checksum_CRC32*/
|
|
{D4LEATTR, READONLYFLAG|NAMEONLYFLAG}, /*_DAP4_Little_Endian*/
|
|
/* Also need to include the provenance attributes */
|
|
{NCPROPS, READONLYFLAG|NAMEONLYFLAG|MATERIALIZEDFLAG}, /*_NCProperties*/
|
|
{NULL, 0}
|
|
};
|
|
|
|
/* Forward */
|
|
static int globalinit(void);
|
|
static int ncd4_get_att_reserved(NC* ncp, int ncid, int varid, const char* name, void* value, nc_type t, const NC_reservedatt* rsvp);
|
|
static int ncd4_inq_att_reserved(NC* ncp, int ncid, int varid, const char* name, nc_type* xtypep, size_t* lenp, const NC_reservedatt* rsvp);
|
|
|
|
|
|
/**************************************************/
|
|
int
|
|
NCD4_initialize(void)
|
|
{
|
|
NCD4_dispatch_table = &NCD4_dispatch_base;
|
|
ncd4initialized = 1;
|
|
ncloginit();
|
|
#ifdef D4DEBUG
|
|
/* force logging to go to stderr */
|
|
nclogclose();
|
|
if(nclogopen(NULL))
|
|
ncsetlogging(1); /* turn it on */
|
|
#endif
|
|
/* Init global state */
|
|
globalinit();
|
|
|
|
return THROW(NC_NOERR);
|
|
}
|
|
|
|
int
|
|
NCD4_finalize(void)
|
|
{
|
|
return THROW(NC_NOERR);
|
|
}
|
|
|
|
static int
|
|
NCD4_redef(int ncid)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align)
|
|
{
|
|
return (NC_NOERR); /* let it go */
|
|
}
|
|
|
|
static int
|
|
NCD4_sync(int ncid)
|
|
{
|
|
return (NC_NOERR); /* let it go */
|
|
}
|
|
|
|
static int
|
|
NCD4_create(const char *path, int cmode,
|
|
size_t initialsz, int basepe, size_t *chunksizehintp,
|
|
void* mpidata, const NC_Dispatch *dispatch, int ncid)
|
|
{
|
|
return THROW(NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_put_vara(int ncid, int varid,
|
|
const size_t *start, const size_t *edges,
|
|
const void *value,
|
|
nc_type memtype)
|
|
{
|
|
return THROW(NC_EPERM);
|
|
}
|
|
|
|
|
|
static int
|
|
NCD4_put_vars(int ncid, int varid,
|
|
const size_t *start, const size_t *edges, const ptrdiff_t* stride,
|
|
const void *value0, nc_type memtype)
|
|
{
|
|
return THROW(NC_EPERM);
|
|
}
|
|
|
|
/*
|
|
Force dap4 access to be read-only
|
|
*/
|
|
static int
|
|
NCD4_set_fill(int ncid, int fillmode, int* old_modep)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_dim(int ncid, const char* name, size_t len, int* idp)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_put_att(int ncid, int varid, const char* name, nc_type datatype,
|
|
size_t len, const void* value, nc_type t)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var(int ncid, const char *name,
|
|
nc_type xtype, int ndims, const int *dimidsp, int *varidp)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_grp(int ncid, const char* p2, int* p3)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_rename_grp(int ncid, const char* p)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_compound(int ncid, size_t p2, const char* p3, nc_type* t)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_insert_compound(int ncid, nc_type t1, const char* p3, size_t p4, nc_type t2)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_insert_array_compound(int ncid, nc_type t1, const char* p3, size_t p4,
|
|
nc_type t2, int p6, const int* p7)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
|
|
static int
|
|
NCD4_def_vlen(int ncid, const char* p2, nc_type base_typeid, nc_type* t)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_put_vlen_element(int ncid, int p2, void* p3, size_t p4, const void* p5)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_enum(int ncid, nc_type t1, const char* p3, nc_type* t)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_insert_enum(int ncid, nc_type t1, const char* p3, const void* p4)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_opaque(int ncid, size_t p2, const char* p3, nc_type* t)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var_deflate(int ncid, int p2, int p3, int p4, int p5)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var_fletcher32(int ncid, int p2, int p3)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var_chunking(int ncid, int p2, int p3, const size_t* p4)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var_fill(int ncid, int p2, int p3, const void* p4)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var_endian(int ncid, int p2, int p3)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_def_var_filter(int ncid, int varid, unsigned int id, size_t n, const unsigned int* parms)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
static int
|
|
NCD4_set_var_chunk_cache(int ncid, int p2, size_t p3, size_t p4, float p5)
|
|
{
|
|
return (NC_EPERM);
|
|
}
|
|
|
|
/**************************************************/
|
|
/*
|
|
Following functions basically return the netcdf-4 value WRT to the nc4id.
|
|
However, it is necessary to modify the grpid(ncid) to point to the substrate.
|
|
*/
|
|
|
|
static int
|
|
NCD4_inq_format(int ncid, int* formatp)
|
|
{
|
|
NC* ncp;
|
|
int ret = NC_NOERR;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_format(substrateid, formatp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq(int ncid, int* ndimsp, int* nvarsp, int* nattsp, int* unlimdimidp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq(substrateid, ndimsp, nvarsp, nattsp, unlimdimidp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_type(int ncid, nc_type p2, char* p3, size_t* p4)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_type(substrateid, p2, p3, p4);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_dimid(int ncid, const char* name, int* idp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_dimid(substrateid, name, idp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_unlimdim(int ncid, int* unlimdimidp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_unlimdim(substrateid, unlimdimidp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_rename_dim(int ncid, int dimid, const char* name)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_rename_dim(substrateid, dimid, name);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_att(int ncid, int varid, const char* name,
|
|
nc_type* xtypep, size_t* lenp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
const NC_reservedatt* rsvp = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
|
|
/* Is this a reserved attribute name? */
|
|
if(name && (rsvp = NCD4_lookupreserved(name)))
|
|
return ncd4_inq_att_reserved(ncp,ncid,varid,name,xtypep,lenp, rsvp);
|
|
ret = nc_inq_att(substrateid, varid, name, xtypep, lenp);
|
|
return (ret);
|
|
}
|
|
|
|
const struct NC_reservedatt*
|
|
NCD4_lookupreserved(const char* name)
|
|
{
|
|
const NC_reservedatt* p = NCD4_reserved;
|
|
for(;p->name;p++) {
|
|
if(strcmp(name,p->name)==0)
|
|
return p;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_attid(int ncid, int varid, const char *name, int *idp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
const NC_reservedatt* rsvp = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
/* Is this a reserved attribute name? */
|
|
if(name && (rsvp = NCD4_lookupreserved(name)))
|
|
return NC_EATTMETA;
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_attid(substrateid, varid, name, idp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_attname(int ncid, int varid, int attnum, char* name)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
const NC_reservedatt* rsvp = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
/* Is this a reserved attribute name? */
|
|
if(name && (rsvp = NCD4_lookupreserved(name)))
|
|
return NC_EATTMETA;
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_attname(substrateid, varid, attnum, name);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_rename_att(int ncid, int varid, const char* name, const char* newname)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
const NC_reservedatt* rsvp = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
/* Is this a reserved attribute name? */
|
|
if(name && (rsvp = NCD4_lookupreserved(name)))
|
|
return NC_EATTMETA;
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_rename_att(substrateid, varid, name, newname);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_del_att(int ncid, int varid, const char* name)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
const NC_reservedatt* rsvp = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
/* Is this a reserved attribute name? */
|
|
if(name && (rsvp = NCD4_lookupreserved(name)))
|
|
return NC_EATTMETA;
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_del_att(substrateid, varid, name);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_get_att(int ncid, int varid, const char* name, void* value, nc_type t)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
const NC_reservedatt* rsvp = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
/* Is this a reserved attribute name? */
|
|
if(name && (rsvp = NCD4_lookupreserved(name)))
|
|
return ncd4_get_att_reserved(ncp,ncid,varid,name,value,t,rsvp);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = NCDISPATCH_get_att(substrateid, varid, name, value, t);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_var_all(int ncid, int varid, char *name, nc_type* xtypep,
|
|
int* ndimsp, int* dimidsp, int* nattsp,
|
|
int* shufflep, int* deflatep, int* deflate_levelp,
|
|
int* fletcher32p, int* contiguousp, size_t* chunksizesp,
|
|
int* no_fill, void* fill_valuep, int* endiannessp,
|
|
unsigned int* idp, size_t* nparamsp, unsigned int* params
|
|
)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = NCDISPATCH_inq_var_all(substrateid, varid, name, xtypep,
|
|
ndimsp, dimidsp, nattsp,
|
|
shufflep, deflatep, deflate_levelp,
|
|
fletcher32p, contiguousp, chunksizesp,
|
|
no_fill, fill_valuep, endiannessp,
|
|
idp, nparamsp, params);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_varid(int ncid, const char *name, int *varidp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_varid(substrateid,name,varidp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_rename_var(int ncid, int varid, const char* name)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_rename_var(substrateid, varid, name);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_var_par_access(int ncid, int p2, int p3)
|
|
{
|
|
return (NC_ENOPAR);
|
|
}
|
|
|
|
|
|
static int
|
|
NCD4_inq_ncid(int ncid, const char* name, int* grp_ncid)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_ncid(substrateid, name, grp_ncid);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_show_metadata(int ncid)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_show_metadata(substrateid);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_grps(int ncid, int* ngrpsp, int* grpids)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
int ngrps;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
/* We always need to know |grpids| */
|
|
ret = nc_inq_grps(substrateid, &ngrps, grpids);
|
|
if(ret == NC_NOERR) {
|
|
if(ngrpsp != NULL)
|
|
*ngrpsp = ngrps; /* return if caller want it */
|
|
if(grpids != NULL) {
|
|
int i;
|
|
/* We need to convert the substrate group ids to dap4 group ids */
|
|
for(i=0;i<ngrps;i++)
|
|
grpids[i] = makedap4id(ncp,grpids[i]);
|
|
}
|
|
}
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_grpname(int ncid, char* p)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_grpname(substrateid, p);
|
|
return (ret);
|
|
}
|
|
|
|
|
|
static int
|
|
NCD4_inq_unlimdims(int ncid, int* p2, int* p3)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_unlimdims(substrateid, p2, p3);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_grpname_full(int ncid, size_t* p2, char* p3)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_grpname_full(substrateid, p2, p3);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_grp_parent(int ncid, int* p)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_grp_parent(substrateid, p);
|
|
if(p != NULL)
|
|
*p = makedap4id(ncp,*p);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_grp_full_ncid(int ncid, const char* fullname, int* grpidp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_grp_full_ncid(substrateid, fullname, grpidp);
|
|
if(grpidp != NULL)
|
|
*grpidp = makedap4id(ncp,*grpidp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_varids(int ncid, int* nvars, int* p)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_varids(substrateid, nvars, p);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_dimids(int ncid, int* ndims, int* p3, int p4)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_dimids(substrateid, ndims, p3, p4);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_typeids(int ncid, int* ntypes, int* p)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_typeids(substrateid, ntypes, p);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_type_equal(int ncid, nc_type t1, int p3, nc_type t2, int* p5)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_type_equal(substrateid, t1, p3, t2, p5);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_user_type(int ncid, nc_type t, char* p3, size_t* p4, nc_type* p5,
|
|
size_t* p6, int* p7)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_user_type(substrateid, t, p3, p4, p5, p6, p7);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_typeid(int ncid, const char* name, nc_type* t)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_typeid(substrateid, name, t);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name,
|
|
size_t *offsetp, nc_type* field_typeidp, int *ndimsp,
|
|
int *dim_sizesp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_compound_field(substrateid, xtype, fieldid, name, offsetp, field_typeidp, ndimsp, dim_sizesp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name,
|
|
int *fieldidp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_compound_fieldindex(substrateid, xtype, name, fieldidp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_get_vlen_element(int ncid, int p2, const void* p3, size_t* p4, void* p5)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_get_vlen_element(substrateid, p2, p3, p4, p5);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_enum_member(int ncid, nc_type t1, int p3, char* p4, void* p5)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_enum_member(substrateid, t1, p3, p4, p5);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_enum_ident(int ncid, nc_type t1, long long p3, char* p4)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_enum_ident(substrateid, t1, p3, p4);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_get_var_chunk_cache(int ncid, int p2, size_t* p3, size_t* p4, float* p5)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_get_var_chunk_cache(substrateid, p2, p3, p4, p5);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_var_quantize(int ncid, int varid, int *quantize_modep, int *nsdp)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_var_quantize(substrateid, varid, quantize_modep, nsdp);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_var_filter_ids(int ncid, int varid, size_t* nfilters, unsigned int* filterids)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_var_filter_ids(substrateid, varid, nfilters, filterids);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_var_filter_info(int ncid, int varid, unsigned int id, size_t* nparams, unsigned int* params)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_var_filter_info(substrateid, varid, id, nparams, params);
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
NCD4_inq_filter_avail(int ncid, unsigned id)
|
|
{
|
|
NC* ncp;
|
|
int ret;
|
|
int substrateid;
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR) return (ret);
|
|
substrateid = makenc4id(ncp,ncid);
|
|
ret = nc_inq_filter_avail(substrateid, id);
|
|
return (ret);
|
|
}
|
|
|
|
/**************************************************/
|
|
/*
|
|
Following functions are overridden to handle
|
|
dap4 implementation specific issues.
|
|
*/
|
|
|
|
/* Force specific format */
|
|
static int
|
|
NCD4_inq_format_extended(int ncid, int* formatp, int* modep)
|
|
{
|
|
NC* nc;
|
|
int ncstatus = NC_check_id(ncid, (NC**)&nc);
|
|
if(ncstatus != NC_NOERR) return (ncstatus);
|
|
if(modep) *modep = nc->mode;
|
|
if(formatp) *formatp = NC_FORMATX_DAP4;
|
|
return THROW(NC_NOERR);
|
|
}
|
|
|
|
/*
|
|
Override nc_inq_dim to handle the fact
|
|
that unlimited dimensions will not have
|
|
a proper size because the substrate has
|
|
never (not yet) been written.
|
|
*/
|
|
int
|
|
NCD4_inq_dim(int ncid, int dimid, char* name, size_t* lenp)
|
|
{
|
|
int ret = NC_NOERR;
|
|
NC* ncp;
|
|
NCD4INFO* info;
|
|
NCD4meta* meta;
|
|
int i;
|
|
NCD4node* dim = NULL;
|
|
|
|
if((ret = NC_check_id(ncid, (NC**)&ncp)) != NC_NOERR)
|
|
goto done;
|
|
info = (NCD4INFO*)ncp->dispatchdata;
|
|
meta = info->substrate.metadata;
|
|
|
|
/* Locate the dimension specified by dimid */
|
|
for(i=0;i<nclistlength(meta->allnodes);i++) {
|
|
NCD4node* n = (NCD4node*)nclistget(meta->allnodes,i);
|
|
if(n->sort == NCD4_DIM && n->meta.id == dimid) {
|
|
dim = n;
|
|
break;
|
|
}
|
|
}
|
|
if(dim == NULL)
|
|
{ret = NC_EBADDIM; goto done;}
|
|
if(name)
|
|
strncpy(name,dim->name,NC_MAX_NAME);
|
|
if(lenp)
|
|
*lenp = (size_t)dim->dim.size;
|
|
done:
|
|
return (ret);
|
|
}
|
|
|
|
static int
|
|
ncd4_get_att_reserved(NC* ncp, int ncid, int varid, const char* name, void* value, nc_type t, const NC_reservedatt* rsvp)
|
|
{
|
|
int ret = NC_NOERR;
|
|
NCD4INFO* info = (NCD4INFO*)(ncp->dispatchdata);
|
|
NCD4meta* meta = info->substrate.metadata;
|
|
NCD4node* var = NULL;
|
|
|
|
if(strcmp(rsvp->name,D4CHECKSUMATTR)==0) {
|
|
unsigned int* ip = (unsigned int*)value;
|
|
if(varid == NC_GLOBAL)
|
|
{ret = NC_EBADID; goto done;}
|
|
if(t != NC_UINT) {ret = NC_EBADTYPE; goto done;}
|
|
if((ret=NCD4_findvar(ncp,ncid,varid,&var,NULL))) goto done;
|
|
if(var->data.remotechecksummed == 0)
|
|
{ret = NC_ENOTATT; goto done;}
|
|
*ip = (var->data.remotechecksum);
|
|
} else if(strcmp(rsvp->name,D4LEATTR)==0) {
|
|
int* ip = (int*)value;
|
|
if(varid != NC_GLOBAL)
|
|
{ret = NC_EBADID; goto done;}
|
|
if(t != NC_INT) {ret = NC_EBADTYPE; goto done;}
|
|
*ip = (meta->serial.remotelittleendian?1:0);
|
|
}
|
|
done:
|
|
return THROW(ret);
|
|
}
|
|
|
|
static int
|
|
ncd4_inq_att_reserved(NC* ncp, int ncid, int varid, const char* name, nc_type* xtypep, size_t* lenp, const NC_reservedatt* rsvp)
|
|
{
|
|
int ret = NC_NOERR;
|
|
NCD4node* var = NULL;
|
|
|
|
if(strcmp(rsvp->name,D4CHECKSUMATTR)==0) {
|
|
if(varid == NC_GLOBAL)
|
|
{ret = NC_EBADID; goto done;}
|
|
if((ret=NCD4_findvar(ncp,ncid,varid,&var,NULL))) goto done;
|
|
if(var->data.remotechecksummed == 0)
|
|
{ret = NC_ENOTATT; goto done;}
|
|
if(xtypep) *xtypep = NC_UINT;
|
|
if(lenp) *lenp = 1;
|
|
} else if(strcmp(rsvp->name,D4LEATTR)==0) {
|
|
if(varid != NC_GLOBAL)
|
|
{ret = NC_EBADID; goto done;}
|
|
if(xtypep) *xtypep = NC_INT;
|
|
if(lenp) *lenp = 1;
|
|
}
|
|
done:
|
|
return THROW(ret);
|
|
}
|
|
|
|
/**************************************************/
|
|
|
|
static int
|
|
globalinit(void)
|
|
{
|
|
int stat = NC_NOERR;
|
|
return stat;
|
|
}
|
|
|
|
/**************************************************/
|
|
|
|
static const NC_Dispatch NCD4_dispatch_base = {
|
|
|
|
NC_FORMATX_DAP4,
|
|
NC_DISPATCH_VERSION,
|
|
|
|
NCD4_create,
|
|
NCD4_open,
|
|
|
|
NCD4_redef,
|
|
NCD4__enddef,
|
|
NCD4_sync,
|
|
NCD4_abort,
|
|
NCD4_close,
|
|
NCD4_set_fill,
|
|
NCD4_inq_format,
|
|
NCD4_inq_format_extended, /*inq_format_extended*/
|
|
|
|
NCD4_inq,
|
|
NCD4_inq_type,
|
|
|
|
NCD4_def_dim,
|
|
NCD4_inq_dimid,
|
|
NCD4_inq_dim,
|
|
NCD4_inq_unlimdim,
|
|
NCD4_rename_dim,
|
|
|
|
NCD4_inq_att,
|
|
NCD4_inq_attid,
|
|
NCD4_inq_attname,
|
|
NCD4_rename_att,
|
|
NCD4_del_att,
|
|
NCD4_get_att,
|
|
NCD4_put_att,
|
|
|
|
NCD4_def_var,
|
|
NCD4_inq_varid,
|
|
NCD4_rename_var,
|
|
NCD4_get_vara,
|
|
NCD4_put_vara,
|
|
NCD4_get_vars,
|
|
NCD4_put_vars,
|
|
NCDEFAULT_get_varm,
|
|
NCDEFAULT_put_varm,
|
|
|
|
NCD4_inq_var_all,
|
|
|
|
NCD4_var_par_access,
|
|
NCD4_def_var_fill,
|
|
|
|
NCD4_show_metadata,
|
|
NCD4_inq_unlimdims,
|
|
NCD4_inq_ncid,
|
|
NCD4_inq_grps,
|
|
NCD4_inq_grpname,
|
|
NCD4_inq_grpname_full,
|
|
NCD4_inq_grp_parent,
|
|
NCD4_inq_grp_full_ncid,
|
|
NCD4_inq_varids,
|
|
NCD4_inq_dimids,
|
|
NCD4_inq_typeids,
|
|
NCD4_inq_type_equal,
|
|
NCD4_def_grp,
|
|
NCD4_rename_grp,
|
|
NCD4_inq_user_type,
|
|
NCD4_inq_typeid,
|
|
|
|
NCD4_def_compound,
|
|
NCD4_insert_compound,
|
|
NCD4_insert_array_compound,
|
|
NCD4_inq_compound_field,
|
|
NCD4_inq_compound_fieldindex,
|
|
NCD4_def_vlen,
|
|
NCD4_put_vlen_element,
|
|
NCD4_get_vlen_element,
|
|
NCD4_def_enum,
|
|
NCD4_insert_enum,
|
|
NCD4_inq_enum_member,
|
|
NCD4_inq_enum_ident,
|
|
NCD4_def_opaque,
|
|
NCD4_def_var_deflate,
|
|
NCD4_def_var_fletcher32,
|
|
NCD4_def_var_chunking,
|
|
NCD4_def_var_endian,
|
|
NCD4_def_var_filter,
|
|
NCD4_set_var_chunk_cache,
|
|
NCD4_get_var_chunk_cache,
|
|
|
|
NCD4_inq_var_filter_ids,
|
|
NCD4_inq_var_filter_info,
|
|
|
|
NC_NOTNC4_def_var_quantize,
|
|
NCD4_inq_var_quantize,
|
|
|
|
NCD4_inq_filter_avail,
|
|
};
|