modified libdap to use a new metadata handling mechanism

This commit is contained in:
Dennis Heimbigner 2011-09-18 21:41:38 +00:00
commit 79ebcb38b8
39 changed files with 2174 additions and 1204 deletions

View File

@ -566,9 +566,6 @@ AC_FUNC_VPRINTF
# Check for <stdbool.h> that conforms to C99 requirements
AC_HEADER_STDBOOL
AC_CHECK_FUNCS([mktime])
AC_CHECK_FUNCS([strptime])
# Check for these functions...
AC_CHECK_FUNCS([strlcat strerror snprintf strchr strrchr mktemp strcat strcpy strdup \
strcasecmp strtod strtoll strtoull getrlimit gettimeofday fsync MPI_Comm_f2c])

View File

@ -10,7 +10,11 @@ if BUILD_PARALLEL
include_HEADERS += netcdf_par.h
endif
noinst_HEADERS = nc_logging.h nc_tests.h fbits.h nc3dispatch.h nc.h \
noinst_HEADERS = nc_logging.h nc_tests.h fbits.h nc.h \
ncio.h nclist.h nc_uri.h utf8proc.h ncdispatch.h ncdimscale.h \
netcdf_f.h err_macros.h ncbytes.h nchashmap.h ceconstraints.h rnd.h \
nclog.h ncconfigure.h nc4internal.h ncaux.h
nclog.h ncconfigure.h nc4internal.h nctime.h nc3dispatch.h
if USE_NETCDF4
noinst_HEADERS += ncaux.h
endif

View File

@ -256,18 +256,19 @@ typedef short int shmem_t;
#endif
/* Warning: fields from BEGIN COMMON to END COMMON must be same for:
1. NC (libsrc/nc.h)
2. NC_FILE_INFO (libsrc4/nc4internal.h)
3. NCDAP3 (libncdap3/ncdap3.h)
4. NCDAP4 (libncdap4/ncdap4.h)
1. NCcommon (include/ncdispatch.h)
2. NC (libsrc/nc.h)
3. NC_FILE_INFO (libsrc4/nc4internal.h)
4. whatever libdiskless uses
*/
struct NC {
/*BEGIN COMMON*/
int ext_ncid; /* uid << 16 */
int int_ncid; /* unspecified other id */
/*BEGIN COMMON (see include/ncdispatch.h: struct NCcommon) */
int ext_ncid;
int int_ncid;
struct NC_Dispatch* dispatch;
struct NC_Dispatch3* dapdispatch;
char* path; /* as specified at open or create */
void* dispatchdata;
char* path;
int substrate;
/*END COMMON*/
/* contains the previous NC during redef. */
struct NC *old;

View File

@ -286,10 +286,10 @@ typedef struct
* group (i.e. group zero). */
/* Warning: fields from BEGIN COMMON to END COMMON must be same for:
1. NC (libsrc/nc.h)
2. NC_FILE_INFO (libsrc4/nc4internal.h)
3. NCDAP3 (libncdap3/ncdap3.h)
4. NCDAP4 (libncdap4/ncdap4.h)
1. NCcommon (include/ncdispatch.h)
2. NC (libsrc/nc.h)
3. NC_FILE_INFO (libsrc4/nc4internal.h)
4. whatever libdiskless uses
*/
typedef struct NC_FILE_INFO
{
@ -297,8 +297,9 @@ typedef struct NC_FILE_INFO
int ext_ncid;
int int_ncid;
struct NC_Dispatch* dispatch;
struct NC_Dispatch4* dapdispatch;
void* dispatchdata;
char* path;
int substrate;
/*END COMMON*/
#ifdef USE_PNETCDF

View File

@ -11,7 +11,6 @@
#define NCAUX_ALIGN_C 0
#define NCAUX_ALIGN_UNIFORM 1
#ifdef USE_NETCDF4
extern int ncaux_begin_compound(int ncid, const char *name, int alignmode,
void** tag);
@ -21,7 +20,6 @@ extern int ncaux_abort_compound(void* tag);
extern int ncaux_add_field(void* tag, const char *name, nc_type field_type,
int ndims, const int* dimsizes);
#endif /*USE_NETCDF4*/
#endif /*NCAUX_H*/

View File

@ -118,27 +118,39 @@ typedef struct NC_MPI_INFO {
} NC_MPI_INFO;
#endif
/* Define known dispatch tables */
/* Define known dispatch tables and initializers */
/*Forward*/
typedef struct NC_Dispatch NC_Dispatch;
extern NC_Dispatch* NCSUBSTRATE_dispatch_table;
extern int NCDISPATCH_initialize(void);
extern NC_Dispatch* NC3_dispatch_table;
extern int NC3_initialize(void);
/* Diskless */
extern NC_Dispatch* NCD_dispatch_table;
extern int NCD_initialize(void);
#ifdef USE_NETCDF4
extern NC_Dispatch* NC4_dispatch_table;
extern int NC4_initialize(void);
#endif
#ifdef USE_DAP
extern NC_Dispatch* NCD3_dispatch_table;
extern int NCD3_initialize(void);
#endif
#if defined(USE_DAP) && defined(USE_NETCDF4)
extern NC_Dispatch* NCD4_dispatch_table;
extern int NCD4_initialize(void);
#endif
#if defined(USE_CDMREMOTE) && defined(USE_NETCDF4)
extern NC_Dispatch* NCCR_dispatch_table;
extern int NCCR_initialize(void);
#endif
/**************************************************/
@ -318,9 +330,9 @@ typedef struct NCcommon {
int ext_ncid; /* uid << 16 */
int int_ncid; /* unspecified other id */
struct NC_Dispatch* dispatch;
#ifdef USE_DAP
struct NCDRNO* drno;
#endif
void* dispatchdata; /* per-protocol instance data */
char* path; /* as specified at open or create */
int substrate; /* ncid for another protocol on which to build */
} NCcommon;
extern int NC_atomictypelen(nc_type xtype);

View File

@ -14,11 +14,6 @@ struct bounds_node{
typedef struct bounds_node bounds_node_t;
static struct {
size_t nbnds; /* number of bounds variables */
bounds_node_t *first;
} bounds_list;
/*
* This code was extracted with permission from the CDMS time
* conversion and arithmetic routines developed by Bob Drach, Lawrence
@ -139,7 +134,8 @@ typedef struct timeinfo_t {
} timeinfo_t;
extern void cdRel2Iso(cdCalenType timetype, char* relunits, int separator, double reltime, char* chartime);
extern void insert_bounds_info(int ncid, int varid, ncatt_t att);
extern boolean is_bounds_att(ncatt_t *attp);
extern void get_timeinfo(int ncid, int varid, ncvar_t *vp);
extern void print_att_times(int ncid, int varid, ncatt_t att);
extern void cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime);
extern void Cdh2e(CdTime *htime, double *etime);
extern void Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime);
extern int cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTime* base_comptime);

View File

@ -16,7 +16,7 @@
#endif
/* Mnemonic */
#define getncid(drno) (((NC*)drno)->ext_ncid)
#define getncid(nccr) (((NC*)(nccr->controller)->ext_ncid)
extern NC_FILE_INFO_T* nc_file;
@ -29,6 +29,7 @@ static int nccr_collect_projection_variables(NCCDMR* cdmr);
static int nccr_mark_visible(NCCDMR* cdmr);
/**************************************************/
#ifdef NOTUSED
int
NCCR_new_nc(NC** ncpp)
{
@ -39,6 +40,7 @@ NCCR_new_nc(NC** ncpp)
if(ncpp) *ncpp = (NC*)ncp;
return NC_NOERR;
}
#endif
/**************************************************/
/* See ncd4dispatch.c for other version */
@ -47,10 +49,9 @@ NCCR_open(const char * path, int mode,
int basepe, size_t *chunksizehintp,
int useparallel, void* mpidata,
NC_Dispatch* dispatch, NC** ncpp)
{
NCerror ncstat = NC_NOERR;
NC_URI* tmpurl;
NCCR* nccr = NULL; /* reuse the ncdap3 structure*/
NC_FILE_INFO_T* drno = NULL; /* reuse the nc4 structure*/
NCCDMR* cdmr = NULL;
NC_HDF5_FILE_INFO_T* h5 = NULL;
NC_GRP_INFO_T *grp = NULL;
@ -84,11 +85,12 @@ NCCR_open(const char * path, int mode,
/* Now, use the file to create the hdf5 file */
ncstat = NC4_create(tmpname,NC_NETCDF4|NC_CLOBBER,
0,0,NULL,0,NULL,dispatch,(NC**)&nccr);
ncid = nccr->info.ext_ncid;
ncid = nccr->ext_ncid;
/* unlink the temp file so it will automatically be reclaimed */
unlink(tmpname);
free(tmpname);
/* Avoid fill */
dispatch->set_fill(ncid,NC_NOFILL,NULL);
if(ncstat)
{THROWCHK(ncstat); goto done;}
@ -98,6 +100,7 @@ NCCR_open(const char * path, int mode,
{THROWCHK(ncstat); goto done;}
/* Setup tentative NCCR state*/
??? nccr->
nccr->info.dispatch = dispatch;
cdmr = (NCCDMR*)calloc(1,sizeof(NCCDMR));
if(cdmr == NULL) {ncstat = NC_ENOMEM; goto done;}

View File

@ -57,10 +57,12 @@ typedef struct NCCDMR {
typedef struct NCCURLSTATE NCCURLSTATE;
#ifdef NOTUSED
typedef struct NCCR {
NC_FILE_INFO_T info;
NCCDMR* cdmr;
} NCCR;
#endif
/**************************************************/
/* Define various flags (powers of 2)*/
@ -81,7 +83,7 @@ struct NClist;
extern int nccrceparse(char*, int, struct NClist**, struct NClist**, char**);
extern int crbuildnc(NCCR*, struct Header*);
extern int crbuildnc(NCCDMR*, struct Header*);
/**********************************************************/
#endif /*NCCR_H*/

View File

@ -229,8 +229,9 @@ cpp::
##################################################
# ncd
NCDUMPC=../ncdump/dumplib.c ../ncdump/indent.c ../ncdump/ncdump.c ../ncdump/nctime.c ../ncdump/vardata.c ../ncdump/utils.c
NCDUMPH=../ncdump/cdl.h ../ncdump/dumplib.h ../ncdump/indent.h ../ncdump/isnan.h ../ncdump/ncdump.h ../ncdump/nctime.h ../ncdump/vardata.h ../ncdump/utils.h
NCDUMPC=../ncdump/dumplib.c ../ncdump/indent.c ../ncdump/ncdump.c ../ncdump/nctime0.c ../ncdump/vardata.c ../ncdump/utils.c
NCDUMPH=../ncdump/cdl.h ../ncdump/dumplib.h ../ncdump/indent.h ../ncdump/isnan.h ../ncdump/ncdump.h ../ncdump/nctime0.h ../ncdump/vardata.h ../ncdump/utils.h
NCDUMPOBJ=${NCDUMPC:../ncdump/%.c=%.o}
#${NCDUMPC} ${NCDUMPH} ${NCLIB}

View File

@ -26,16 +26,10 @@ static NCerror testregrid3(CDFnode* node, CDFnode* template, NClist*);
static CDFnode* makenewstruct3(CDFnode* node, CDFnode* template);
static NCerror regridinsert(CDFnode* newgrid, CDFnode* node);
static NCerror regridremove(CDFnode* newgrid, CDFnode* node);
static void projection3r(CDFnode*);
static void unprojected3(NClist* nodes);
static void projectall3(NClist* nodes);
#ifdef DDSNEW
static NCerror mapnodes3r(CDFnode*, CDFnode*, int depth);
static NCerror mapdims3(CDFnode*, CDFnode*);
#else
static NCerror imprint3r(CDFnode*, CDFnode*, int depth);
static NCerror imprintdims3(CDFnode*, CDFnode*);
#endif
/* Accumulate useful node sets */
NCerror
@ -375,7 +369,6 @@ to produce (1) from (2).
NCerror
regrid3(CDFnode* ddsroot, CDFnode* template, NClist* projections)
{
int i;
NCerror ncstat = NC_NOERR;
NClist* newstructs = nclistnew();
@ -400,17 +393,7 @@ fprintf(stderr,"regrid: template=%s\n",dumptree(template));
This includes containers and subnodes. If there are no
projections then mark all nodes
*/
#ifdef DDSNEW
projectall3(template->tree->nodes);
#else
if(nclistlength(projections) == 0) {
projectall3(template->tree->nodes);
} else for(i=0;i<nclistlength(projections);i++) {
DCEprojection* proj = (DCEprojection*)nclistget(projections,i);
ASSERT(proj->discrim == CES_VAR);
projection3r(proj->var->cdfleaf);
}
#endif
if(simplenodematch34(ddsroot,template)) {
ncstat = regrid3r(ddsroot,template,newstructs);
@ -441,6 +424,7 @@ projectall3(NClist* nodes)
}
}
#ifdef NOTUSED
static void
projection3r(CDFnode* node)
{
@ -462,6 +446,7 @@ fprintf(stderr,"projection: %s\n",makesimplepathstring3(pathnode));
}
nclistfree(path);
}
#endif /*NOTUSED*/
/*
Add in virtual structure nodes so that
@ -664,7 +649,6 @@ findddsnode0(CDFnode* node)
}
#endif
#ifdef DDSNEW
/**
Make the constrained dds nodes (root)
@ -751,7 +735,7 @@ mapdims3(CDFnode* connode, CDFnode* fullnode)
return NC_NOERR;
}
#else /*!DDSNEW*/
#ifdef NOTUSED
/*
Move data from nodes in src tree to nodes in dst tree where
@ -839,7 +823,7 @@ unimprint3(CDFnode* root)
}
}
}
#endif /*!DDSNEW*/
#endif /*NOTUSED*/
void
setvisible(CDFnode* root, int visible)

View File

@ -2,11 +2,34 @@
PARMS=""; ARGS=""; CON="" ; CE=""; OCON=""
PARMS="[log]"
F="file:///home/dmh/nc/netcdf-3/ncdap_test/testdata3/synth1"
PARMS="${PARMS}[netcdf4]"
#PARMS="${PARMS}[cache]"
PARMS="${PARMS}[show=fetch]"
#PARMS="${PARMS}[compile]"
if test "x$CE" != "x" ; then set PARMS="${PARMS}[ce=${CE}]" ; fi
PROG="./ncd"
#PROG="../ncdump/ncdump"
U="${PARMS}$F"
if test "x$CON" != "x" ; then U="${PARMS}$F?$CON"; fi
UALL="${PARMS}$F"
#ARGS="-h $ARGS"
#ARGS="-w $ARGS"
#ARGS="-c $ARGS"
VARGS="--leak-check=full"
alias qq="gdb --args $PROG $ARGS '$U'"
alias qv="valgrind $VARGS PROG $ARGS '$U'"
alias q0="$PROG $ARGS '$U'"
alias qh="$PROG -h $ARGS '$U'"
alias qqh="gdb --args $PROG -h $ARGS '$U'"
alias qall="$PROG -h $ARGS '${UALL}'"
alias qv="valgrind $VARGS $PROG $ARGS '$U'"
F="http://nomads.ncep.noaa.gov:9090/dods/gfs_hd/gfs_hd20110908/gfs_hd_00z"
CON="absvprs[0:10][6:6][0:10][0:10]"
if test 1 = 0; then
F="http://nomads.ncep.noaa.gov:9090/dods/gfs_hd/gfs_hd20110908/gfs_hd_00z"
CON="absvprs[0:10][6:6][0:10][0:10]"
CON="absvprs[0:1:64][6:1:6][0:1:360][0:1:719]"
F="http://ferret.pmel.noaa.gov/geoide/dodsC/ct_flux"
F="http://motherlode.ucar.edu:9080/thredds/dodsC/fmrc/NCEP/GFS/Alaska_191km/NCEP-GFS-Alaska_191km_fmrc.ncx"
@ -30,24 +53,3 @@ F="http://dods.ndbc.noaa.gov/thredds/dodsC/data/stdmet/46029/46029h9999.nc"
CON="wind_dir[1:10][0:0][0:0]"
fi
#PARMS="${PARMS}[netcdf4]"
#PARMS="${PARMS}[cache]"
PARMS="${PARMS}[show=fetch]"
#PARMS="${PARMS}[compile]"
if test "x$CE" != "x" ; then set PARMS="${PARMS}[ce=${CE}]" ; fi
PROG="./ncd"
#PROG="../ncdump/ncdump"
U="${PARMS}$F"
if test "x$CON" != "x" ; then U="${PARMS}$F?$CON"; fi
UALL="${PARMS}$F"
#ARGS="-h $ARGS"
#ARGS="-w $ARGS"
#ARGS="-c $ARGS"
VARGS="--leak-check=full"
alias qq="gdb --args $PROG $ARGS '$U'"
alias qv="valgrind $VARGS PROG $ARGS '$U'"
alias q0="$PROG $ARGS '$U'"
alias qh="$PROG -h $ARGS '$U'"
alias qqh="gdb --args $PROG -h $ARGS '$U'"
alias qall="$PROG -h $ARGS '${UALL}'"
alias qv="valgrind $VARGS $PROG $ARGS '$U'"

View File

@ -34,8 +34,9 @@ nc3d_getvarx(int ncid, int varid,
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
int i;
NCDAP3* drno;
NC_var* var;
NC* drno;
NC* substrate;
NCDAPCOMMON* dapcomm;
CDFnode* cdfvar; /* cdf node mapping to var*/
NClist* varnodes;
nc_type dsttype;
@ -52,12 +53,13 @@ nc3d_getvarx(int ncid, int varid,
ncstat = NC_check_id(ncid, (NC**)&drno);
if(ncstat != NC_NOERR) goto fail;
dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
var = NC_lookupvar((NC*)drno,varid);
if(var == NULL) {ncstat = NC_ENOTVAR; goto fail;}
ncstat = NC_check_id(drno->substrate, (NC**)&substrate);
if(ncstat != NC_NOERR) goto fail;
/* Locate var node via varid */
varnodes = drno->dap.cdf.varnodes;
varnodes = dapcomm->cdf.varnodes;
for(i=0;i<nclistlength(varnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(varnodes,i);
if(node->array.basevar == NULL
@ -69,7 +71,6 @@ nc3d_getvarx(int ncid, int varid,
}
ASSERT((cdfvar != NULL));
ASSERT((strcmp(cdfvar->ncfullname,var->name->cp)==0));
/* Get the dimension info */
ncdims = cdfvar->array.dimensions;
@ -139,23 +140,23 @@ fprintf(stderr,"\n");
}
}
ncstat = makegetvar34(&drno->dap,cdfvar,data,dsttype,&varinfo);
ncstat = makegetvar34(dapcomm,cdfvar,data,dsttype,&varinfo);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
#ifdef IGNORE
freegetvara(drno->dap.cdf.vara);
drno->dap.cdf.vara = varinfo;
freegetvara(dapcomm->cdf.vara);
dapcomm->cdf.vara = varinfo;
#endif
ncstat = buildvaraprojection3(varinfo,startp,countp,stridep,&varaprojection);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
if(FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE)) {
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
#ifdef DEBUG
fprintf(stderr,"Unconstrained: reusing prefetch\n");
#endif
cachenode = drno->dap.cdf.cache->prefetch;
cachenode = dapcomm->cdf.cache->prefetch;
ASSERT((cachenode != NULL));
} else if(iscached(&drno->dap,varaprojection->var->cdfleaf,&cachenode)) {
} else if(iscached(dapcomm,varaprojection->var->cdfleaf,&cachenode)) {
/* If it is cached, then it is a whole variable */
#ifdef DEBUG
fprintf(stderr,"Reusing cache\n");
@ -163,8 +164,8 @@ fprintf(stderr,"Reusing cache\n");
} else { /*not cached: load using constraints */
nclistpush(vars,(ncelem)varinfo->target);
constraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
constraint->projections = dceclonelist(drno->dap.oc.dapconstraint->projections);
if(!FLAGSET(drno->dap.controls,NCF_CACHE)) {
constraint->projections = dceclonelist(dapcomm->oc.dapconstraint->projections);
if(!FLAGSET(dapcomm->controls,NCF_CACHE)) {
/* If we are not caching, then merge the getvara projections */
NClist* tmp = nclistnew();
DCEprojection* clone = (DCEprojection*)dceclone((DCEnode*)varaprojection);
@ -185,11 +186,11 @@ fprintf(stderr,"vara merge: %s\n",
}
restrictprojection34(vars,constraint->projections);
constraint->selections = dceclonelist(drno->dap.oc.dapconstraint->selections);
constraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
/* buildcachenode3 will create a new cachenode and
will also fetch the corresponding datadds */
ncstat = buildcachenode34(&drno->dap,constraint,vars,&cachenode,0);
ncstat = buildcachenode34(dapcomm,constraint,vars,&cachenode,0);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
constraint = NULL; /* buildcachenode34 takes control of constraint */
@ -199,8 +200,8 @@ fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
}
/* attach DATADDS to DDS */
unattach34(drno->dap.cdf.ddsroot);
ncstat = attachsubset34(cachenode->datadds,drno->dap.cdf.ddsroot);
unattach34(dapcomm->cdf.ddsroot);
ncstat = attachsubset34(cachenode->datadds,dapcomm->cdf.ddsroot);
if(ncstat) goto fail;
/* Fix up varinfo to use the cache */
@ -219,7 +220,7 @@ fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
/* Switch to datadds tree space*/
varinfo->target = xtarget;
ncstat = moveto(&drno->dap,varinfo,cachenode->datadds,data);
ncstat = moveto(dapcomm,varinfo,cachenode->datadds,data);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
goto ok;
fail:
@ -693,7 +694,9 @@ nc3d_getvarmx(int ncid, int varid,
{
NCerror ncstat = NC_NOERR;
int i;
NCDAP3* drno;
NC* drno;
NC* substrate;
NCDAPCOMMON* dapcomm;
NC_var* var;
CDFnode* cdfvar; /* cdf node mapping to var*/
NClist* varnodes;
@ -710,12 +713,15 @@ nc3d_getvarmx(int ncid, int varid,
ncstat = NC_check_id(ncid, (NC**)&drno);
if(ncstat != NC_NOERR) goto done;
dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
var = NC_lookupvar((NC*)drno,varid);
ncstat = NC_check_id(drno->substrate, (NC**)&substrate);
if(ncstat != NC_NOERR) goto done;
var = NC_lookupvar(substrate,varid);
if(var == NULL) {ncstat = NC_ENOTVAR; goto done;}
/* Locate var node via varid */
varnodes = drno->dap.cdf.varnodes;
varnodes = dapcomm->cdf.varnodes;
for(i=0;i<nclistlength(varnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(varnodes,i);
if(node->array.basevar == NULL

View File

@ -6,9 +6,9 @@
#endif
#include "ncd3dispatch.h"
static NCerror getcontent4(NCDAP4*, Getvara*, CDFnode* rootnode, void* data);
static NCerror getcontent4r(NCDAP4*, Getvara*, CDFnode* tnode, OCdata, NCbytes*);
static NCerror getcontent4prim(NCDAP4* drno, Getvara*, CDFnode* tnode, DCEsegment*,
static NCerror getcontent4(NCDAPCOMMON*, Getvara*, CDFnode* rootnode, void* data);
static NCerror getcontent4r(NCDAPCOMMON*, Getvara*, CDFnode* tnode, OCdata, NCbytes*);
static NCerror getcontent4prim(NCDAPCOMMON* dapcomm, Getvara*, CDFnode* tnode, DCEsegment*,
OCdata currentcontent, NCbytes* memory);
static int findfield(CDFnode* node, CDFnode* subnode);
static int contiguousdims(Dapodometer* odom);
@ -24,11 +24,8 @@ NCD4_get_vara(int ncid, int varid,
unsigned int i;
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
NC_GRP_INFO_T *grp;
NC_HDF5_FILE_INFO_T *h5;
NC_VAR_INFO_T *var;
NCDAP4* drno;
NCDAPCOMMON* nccomm;
NC* drno;
NCDAPCOMMON* dapcomm;
CDFnode* cdfvar; /* cdf node mapping to var*/
NClist* varnodes;
Getvara* varainfo = NULL;
@ -44,18 +41,12 @@ NCD4_get_vara(int ncid, int varid,
LOG((2, "nc_get_vara: ncid 0x%x varid %d", ncid, varid));
if((ncstat = nc4_find_nc_grp_h5(ncid, (NC_FILE_INFO_T**)&drno, &grp, &h5)))
{THROWCHK(ncstat); goto fail;}
nccomm = &drno->dap;
/* Find the netcdf-4 var structure */
for(var=grp->var;var!=NULL;var=var->next) {
if (var->varid == varid) break;
}
if(var == NULL) {ncstat = NC_ENOTVAR; goto fail;}
ncstat = NC_check_id(ncid, (NC**)&drno);
if(ncstat != NC_NOERR) goto fail;
dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
/* Find cdfnode corresponding to the var.*/
varnodes = nccomm->cdf.varnodes;
varnodes = dapcomm->cdf.varnodes;
cdfvar = NULL;
for(i=0;i<nclistlength(varnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(varnodes,i);
@ -65,7 +56,6 @@ NCD4_get_vara(int ncid, int varid,
}
}
ASSERT((cdfvar != NULL));
ASSERT((strcmp(cdfvar->ncfullname,var->name)==0));
/* Get the dimension info */
ncdims = cdfvar->array.dimensions;
@ -126,11 +116,11 @@ fprintf(stderr,"\n");
}
}
ncstat = makegetvar34(nccomm,cdfvar,data,externaltype,&varainfo);
ncstat = makegetvar34(dapcomm,cdfvar,data,externaltype,&varainfo);
if(ncstat) {THROWCHK(NC_ENOMEM); goto fail;}
#ifdef IGNORE
freegetvara(nccomm->vara);
nccomm->vara = varainfo;
freegetvara(dapcomm->vara);
dapcomm->vara = varainfo;
#endif
ncstat = buildvaraprojection4(varainfo,
@ -138,13 +128,13 @@ fprintf(stderr,"\n");
&varaprojection);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
if(FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE)) {
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
#ifdef DEBUG
fprintf(stderr,"Unconstrained: reusing prefetch\n");
#endif
cachenode = nccomm->cdf.cache->prefetch;
cachenode = dapcomm->cdf.cache->prefetch;
ASSERT((cachenode != NULL));
} else if(iscached(&drno->dap,varaprojection->var->cdfleaf,&cachenode)) {
} else if(iscached(dapcomm,varaprojection->var->cdfleaf,&cachenode)) {
#ifdef DEBUG
fprintf(stderr,"Reusing cached fetch constraint: %s\n",
dumpconstraint(cachenode->constraint));
@ -155,8 +145,8 @@ fprintf(stderr,"Reusing cached fetch constraint: %s\n",
nclistpush(vars,(ncelem)varainfo->target);
constraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
constraint->projections = dceclonelist(nccomm->oc.dapconstraint->projections);
if(!FLAGSET(drno->dap.controls,NCF_CACHE)) {
constraint->projections = dceclonelist(dapcomm->oc.dapconstraint->projections);
if(!FLAGSET(dapcomm->controls,NCF_CACHE)) {
/* If we are not caching, then merge the getvara projections */
NClist* tmp = nclistnew();
DCEprojection* clone = (DCEprojection*)dceclone((DCEnode*)varaprojection);
@ -172,10 +162,10 @@ fprintf(stderr,"vara merge: %s\n",
}
restrictprojection34(vars,constraint->projections);
constraint->selections = dceclonelist(nccomm->oc.dapconstraint->selections);
constraint->selections = dceclonelist(dapcomm->oc.dapconstraint->selections);
/* buildcachenode3 will also fetch the corresponding datadds */
ncstat = buildcachenode34(nccomm,constraint,vars,&cachenode,0);
ncstat = buildcachenode34(dapcomm,constraint,vars,&cachenode,0);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
#ifdef DEBUG
fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
@ -183,8 +173,8 @@ fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
}
/* attach DATADDS to DDS */
unattach34(nccomm->cdf.ddsroot);
ncstat = attachsubset34(cachenode->datadds,nccomm->cdf.ddsroot);
unattach34(dapcomm->cdf.ddsroot);
ncstat = attachsubset34(cachenode->datadds,dapcomm->cdf.ddsroot);
if(ncstat) goto fail;
/* Fix up varainfo to use the cache */
@ -202,7 +192,7 @@ fprintf(stderr,"cache.datadds=%s\n",dumptree(cachenode->datadds));
{THROWCHK(ncstat=NC_ENODATA); goto fail;}
/* Switch to datadds tree space*/
varainfo->target = xtarget;
ncstat = getcontent4(drno,varainfo,cachenode->datadds,data);
ncstat = getcontent4(dapcomm,varainfo,cachenode->datadds,data);
if(ncstat != OC_NOERR) {THROWCHK(ncstat); goto fail;}
goto ok;
fail:
@ -215,7 +205,7 @@ ok:
}
static NCerror
getcontent4(NCDAP4* drno, Getvara* xgetvar, CDFnode* xroot, void* data)
getcontent4(NCDAPCOMMON* dapcomm, Getvara* xgetvar, CDFnode* xroot, void* data)
{
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
@ -223,7 +213,7 @@ getcontent4(NCDAP4* drno, Getvara* xgetvar, CDFnode* xroot, void* data)
size_t alloc;
int fieldindex;
CDFnode* tnode = xgetvar->target;
OCconnection conn = drno->dap.oc.conn;
OCconnection conn = dapcomm->oc.conn;
OCdata rootcontent = OCNULL;
OCdata fieldcontent = OCNULL;
OCdata dimcontent = OCNULL;
@ -231,8 +221,8 @@ getcontent4(NCDAP4* drno, Getvara* xgetvar, CDFnode* xroot, void* data)
OCdata gridcontent = OCNULL;
Dapodometer* odom = NULL;
OCobject ocroot = OCNULL;
int caching = FLAGSET(drno->dap.controls,NCF_CACHE);
int unconstrainable = FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE);
int caching = FLAGSET(dapcomm->controls,NCF_CACHE);
int unconstrainable = FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE);
nc_type externaltype = xgetvar->dsttype;
/* is var from a toplevel grid? */
@ -311,14 +301,14 @@ fprintf(stderr,"getcontent4: |%s| = %lu\n",tnode->name,alloc);
if(seqvar) {
ASSERT((seqcontent != OCNULL));
ncstat=getcontent4r(drno,xgetvar,tnode,seqcontent,memory);
ncstat=getcontent4r(dapcomm,xgetvar,tnode,seqcontent,memory);
} else if(tnode->nctype == NC_Primitive) {
/* Stride the dimensions and get the instances */
DCEsegment* segment = NULL;
ASSERT((nclistlength(xgetvar->varaprojection->var->segments)==1));
segment = (DCEsegment*)nclistget(xgetvar->varaprojection->var->segments,0);
ASSERT((fieldcontent != OCNULL));
ncstat = getcontent4prim(drno,xgetvar,tnode,segment,fieldcontent,memory);
ncstat = getcontent4prim(dapcomm,xgetvar,tnode,segment,fieldcontent,memory);
} else if(nclistlength(tnode->array.dimensions) > 0) {
/* Stride the dimensions and get the instances */
DCEsegment* segment = NULL;
@ -335,12 +325,12 @@ fprintf(stderr,"getcontent4: |%s| = %lu\n",tnode->name,alloc);
dimcontent = oc_data_new(conn);
ocstat = oc_data_ith(conn,fieldcontent,dimoffset,dimcontent);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
ncstat = getcontent4r(drno,xgetvar,tnode,dimcontent,memory);
ncstat = getcontent4r(dapcomm,xgetvar,tnode,dimcontent,memory);
dapodometerincr(odom);
}
freedapodometer(odom);
} else {
ncstat=getcontent4r(drno,xgetvar,tnode,fieldcontent,memory);
ncstat=getcontent4r(dapcomm,xgetvar,tnode,fieldcontent,memory);
}
/*ok:*/
@ -357,7 +347,7 @@ fail:
/* Recursive walker part of getcontent */
static NCerror
getcontent4r(NCDAP4* drno,
getcontent4r(NCDAPCOMMON* dapcomm,
Getvara* xgetvar,
CDFnode* tnode, /* type definition */
OCdata currentcontent,
@ -368,15 +358,15 @@ getcontent4r(NCDAP4* drno,
NCerror ncstat = NC_NOERR;
size_t rank;
OCmode mode;
OCconnection conn = drno->dap.oc.conn;
OCconnection conn = dapcomm->oc.conn;
OCdata reccontent = OCNULL;
OCdata fieldcontent = OCNULL;
OCdata dimcontent = OCNULL;
Dapodometer* odom = NULL;
NCbytes* vlenmemory = NULL;
nc_vlen_t vlenref = {0,NULL};
int caching = FLAGSET(drno->dap.controls,NCF_CACHE);
int unconstrainable = FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE);
int caching = FLAGSET(dapcomm->controls,NCF_CACHE);
int unconstrainable = FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE);
rank = nclistlength(tnode->array.dimensions);
oc_data_mode(conn,currentcontent,&mode);
@ -390,7 +380,7 @@ fprintf(stderr,"getcontent4r: rank=%lu mode=%d nctype=%s\n",
seg.name = tnode->name;
seg.cdfnode = tnode;
makewholesegment3(&seg,tnode);
ncstat = getcontent4prim(drno,xgetvar,tnode,&seg,currentcontent,memory);
ncstat = getcontent4prim(dapcomm,xgetvar,tnode,&seg,currentcontent,memory);
goto done;
}
@ -422,7 +412,7 @@ abort();
unsigned int dimoffset = dapodometercount(odom);
ocstat = oc_data_ith(conn,currentcontent,dimoffset,dimcontent);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
ncstat = getcontent4r(drno,xgetvar,tnode,dimcontent,memory);
ncstat = getcontent4r(dapcomm,xgetvar,tnode,dimcontent,memory);
}
} break;
@ -434,7 +424,7 @@ abort();
CDFnode* subnode = (CDFnode*)nclistget(tnode->subnodes,i);
ocstat = oc_data_ith(conn,currentcontent,i,fieldcontent);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
ncstat = getcontent4r(drno,xgetvar,subnode,fieldcontent,memory);
ncstat = getcontent4r(dapcomm,xgetvar,subnode,fieldcontent,memory);
}
break;
@ -451,7 +441,7 @@ fprintf(stderr,"getcontent4r: record: vlenmemory=%lx\n",
ocstat = oc_data_ith(conn,currentcontent,i,reccontent);
if(ocstat == OC_EINVALCOORDS) {ocstat=OC_NOERR; break;} /* no more records */
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
ncstat = getcontent4r(drno,xgetvar,tnode,reccontent,vlenmemory);
ncstat = getcontent4r(dapcomm,xgetvar,tnode,reccontent,vlenmemory);
}
vlenref.len = i;
vlenref.p = ncbytesextract(vlenmemory);
@ -483,7 +473,7 @@ fail:
}
static NCerror
getcontent4prim(NCDAP4* drno,
getcontent4prim(NCDAPCOMMON* dapcomm,
Getvara* xgetvar,
CDFnode* tnode,
DCEsegment* segment,
@ -493,12 +483,12 @@ getcontent4prim(NCDAP4* drno,
OCerror ocstat = OC_NOERR;
NCerror ncstat = NC_NOERR;
unsigned int rank;
OCconnection conn = drno->dap.oc.conn;
OCconnection conn = dapcomm->oc.conn;
Dapodometer* odom = NULL;
unsigned int memoffset;
DCEslice* slices = segment->slices;
int caching = FLAGSET(drno->dap.controls,NCF_CACHE);
int unconstrainable = FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE);
int caching = FLAGSET(dapcomm->controls,NCF_CACHE);
int unconstrainable = FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE);
size_t internaltypesize, externaltypesize;
nc_type internaltype = segment->cdfnode->etype;
nc_type externaltype = xgetvar->dsttype;
@ -736,7 +726,7 @@ against the relevant nodes in which the ultimate target
is contained.
*/
static NCerror
buildvarprojection4(NCDAP4* drno, Getvara* getvar, NCbytes* buf)
buildvarprojection4(NCDAPCOMMON* dapcomm, Getvara* getvar, NCbytes* buf)
{
int i, dimdex;
CDFnode* node;

View File

@ -6,8 +6,6 @@
#ifndef NCCOMMON_H
#define NCCOMMON_H 1
#define DDSNEW 1
/* Mnemonics */
#ifndef BOOL
#define BOOL int
@ -47,7 +45,6 @@
/**************************************************/
/* sigh, do the forwards */
struct NCDAP3;
struct NCDAPCOMMON;
struct NCprojection;
struct NCselection;
@ -131,12 +128,8 @@ typedef struct NCOC {
} NCOC;
typedef struct NCCDF {
#ifdef DDSNEW
struct CDFnode* ddsroot; /* constrained dds */
struct CDFnode* fullddsroot; /* unconstrained dds */
#else
struct CDFnode* ddsroot; /* unconstrained dds */
#endif
/* Collected sets of useful nodes (in ddsroot tree space) */
NClist* varnodes; /* nodes which can represent netcdf variables */
NClist* seqnodes; /* sequence nodes; */
@ -158,7 +151,7 @@ typedef struct NCCDF {
/* Define a structure holding common info for NCDAP{3,4} */
typedef struct NCDAPCOMMON {
NC* controller; /* Parent instance of NCDAP3 or NCDAP4 */
NC* controller; /* Parent instance of NCDAPCOMMON */
NCCDF cdf;
NCOC oc;
NCCONTROLS controls; /* Control flags and parameters */
@ -258,9 +251,7 @@ typedef struct CDFnode {
unsigned long sequencelimit; /* 0=>unlimited */
BOOL usesequence; /* If this sequence is usable */
BOOL elided; /* 1 => node does not partipate in naming*/
#ifdef DDSNEW
struct CDFnode* basenode; /* map from constrained tree to unconstrained */
#endif
BOOL visible; /* 1 => node is present in constrained tree;
independent of elided flag */
BOOL zerodim; /* 1 => node has a zero dimension */
@ -287,9 +278,8 @@ typedef struct CDFnode {
/* Shared procedures */
/* From ncdap3.c*/
extern NCerror cleanNCDAP3(struct NCDAP3* drno);
extern NCerror cleanNCDAPCOMMON(struct NCDAPCOMMON*);
extern NCerror fetchtemplatemetadata3(NCDAPCOMMON* drno);
extern NCerror fetchtemplatemetadata3(NCDAPCOMMON*);
/* From error.c*/
extern NCerror ocerrtoncerr(OCerror);

View File

@ -22,7 +22,7 @@ NCD3_create(const char *path, int cmode,
static int NCD3_redef(int ncid);
static int NCD3__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align);
static int NCD3_sync(int ncid);
static int NCD3_abort(int ncid);
static int NCD3_close(int ncid);
static int NCD3_put_vara(int ncid, int varid,
const size_t *start, const size_t *edges0,
@ -46,11 +46,14 @@ ptrdiff_t dapsinglestride3[NC_MAX_VAR_DIMS];
size_t dapzerostart3[NC_MAX_VAR_DIMS];
size_t dapsinglecount3[NC_MAX_VAR_DIMS];
NC_Dispatch* NCD3_dispatch_table = NULL;
NC_Dispatch NCD3_dispatch_base = {
NC_DISPATCH_NC3 | NC_DISPATCH_NCD,
NCD3_new_nc,
/* Note: we are using the standard substrate struct NC creator */
NULL,
NCD3_create,
NCD3_open,
@ -89,8 +92,8 @@ NCD3_get_vara,
NCD3_put_vara,
NCD3_get_vars,
NCD3_put_vars,
NULL, /*get_varm*/
NULL, /*put_varm*/
NCDEFAULT_get_varm,
NCDEFAULT_put_varm,
NULL, /*inq_var_all*/
@ -143,9 +146,9 @@ int
NCD3_initialize(void)
{
int i;
/* Create our dispatch table as the merge of NC3 table
plus some overrides */
NC_dispatch_overlay(&NCD3_dispatch_base, NC3_dispatch_table, &NCD3_dispatcher);
/* Create our dispatch table as the merge of NCD3 table and NCSUBSTRATE */
/* watch the order because we want NCD3 to overwrite NCSUBSTRATE */
NC_dispatch_overlay(&NCD3_dispatch_base, NCSUBSTRATE_dispatch_table, &NCD3_dispatcher);
NCD3_dispatch_table = &NCD3_dispatcher;
for(i=0;i<NC_MAX_VAR_DIMS;i++)
{dapzerostart3[i] = 0; dapsinglecount3[i] = 1; dapsinglestride3[i] = 1;}
@ -171,9 +174,9 @@ NCD3_sync(int ncid)
}
static int
NCD3_abort(int ncid)
NCD3_close(int ncid)
{
return (NC_NOERR);
return NCD3_abort(ncid);
}
static int

View File

@ -54,7 +54,7 @@ NCD3_open(const char *path, int mode,
struct NC_Dispatch* dispatch, NC** ncp);
EXTERNL int
NCD3_close(int ncid);
NCD3_abort(int ncid);
/* End _var */

View File

@ -9,8 +9,8 @@
#include <stdlib.h>
#include <string.h>
#include "ncdap4.h"
#include "nc.h"
#include "ncdap4.h"
#include "ncd4dispatch.h"
#include "ncdispatch.h"
@ -31,11 +31,14 @@ extern ptrdiff_t dapsinglestride3[NC_MAX_VAR_DIMS];
extern size_t dapzerostart3[NC_MAX_VAR_DIMS];
extern size_t dapsinglecount3[NC_MAX_VAR_DIMS];
NC_Dispatch* NCD4_dispatch_table = NULL;
NC_Dispatch NCD4_dispatch_base = {
NC_DISPATCH_NC4|NC_DISPATCH_NCD,
NCD4_new_nc,
/* Note: we are using the standard substrate struct NC creator */
NULL,
NCD4_create,
NCD4_open,
@ -128,9 +131,9 @@ int
NCD4_initialize(void)
{
int i;
/* Create our dispatch table as the merge of NC4 table
plus some overrides */
NC_dispatch_overlay(&NCD4_dispatch_base, NC4_dispatch_table, &NCD4_dispatcher);
/* Create our dispatch table as the merge of NCD4 table and NCSUBSTRATE */
/* watch the order because we want NCD4 to overwrite NCSUBSTRATE */
NC_dispatch_overlay(&NCD4_dispatch_base, NCSUBSTRATE_dispatch_table, &NCD4_dispatcher);
NCD4_dispatch_table = &NCD4_dispatcher;
for(i=0;i<NC_MAX_VAR_DIMS;i++)
{dapzerostart3[i] = 0; dapsinglecount3[i] = 1; dapsinglestride3[i] = 1;}
@ -175,10 +178,10 @@ NCD4_sync(int ncid)
}
int
NCD4_abort(int ncid)
NCD4_close(int ncid)
{
LOG((1, "nc_abort: ncid 0x%x", ncid));
/* Turn into close */
return NCD4_close(ncid);
LOG((1, "nc_close: ncid 0x%x", ncid));
/* Turn into abort */
return NCD4_abort(ncid);
}

View File

@ -55,7 +55,7 @@ NCD4_open(const char *path, int mode,
struct NC_Dispatch* dispatch, NC** ncp);
EXTERNL int
NCD4_close(int ncid);
NCD4_abort(int ncid);
EXTERNL int
NCD4_get_vara(int ncid, int varid,

View File

@ -12,19 +12,16 @@
#include "ocdrno.h"
#include "dapdump.h"
static NCerror buildncstructures(NCDAP3*);
static NCerror builddims(NCDAP3*);
static NCerror buildvars(NCDAP3*);
static NCerror buildglobalattrs3(NCDAP3*, int ncid, CDFnode* root);
static NCerror buildattribute3a(NCDAP3*, NCattribute* att, nc_type, int varid, int ncid);
static NCerror buildncstructures3(NCDAPCOMMON*);
static NCerror builddims(NCDAPCOMMON*);
static NCerror buildvars(NCDAPCOMMON*);
static NCerror buildglobalattrs3(NCDAPCOMMON*,CDFnode* root);
static NCerror buildattribute3a(NCDAPCOMMON*, NCattribute*, nc_type, int);
extern CDFnode* v4node;
int nc3dinitialized = 0;
#define getncid(drno) (((NC*)drno)->ext_ncid)
/**************************************************/
/* Add an extra function whose sole purpose is to allow
configure(.ac) to test for the presence of thiscode.
@ -49,17 +46,18 @@ nc3dinitialize(void)
}
/**************************************************/
#ifdef NOTUSED
int
NCD3_new_nc(NC** ncpp)
{
NCDAP3* ncp;
NCDAPCOMMON* ncp;
/* Allocate memory for this info. */
if (!(ncp = calloc(1, sizeof(struct NCDAP3))))
return NC_ENOMEM;
if(ncpp) *ncpp = (NC*)ncp;
return NC_NOERR;
}
#endif
/**************************************************/
/* See ncd3dispatch.c for other version */
@ -71,18 +69,16 @@ NCD3_open(const char * path, int mode,
{
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
NCDAP3* drno = NULL;
NC* drno = NULL;
NCDAPCOMMON* dapcomm = NULL;
char* modifiedpath;
OCURI* tmpurl;
char* ce = NULL;
int ncid = -1;
const char* value;
int fd;
char* tmpname = NULL;
if(!nc3dinitialized) nc3dinitialize();
if(!ocuriparse(path,&tmpurl)) PANIC("libncdap3: non-url path");
ocurifree(tmpurl); /* no longer needed */
@ -95,70 +91,87 @@ NCD3_open(const char * path, int mode,
modifiedpath = nulldup(path);
#endif
/* Use libsrc code to establish initial NC(alias NCDRNO) structure */
/* Setup our NC and NCDAPCOMMON state*/
drno = (NC*)calloc(1,sizeof(NC));
if(drno == NULL) {ncstat = NC_ENOMEM; goto done;}
/* compute an ncid */
ncstat = add_to_NCList(drno);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
ncid = drno->ext_ncid;
dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON));
if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;}
drno->dispatch = dispatch;
drno->dispatchdata = dapcomm;
dapcomm->controller = (NC*)drno;
dapcomm->oc.urltext = modifiedpath;
ocuriparse(dapcomm->oc.urltext,&dapcomm->oc.uri);
if(!constrainable34(dapcomm->oc.uri))
SETFLAG(dapcomm->controls,NCF_UNCONSTRAINABLE);
dapcomm->cdf.separator = ".";
dapcomm->cdf.smallsizelimit = DFALTSMALLLIMIT;
dapcomm->cdf.cache = createnccache();
/* Use libsrc code for storing metadata */
tmpname = nulldup(PSEUDOFILE);
fd = mkstemp(tmpname);
if(fd < 0) {THROWCHK(errno); goto done;}
/* Now, use the file to create the netcdf file */
if(sizeof(size_t) == sizeof(unsigned int))
ncstat = NC3_create(tmpname,NC_CLOBBER,0,0,NULL,0,NULL,
dispatch,(NC**)&drno);
ncstat = nc_create(tmpname,NC_CLOBBER,&drno->substrate);
else
ncstat = NC3_create(tmpname,NC_CLOBBER|NC_64BIT_OFFSET,0,0,NULL,0,NULL,
dispatch,(NC**)&drno);
/* free the original fd */
close(fd);
ncstat = nc_create(tmpname,NC_CLOBBER|NC_64BIT_OFFSET,&drno->substrate);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
/* free the filename so it will automatically go away*/
#ifdef NOTUSED
{
/* break the abstraction to get the fd */
NC* nc;
ncstat = NC_check_id(drno->substrate, &nc);
close(nc->int_ncid);
}
#endif
/* unlink the temp file so it will automatically be reclaimed */
unlink(tmpname);
nullfree(tmpname);
/* Avoid fill */
NC3_set_fill(ncid,NC_NOFILL,NULL);
/* Setup tentative DRNO state*/
drno->dap.controller = (NC*)drno;
drno->dap.oc.urltext = modifiedpath;
ocuriparse(drno->dap.oc.urltext,&drno->dap.oc.uri);
if(!constrainable34(drno->dap.oc.uri))
SETFLAG(drno->dap.controls,NCF_UNCONSTRAINABLE);
drno->dap.cdf.separator = ".";
drno->dap.cdf.smallsizelimit = DFALTSMALLLIMIT;
drno->dap.cdf.cache = createnccache();
drno->nc.dispatch = dispatch;
/* Avoid fill */
nc_set_fill(drno->ext_ncid,NC_NOFILL,NULL);
/* process control client parameters */
applyclientparamcontrols3(&drno->dap);
applyclientparamcontrols3(dapcomm);
drno->dap.oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
drno->dap.oc.dapconstraint->projections = nclistnew();
drno->dap.oc.dapconstraint->selections = nclistnew();
dapcomm->oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
dapcomm->oc.dapconstraint->projections = nclistnew();
dapcomm->oc.dapconstraint->selections = nclistnew();
/* Check to see if we are unconstrainable */
if(FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE)) {
if(drno->dap.oc.uri->constraint != NULL
&& strlen(drno->dap.oc.uri->constraint) > 0) {
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
if(dapcomm->oc.uri->constraint != NULL
&& strlen(dapcomm->oc.uri->constraint) > 0) {
nclog(NCLOGWARN,"Attempt to constrain an unconstrainable data source: %s",
drno->dap.oc.uri->constraint);
dapcomm->oc.uri->constraint);
}
/* ignore all constraints */
} else {
/* Parse constraints to make sure that they are syntactically correct */
ncstat = parsedapconstraints(&drno->dap,drno->dap.oc.uri->constraint,drno->dap.oc.dapconstraint);
ncstat = parsedapconstraints(dapcomm,dapcomm->oc.uri->constraint,dapcomm->oc.dapconstraint);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
}
#ifdef DEBUG
fprintf(stderr,"parsed constraint: %s\n",
dumpconstraint(drno->dap.oc.dapconstraint));
dumpconstraint(dapcomm->oc.dapconstraint));
#endif
/* Pass to OC */
ocstat = oc_open(drno->dap.oc.urltext,&drno->dap.oc.conn);
ocstat = oc_open(dapcomm->oc.urltext,&dapcomm->oc.conn);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
if(paramcheck34(&drno->dap,"show","fetch"))
SETFLAG(drno->dap.controls,NCF_SHOWFETCH);
if(paramcheck34(dapcomm,"show","fetch"))
SETFLAG(dapcomm->controls,NCF_SHOWFETCH);
/* Turn on logging; only do this after oc_open*/
value = oc_clientparam_get(drno->dap.oc.conn,"log");
value = oc_clientparam_get(dapcomm->oc.conn,"log");
if(value != NULL) {
ncloginit();
ncsetlogging(1);
@ -170,161 +183,177 @@ fprintf(stderr,"parsed constraint: %s\n",
/* fetch and build the (almost) unconstrained DDS for use as
template */
ncstat = fetchtemplatemetadata3(&drno->dap);
ncstat = fetchtemplatemetadata3(dapcomm);
if(ncstat != NC_NOERR) goto done;
/* fetch and build the constrained DDS */
ncstat = fetchconstrainedmetadata3(&drno->dap);
ncstat = fetchconstrainedmetadata3(dapcomm);
if(ncstat != NC_NOERR) goto done;
/* The following actions are (mostly) WRT to the
constrained tree */
/* The following actions are (mostly) WRT to the constrained tree */
/* Process the constraints to map to the constrained CDF tree */
ncstat = mapconstraints3(drno->dap.oc.dapconstraint,drno->dap.cdf.ddsroot);
ncstat = mapconstraints3(dapcomm->oc.dapconstraint,dapcomm->cdf.ddsroot);
if(ncstat != NC_NOERR) goto done;
/* Accumulate useful nodes sets */
ncstat = computecdfnodesets3(&drno->dap);
ncstat = computecdfnodesets3(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Fix grids */
ncstat = fixgrids3(&drno->dap);
ncstat = fixgrids3(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Locate and mark usable sequences */
ncstat = sequencecheck3(&drno->dap);
ncstat = sequencecheck3(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Conditionally suppress variables not in usable
sequences */
if(FLAGSET(drno->dap.controls,NCF_NOUNLIM)) {
ncstat = suppressunusablevars3(&drno->dap);
if(FLAGSET(dapcomm->controls,NCF_NOUNLIM)) {
ncstat = suppressunusablevars3(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
}
/* apply client parameters (after computcdfinfo and computecdfvars)*/
ncstat = applyclientparams34(&drno->dap);
ncstat = applyclientparams34(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Add (as needed) string dimensions*/
ncstat = addstringdims(drno);
ncstat = addstringdims(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
if(nclistlength(drno->dap.cdf.seqnodes) > 0) {
if(nclistlength(dapcomm->cdf.seqnodes) > 0) {
/* Build the sequence related dimensions */
ncstat = defseqdims(drno);
ncstat = defseqdims(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
}
/* Build a cloned set of dimensions for every variable */
ncstat = clonecdfdims34(&drno->dap);
ncstat = clonecdfdims34(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Re-compute the dimension names*/
ncstat = computecdfdimnames34(&drno->dap);
ncstat = computecdfdimnames34(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Deal with zero size dimensions */
ncstat = fixzerodims3(&drno->dap);
ncstat = fixzerodims3(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
if(nclistlength(drno->dap.cdf.seqnodes) == 0
&& drno->dap.cdf.recorddim != NULL) {
if(nclistlength(dapcomm->cdf.seqnodes) == 0
&& dapcomm->cdf.recorddim != NULL) {
/* Attempt to use the DODS_EXTRA info to turn
one of the dimensions into unlimited. Can only do it
in a sequence free DDS.
*/
ncstat = defrecorddim3(drno);
ncstat = defrecorddim3(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
}
/* Re-compute the var names*/
ncstat = computecdfvarnames3(&drno->dap,drno->dap.cdf.ddsroot,drno->dap.cdf.varnodes);
ncstat = computecdfvarnames3(dapcomm,dapcomm->cdf.ddsroot,dapcomm->cdf.varnodes);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Estimate the variable sizes */
estimatevarsizes3(&drno->dap);
estimatevarsizes3(dapcomm);
/* Build the meta data */
ncstat = buildncstructures(drno);
ncstat = buildncstructures3(dapcomm);
if(ncstat != NC_NOERR) {
del_from_NCList((NC*)drno); /* undefine here */
{THROWCHK(ncstat); goto done;}
}
/* Do any necessary data prefetch */
ncstat = prefetchdata3(&drno->dap);
ncstat = prefetchdata3(dapcomm);
if(ncstat != NC_NOERR) {
del_from_NCList((NC*)drno); /* undefine here */
{THROWCHK(ncstat); goto done;}
}
/* Mark as no longer indef */
fClr(drno->nc.flags, NC_INDEF);
/* Mark as no longer writable */
fClr(drno->nc.nciop->ioflags, NC_WRITE);
{
/* Mark as no longer writable and no longer indef;
requires breaking abstraction */
NC* nc;
ncstat = NC_check_id(drno->substrate, &nc);
/* Mark as no longer writeable */
fClr(nc->nciop->ioflags, NC_WRITE);
/* Mark as no longer indef;
(do NOT use nc_enddef until diskless is working)*/
fSet(nc->flags, NC_INDEF);
}
if(ncpp) *ncpp = (NC*)drno;
return THROW(NC_NOERR);
return ncstat;
done:
if(drno != NULL) {
int ncid = drno->nc.ext_ncid;
cleanNCDAP3(drno);
NC3_abort(ncid);
}
if(ce) nullfree(ce);
if(drno != NULL) NCD3_abort(drno->ext_ncid);
if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
return THROW(ncstat);
}
int
NCD3_close(int ncid)
NCD3_abort(int ncid)
{
NC* drno;
NCDAPCOMMON* dapcomm;
int ncstatus = NC_NOERR;
NCDAP3* drno;
ncstatus = NC_check_id(ncid, (NC**)&drno);
if(ncstatus != NC_NOERR) return THROW(ncstatus);
cleanNCDAP3(drno);
NC3_abort(ncid);
dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
ncstatus = nc_abort(drno->substrate);
/* remove ourselves from NClist */
del_from_NCList(drno);
/* clean NC* */
cleanNCDAPCOMMON(dapcomm);
if(drno->path != NULL) free(drno->path);
free(drno);
return THROW(ncstatus);
}
/**************************************************/
static NCerror
buildncstructures(NCDAP3* drno)
buildncstructures3(NCDAPCOMMON* dapcomm)
{
NCerror ncstat = NC_NOERR;
CDFnode* dds = drno->dap.cdf.ddsroot;
ncstat = buildglobalattrs3(drno,getncid(drno),dds);
CDFnode* dds = dapcomm->cdf.ddsroot;
NC* ncsub;
NC_check_id(dapcomm->controller->substrate,&ncsub);
ncstat = buildglobalattrs3(dapcomm,dds);
if(ncstat != NC_NOERR) goto done;
ncstat = builddims(drno);
ncstat = builddims(dapcomm);
if(ncstat != NC_NOERR) goto done;
ncstat = buildvars(drno);
ncstat = buildvars(dapcomm);
if(ncstat != NC_NOERR) goto done;
done:
return THROW(ncstat);
}
static NCerror
builddims(NCDAP3* drno)
builddims(NCDAPCOMMON* dapcomm)
{
int i;
NCerror ncstat = NC_NOERR;
int dimid;
int ncid = getncid(drno);
int defunlimited = 0;
NClist* dimset = NULL;
NC* drno = dapcomm->controller;
NC* ncsub;
ncstat = NC_check_id(drno->substrate,&ncsub);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
/* collect all dimensions from variables */
dimset = getalldims3(drno->dap.cdf.varnodes,1);
dimset = getalldims3(dapcomm->cdf.varnodes,1);
/* exclude unlimited */
for(i=nclistlength(dimset)-1;i>=0;i--) {
CDFnode* dim = (CDFnode*)nclistget(dimset,i);
@ -350,14 +379,14 @@ builddims(NCDAP3* drno)
if(!swap) break;
}
/* Define unlimited only if needed */
if(defunlimited && drno->dap.cdf.unlimited != NULL) {
CDFnode* unlimited = drno->dap.cdf.unlimited;
if(defunlimited && dapcomm->cdf.unlimited != NULL) {
CDFnode* unlimited = dapcomm->cdf.unlimited;
size_t unlimsize;
ncstat = nc_def_dim(ncid,
ncstat = nc_def_dim(drno->substrate,
unlimited->name,
NC_UNLIMITED,
&unlimited->ncid);
if(ncstat != NC_NOERR) goto done;
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
if(DIMFLAG(unlimited,CDFDIMRECORD)) {
/* This dimension was defined as unlimited by DODS_EXTRA */
unlimsize = unlimited->dim.declsize;
@ -366,13 +395,13 @@ builddims(NCDAP3* drno)
}
/* Set the effective size of UNLIMITED;
note that this cannot be done thru the normal API.*/
NC_set_numrecs((NC*)drno,unlimsize);
NC_set_numrecs(ncsub,unlimsize);
}
for(i=0;i<nclistlength(dimset);i++) {
CDFnode* dim = (CDFnode*)nclistget(dimset,i);
if(dim->dim.basedim != NULL) continue; /* handle below */
ncstat = nc_def_dim(ncid,dim->ncfullname,dim->dim.declsize,&dimid);
ncstat = nc_def_dim(drno->substrate,dim->ncfullname,dim->dim.declsize,&dimid);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
dim->ncid = dimid;
}
@ -393,13 +422,13 @@ done:
/* Simultaneously build any associated attributes*/
/* and any necessary pseudo-dimensions for string types*/
static NCerror
buildvars(NCDAP3* drno)
buildvars(NCDAPCOMMON* dapcomm)
{
int i,j,dimindex;
NCerror ncstat = NC_NOERR;
int varid;
int ncid = getncid(drno);
NClist* varnodes = drno->dap.cdf.varnodes;
NClist* varnodes = dapcomm->cdf.varnodes;
NC* drno = dapcomm->controller;
ASSERT((varnodes != NULL));
for(i=0;i<nclistlength(varnodes);i++) {
@ -424,7 +453,7 @@ fprintf(stderr,"buildvars.candidate=|%s|\n",var->ncfullname);
dimids[dimindex++] = dim->ncid;
}
}
ncstat = nc_def_var(ncid,var->ncfullname,
ncstat = nc_def_var(drno->substrate,var->ncfullname,
var->externaltype,
ncrank,
(ncrank==0?NULL:dimids),
@ -434,21 +463,20 @@ fprintf(stderr,"buildvars.candidate=|%s|\n",var->ncfullname);
if(var->attributes != NULL) {
for(j=0;j<nclistlength(var->attributes);j++) {
NCattribute* att = (NCattribute*)nclistget(var->attributes,j);
ncstat = buildattribute3a(drno,att,var->etype,varid,ncid);
ncstat = buildattribute3a(dapcomm,att,var->etype,varid);
if(ncstat != NC_NOERR) goto done;
}
}
/* Tag the variable with its DAP path */
if(paramcheck34(&drno->dap,"show","projection"))
showprojection3(drno,var);
if(paramcheck34(dapcomm,"show","projection"))
showprojection3(dapcomm,var);
}
done:
return THROW(ncstat);
}
static NCerror
buildglobalattrs3(NCDAP3* drno, int ncid, CDFnode* root)
buildglobalattrs3(NCDAPCOMMON* dapcomm, CDFnode* root)
{
int i;
NCerror ncstat = NC_NOERR;
@ -456,19 +484,20 @@ buildglobalattrs3(NCDAP3* drno, int ncid, CDFnode* root)
char *nltxt, *p;
NCbytes* buf = NULL;
NClist* cdfnodes;
NC* drno = dapcomm->controller;
if(root->attributes != NULL) {
for(i=0;i<nclistlength(root->attributes);i++) {
NCattribute* att = (NCattribute*)nclistget(root->attributes,i);
ncstat = buildattribute3a(drno,att,NC_NAT,NC_GLOBAL,ncid);
ncstat = buildattribute3a(dapcomm,att,NC_NAT,NC_GLOBAL);
if(ncstat != NC_NOERR) goto done;
}
}
/* Add global attribute identifying the sequence dimensions */
if(paramcheck34(&drno->dap,"show","seqdims")) {
if(paramcheck34(dapcomm,"show","seqdims")) {
buf = ncbytesnew();
cdfnodes = drno->dap.cdf.ddsroot->tree->nodes;
cdfnodes = dapcomm->cdf.ddsroot->tree->nodes;
for(i=0;i<nclistlength(cdfnodes);i++) {
CDFnode* dim = (CDFnode*)nclistget(cdfnodes,i);
if(dim->nctype != NC_Dimension) continue;
@ -480,7 +509,7 @@ buildglobalattrs3(NCDAP3* drno, int ncid, CDFnode* root)
}
}
if(ncbyteslength(buf) > 0) {
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_sequence_dimensions",
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_sequence_dimensions",
ncbyteslength(buf),ncbytescontents(buf));
}
}
@ -489,36 +518,36 @@ buildglobalattrs3(NCDAP3* drno, int ncid, CDFnode* root)
depending on show= clientparams*/
/* Ignore failures*/
if(paramcheck34(&drno->dap,"show","translate")) {
if(paramcheck34(dapcomm,"show","translate")) {
/* Add a global attribute to show the translation */
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_translate",
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_translate",
strlen("netcdf-3"),"netcdf-3");
}
if(paramcheck34(&drno->dap,"show","url")) {
if(drno->dap.oc.urltext != NULL)
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_url",
strlen(drno->dap.oc.urltext),drno->dap.oc.urltext);
if(paramcheck34(dapcomm,"show","url")) {
if(dapcomm->oc.urltext != NULL)
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_url",
strlen(dapcomm->oc.urltext),dapcomm->oc.urltext);
}
if(paramcheck34(&drno->dap,"show","dds")) {
if(paramcheck34(dapcomm,"show","dds")) {
txt = NULL;
if(drno->dap.cdf.ddsroot != NULL)
txt = oc_inq_text(drno->dap.oc.conn,drno->dap.cdf.ddsroot->dds);
if(dapcomm->cdf.ddsroot != NULL)
txt = oc_inq_text(dapcomm->oc.conn,dapcomm->cdf.ddsroot->dds);
if(txt != NULL) {
/* replace newlines with spaces*/
nltxt = nulldup(txt);
for(p=nltxt;*p;p++) {if(*p == '\n' || *p == '\r' || *p == '\t') {*p = ' ';}};
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_dds",strlen(nltxt),nltxt);
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_dds",strlen(nltxt),nltxt);
nullfree(nltxt);
}
}
if(paramcheck34(&drno->dap,"show","das")) {
if(paramcheck34(dapcomm,"show","das")) {
txt = NULL;
if(drno->dap.oc.ocdasroot != OCNULL)
txt = oc_inq_text(drno->dap.oc.conn,drno->dap.oc.ocdasroot);
if(dapcomm->oc.ocdasroot != OCNULL)
txt = oc_inq_text(dapcomm->oc.conn,dapcomm->oc.ocdasroot);
if(txt != NULL) {
nltxt = nulldup(txt);
for(p=nltxt;*p;p++) {if(*p == '\n' || *p == '\r' || *p == '\t') {*p = ' ';}};
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_das",strlen(nltxt),nltxt);
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_das",strlen(nltxt),nltxt);
nullfree(nltxt);
}
}
@ -529,12 +558,13 @@ done:
}
static NCerror
buildattribute3a(NCDAP3* drno, NCattribute* att, nc_type vartype, int varid, int ncid)
buildattribute3a(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int varid)
{
int i;
NCerror ncstat = NC_NOERR;
char* cname = cdflegalname3(att->name);
unsigned int nvalues = nclistlength(att->values);
NC* drno = dapcomm->controller;
/* If the type of the attribute is string, then we need*/
/* to convert to a single character string by concatenation.
@ -558,9 +588,9 @@ buildattribute3a(NCDAP3* drno, NCattribute* att, nc_type vartype, int varid, int
}
dapexpandescapes(newstring);
if(newstring[0]=='\0')
ncstat = nc_put_att_text(ncid,varid,cname,1,newstring);
ncstat = nc_put_att_text(drno->substrate,varid,cname,1,newstring);
else
ncstat = nc_put_att_text(ncid,varid,cname,strlen(newstring),newstring);
ncstat = nc_put_att_text(drno->substrate,varid,cname,strlen(newstring),newstring);
free(newstring);
} else {
nc_type atype;
@ -574,13 +604,13 @@ buildattribute3a(NCDAP3* drno, NCattribute* att, nc_type vartype, int varid, int
is the same as that of the controlling variable.
*/
if(varid != NC_GLOBAL && strcmp(att->name,"_FillValue")==0)
atype = nctypeconvert(&drno->dap,vartype);
atype = nctypeconvert(dapcomm,vartype);
else
atype = nctypeconvert(&drno->dap,att->etype);
atype = nctypeconvert(dapcomm,att->etype);
typesize = nctypesizeof(atype);
mem = malloc(typesize * nvalues);
ncstat = dapcvtattrval3(atype,mem,att->values);
ncstat = nc_put_att(ncid,varid,cname,atype,nvalues,mem);
ncstat = nc_put_att(drno->substrate,varid,cname,atype,nvalues,mem);
nullfree(mem);
}
free(cname);

View File

@ -84,10 +84,12 @@ struct NCsegment;
/**************************************************/
/* The NCDAP3 structure is an extension of the NC structure (libsrc/nc.h) */
#ifdef NOTUSED
typedef struct NCDAP3 {
NC nc; /* Used to store meta-data */
NCDAPCOMMON dap;
} NCDAP3;
#endif
/**************************************************/
@ -143,27 +145,21 @@ extern int nc3d_close(int ncid);
extern int nc3dinitialize(void);
extern NCerror regrid3(CDFnode* ddsroot, CDFnode* template, NClist*);
extern void setvisible(CDFnode* root, int visible);
#ifdef DDSNEW
extern NCerror mapnodes3(CDFnode* dstroot, CDFnode* srcroot);
extern void unmap3(CDFnode* root);
#else
extern NCerror imprint3(CDFnode* dstroot, CDFnode* srcroot);
extern void unimprint3(CDFnode* root);
extern NCerror imprintself3(CDFnode* root);
#endif
/* From: ncdap3a.c*/
extern NCerror fetchtemplatemetadata3(NCDAPCOMMON* nccomm);
extern NCerror fetchconstrainedmetadata3(NCDAPCOMMON* nccomm);
extern void applyclientparamcontrols3(NCDAPCOMMON*);
extern NCerror suppressunusablevars3(NCDAPCOMMON*);
extern NCerror addstringdims(NCDAP3* drno);
extern NCerror defseqdims(NCDAP3* drno);
extern NCerror addstringdims(NCDAPCOMMON* drno);
extern NCerror defseqdims(NCDAPCOMMON* drno);
extern NCerror fixzerodims3(NCDAPCOMMON*);
extern void estimatevarsizes3(NCDAPCOMMON*);
extern NCerror defrecorddim3(NCDAP3*);
extern NCerror defrecorddim3(NCDAPCOMMON*);
extern NClist* getalldims3(NClist* vars, int visibleonly);
extern NCerror showprojection3(NCDAP3*, CDFnode* var);
extern NCerror showprojection3(NCDAPCOMMON*, CDFnode* var);
/* From: dapcvt.c*/

View File

@ -1,7 +1,6 @@
/*********************************************************************
* Copyright 1993, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Header: /upc/share/CVS/netcdf-3/libncdap3/ncdap3.c,v 1.94 2010/05/28 01:05:34 dmh Exp $
*********************************************************************/
#include "ncdap3.h"
@ -31,39 +30,33 @@ freegetvara(Getvara* vara)
}
NCerror
cleanNCDAPCOMMON(NCDAPCOMMON* nccomm)
cleanNCDAPCOMMON(NCDAPCOMMON* dapcomm)
{
freenccache(nccomm,nccomm->cdf.cache);
nclistfree(nccomm->cdf.varnodes);
nclistfree(nccomm->cdf.seqnodes);
nclistfree(nccomm->cdf.gridnodes);
nclistfree(nccomm->cdf.usertypes);
nullfree(nccomm->cdf.recorddim);
/* abort the metadata file */
(void)nc_abort(getncid(dapcomm));
freenccache(dapcomm,dapcomm->cdf.cache);
nclistfree(dapcomm->cdf.varnodes);
nclistfree(dapcomm->cdf.seqnodes);
nclistfree(dapcomm->cdf.gridnodes);
nclistfree(dapcomm->cdf.usertypes);
nullfree(dapcomm->cdf.recorddim);
/* free the trees */
freecdfroot34(nccomm->cdf.ddsroot);
nccomm->cdf.ddsroot = NULL;
if(nccomm->oc.ocdasroot != NULL)
oc_root_free(nccomm->oc.conn,nccomm->oc.ocdasroot);
nccomm->oc.ocdasroot = NULL;
oc_close(nccomm->oc.conn); /* also reclaims remaining OC trees */
ocurifree(nccomm->oc.uri);
nullfree(nccomm->oc.urltext);
freecdfroot34(dapcomm->cdf.ddsroot);
dapcomm->cdf.ddsroot = NULL;
if(dapcomm->oc.ocdasroot != NULL)
oc_root_free(dapcomm->oc.conn,dapcomm->oc.ocdasroot);
dapcomm->oc.ocdasroot = NULL;
oc_close(dapcomm->oc.conn); /* also reclaims remaining OC trees */
ocurifree(dapcomm->oc.uri);
nullfree(dapcomm->oc.urltext);
dcefree((DCEnode*)nccomm->oc.dapconstraint);
nccomm->oc.dapconstraint = NULL;
dcefree((DCEnode*)dapcomm->oc.dapconstraint);
dapcomm->oc.dapconstraint = NULL;
return NC_NOERR;
}
NCerror
cleanNCDAP3(NCDAP3* drno)
{
return cleanNCDAPCOMMON(&drno->dap);
}
#ifdef IGNORE
/* Given a path, collect the set of dimensions along that path */
static void
@ -89,7 +82,7 @@ collectdims3(NClist* path, NClist* dimset)
#endif
NCerror
addstringdims(NCDAP3* drno)
addstringdims(NCDAPCOMMON* dapcomm)
{
/* for all variables of string type, we will need another dimension
to represent the string; Accumulate the needed sizes and create
@ -98,7 +91,7 @@ addstringdims(NCDAP3* drno)
All such dimensions are global.
*/
int i;
NClist* varnodes = drno->dap.cdf.varnodes;
NClist* varnodes = dapcomm->cdf.varnodes;
for(i=0;i<nclistlength(varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(varnodes,i);
CDFnode* sdim = NULL;
@ -118,10 +111,10 @@ addstringdims(NCDAP3* drno)
snprintf(dimname,sizeof(dimname),"maxStrlen%lu",
(unsigned long)dimsize);
}
sdim = makecdfnode34(&drno->dap, dimname, OC_Dimension, OCNULL,
drno->dap.cdf.ddsroot);
sdim = makecdfnode34(dapcomm, dimname, OC_Dimension, OCNULL,
dapcomm->cdf.ddsroot);
if(sdim == NULL) return THROW(NC_ENOMEM);
nclistpush(drno->dap.cdf.ddsroot->tree->nodes,(ncelem)sdim);
nclistpush(dapcomm->cdf.ddsroot->tree->nodes,(ncelem)sdim);
sdim->dim.dimflags |= CDFDIMSTRING;
sdim->dim.declsize = dimsize;
nullfree(sdim->ncbasename);
@ -135,40 +128,40 @@ addstringdims(NCDAP3* drno)
}
NCerror
defrecorddim3(NCDAP3* drno)
defrecorddim3(NCDAPCOMMON* dapcomm)
{
unsigned int i;
NCerror ncstat = NC_NOERR;
NClist* alldims;
ASSERT((drno->dap.cdf.recorddim != NULL));
ASSERT((dapcomm->cdf.recorddim != NULL));
/* Locate the dimension matching the record dim */
alldims = getalldims3(drno->dap.cdf.varnodes,1);
alldims = getalldims3(dapcomm->cdf.varnodes,1);
for(i=0;i<nclistlength(alldims);i++) {
CDFnode* dim = (CDFnode*)nclistget(alldims,i);
if(dim->nctype != NC_Dimension) continue;
if(dim->dim.basedim != NULL) continue; /* not the controlling dim */
if(strcmp(dim->name,drno->dap.cdf.recorddim) != 0) continue;
if(strcmp(dim->name,dapcomm->cdf.recorddim) != 0) continue;
if(DIMFLAG(dim,CDFDIMCLONE)) PANIC("cloned record dim");
if(drno->dap.cdf.unlimited != NULL) PANIC("Multiple unlimited");
if(dapcomm->cdf.unlimited != NULL) PANIC("Multiple unlimited");
DIMFLAGSET(dim,CDFDIMUNLIM|CDFDIMRECORD);
drno->dap.cdf.unlimited = dim;
dapcomm->cdf.unlimited = dim;
}
nclistfree(alldims);
/* Now, locate all the string dims and see if they are the record dim,
then replace */
if(drno->dap.cdf.unlimited != NULL) {
CDFnode* unlim = drno->dap.cdf.unlimited;
for(i=0;i<nclistlength(drno->dap.cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(drno->dap.cdf.varnodes,i);
if(dapcomm->cdf.unlimited != NULL) {
CDFnode* unlim = dapcomm->cdf.unlimited;
for(i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
CDFnode* sdim = var->array.stringdim;
if(sdim == NULL) continue;
if(strcmp(sdim->ncfullname,unlim->ncfullname)==0
&& sdim->dim.declsize == unlim->dim.declsize) {
var->array.stringdim = unlim;
nclistpop(var->array.dimensions);
nclistpush(var->array.dimensions,(ncelem)drno->dap.cdf.unlimited);
nclistpush(var->array.dimensions,(ncelem)dapcomm->cdf.unlimited);
}
}
}
@ -177,7 +170,7 @@ defrecorddim3(NCDAP3* drno)
}
NCerror
defseqdims(NCDAP3* drno)
defseqdims(NCDAPCOMMON* dapcomm)
{
unsigned int i;
CDFnode* unlimited = NULL;
@ -185,24 +178,24 @@ defseqdims(NCDAP3* drno)
int seqdims = 1; /* default is to compute seq dims counts */
/* Does the user want to see which dims are sequence dims? */
if(paramcheck34(&drno->dap,"show","seqdims")) seqdims = 0;
if(paramcheck34(dapcomm,"show","seqdims")) seqdims = 0;
/* Build the unlimited node if needed */
if(!FLAGSET(drno->dap.controls,NCF_NOUNLIM)) {
unlimited = makecdfnode34(&drno->dap,"unlimited",OC_Dimension,OCNULL,drno->dap.cdf.ddsroot);
nclistpush(drno->dap.cdf.ddsroot->tree->nodes,(ncelem)unlimited);
if(!FLAGSET(dapcomm->controls,NCF_NOUNLIM)) {
unlimited = makecdfnode34(dapcomm,"unlimited",OC_Dimension,OCNULL,dapcomm->cdf.ddsroot);
nclistpush(dapcomm->cdf.ddsroot->tree->nodes,(ncelem)unlimited);
nullfree(unlimited->ncbasename);
nullfree(unlimited->ncfullname);
unlimited->ncbasename = cdflegalname3(unlimited->name);
unlimited->ncfullname = nulldup(unlimited->ncbasename);
DIMFLAGSET(unlimited,CDFDIMUNLIM);
drno->dap.cdf.unlimited = unlimited;
dapcomm->cdf.unlimited = unlimited;
}
/* Compute and define pseudo dimensions for all sequences */
for(i=0;i<nclistlength(drno->dap.cdf.seqnodes);i++) {
CDFnode* seq = (CDFnode*)nclistget(drno->dap.cdf.seqnodes,i);
for(i=0;i<nclistlength(dapcomm->cdf.seqnodes);i++) {
CDFnode* seq = (CDFnode*)nclistget(dapcomm->cdf.seqnodes,i);
CDFnode* sqdim;
size_t seqsize;
@ -218,7 +211,7 @@ defseqdims(NCDAP3* drno)
/* Does the user want us to compute the sequence dim size? */
sqdim = NULL;
if(seqdims) {
ncstat = getseqdimsize(&drno->dap,seq,&seqsize);
ncstat = getseqdimsize(dapcomm,seq,&seqsize);
if(ncstat != NC_NOERR) {
/* Cannot get DATADDDS; convert to unlimited */
sqdim = unlimited;
@ -228,7 +221,7 @@ defseqdims(NCDAP3* drno)
}
if(sqdim == NULL) {
/* Note: we are making the dimension in the dds root tree */
ncstat = makeseqdim(&drno->dap,seq,seqsize,&sqdim);
ncstat = makeseqdim(dapcomm,seq,seqsize,&sqdim);
if(ncstat) goto fail;
}
seq->array.seqdim = sqdim;
@ -240,11 +233,11 @@ fail:
}
static NCerror
getseqdimsize(NCDAPCOMMON* nccomm, CDFnode* seq, size_t* sizep)
getseqdimsize(NCDAPCOMMON* dapcomm, CDFnode* seq, size_t* sizep)
{
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
OCconnection conn = nccomm->oc.conn;
OCconnection conn = dapcomm->oc.conn;
OCdata rootcontent = OCNULL;
OCobject ocroot;
CDFnode* dxdroot;
@ -254,37 +247,37 @@ getseqdimsize(NCDAPCOMMON* nccomm, CDFnode* seq, size_t* sizep)
/* Read the minimal amount of data in order to get the count */
/* If the url is unconstrainable, then get the whole thing */
computeminconstraints3(nccomm,seq,minconstraints);
computeminconstraints3(dapcomm,seq,minconstraints);
#ifdef DEBUG
fprintf(stderr,"minconstraints: %s\n",ncbytescontents(minconstraints));
#endif
/* Obtain the record counts for the sequence */
if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE))
ocstat = dap_oc_fetch(nccomm,conn,NULL,OCDATADDS,&ocroot);
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
ocstat = dap_oc_fetch(dapcomm,conn,NULL,OCDATADDS,&ocroot);
else
ocstat = dap_oc_fetch(nccomm,conn,ncbytescontents(minconstraints),OCDATADDS,&ocroot);
ocstat = dap_oc_fetch(dapcomm,conn,ncbytescontents(minconstraints),OCDATADDS,&ocroot);
if(ocstat) goto fail;
ncstat = buildcdftree34(nccomm,ocroot,OCDATA,&dxdroot);
ncstat = buildcdftree34(dapcomm,ocroot,OCDATA,&dxdroot);
if(ncstat) goto fail;
/* attach DATADDS to DDS */
ncstat = attach34(dxdroot,seq);
if(ncstat) goto fail;
/* WARNING: we are now switching to datadds tree */
xseq = seq->attachment;
ncstat = countsequence(nccomm,xseq,&seqsize);
ncstat = countsequence(dapcomm,xseq,&seqsize);
if(ncstat) goto fail;
#ifdef DEBUG
fprintf(stderr,"sequencesize: %s = %lu\n",seq->name,(unsigned long)seqsize);
#endif
/* throw away the fetch'd trees */
unattach34(nccomm->cdf.ddsroot);
unattach34(dapcomm->cdf.ddsroot);
freecdfroot34(dxdroot);
if(ncstat != NC_NOERR) {
/* Cannot get DATADDDS; convert to unlimited */
char* code;
char* msg;
long httperr;
oc_svcerrordata(nccomm->oc.conn,&code,&msg,&httperr);
oc_svcerrordata(dapcomm->oc.conn,&code,&msg,&httperr);
if(code != NULL) {
nclog(NCLOGERR,"oc_fetch_datadds failed: %s %s %l",
code,msg,httperr);
@ -301,14 +294,14 @@ fail:
}
static NCerror
makeseqdim(NCDAPCOMMON* nccomm, CDFnode* seq, size_t count, CDFnode** sqdimp)
makeseqdim(NCDAPCOMMON* dapcomm, CDFnode* seq, size_t count, CDFnode** sqdimp)
{
CDFnode* sqdim;
CDFnode* root = seq->root;
CDFtree* tree = root->tree;
/* build the dimension with given size */
sqdim = makecdfnode34(nccomm,seq->name,OC_Dimension,OCNULL,root);
sqdim = makecdfnode34(dapcomm,seq->name,OC_Dimension,OCNULL,root);
if(sqdim == NULL) return THROW(NC_ENOMEM);
nclistpush(tree->nodes,(ncelem)sqdim);
nullfree(sqdim->ncbasename);
@ -323,7 +316,7 @@ makeseqdim(NCDAPCOMMON* nccomm, CDFnode* seq, size_t count, CDFnode** sqdimp)
}
static NCerror
countsequence(NCDAPCOMMON* nccomm, CDFnode* xseq, size_t* sizep)
countsequence(NCDAPCOMMON* dapcomm, CDFnode* xseq, size_t* sizep)
{
unsigned int i;
NClist* path = nclistnew();
@ -334,7 +327,7 @@ countsequence(NCDAPCOMMON* nccomm, CDFnode* xseq, size_t* sizep)
int index;
OCerror ocstat = OC_NOERR;
NCerror ncstat = NC_NOERR;
OCconnection conn = nccomm->oc.conn;
OCconnection conn = dapcomm->oc.conn;
size_t recordcount;
CDFnode* xroot;
@ -386,12 +379,14 @@ fieldindex(CDFnode* parent, CDFnode* child)
}
NCerror
showprojection3(NCDAP3* drno, CDFnode* var)
showprojection3(NCDAPCOMMON* dapcomm, CDFnode* var)
{
int i,rank;
NCerror ncstat = NC_NOERR;
NCbytes* projection = ncbytesnew();
NClist* path = nclistnew();
NC* drno = dapcomm->controller;
/* Collect the set of DDS node name forming the xpath */
collectnodepath3(var,path,WITHOUTDATASET);
for(i=0;i<nclistlength(path);i++) {
@ -419,11 +414,11 @@ showprojection3(NCDAP3* drno, CDFnode* var)
#ifdef IGNORE
NCerror
detachdatadds3(NCDAP3* drno)
detachdatadds3(NCDAPCOMMON* dapcomm)
{
int i;
for(i=0;i<nclistlength(nccomm->cdf.dds->tree.nodes);i++) {
CDFnode* node = (CDFnode*)nclistget(nccomm->cdf.dds->tree.nodes,i);
for(i=0;i<nclistlength(dapcomm->cdf.dds->tree.nodes);i++) {
CDFnode* node = (CDFnode*)nclistget(dapcomm->cdf.dds->tree.nodes,i);
node->active = 0;
node->dim.datasize = node->dim.declsize;
}
@ -431,17 +426,17 @@ detachdatadds3(NCDAP3* drno)
}
NCerror
attachdatadds3(NCDAPCOMMON* nccomm)
attachdatadds3(NCDAPCOMMON* dapcomm)
{
int i;
NClist* cdfnodes = nccomm->cdf.dds->tree.nodes;
NClist* cdfnodes = dapcomm->cdf.dds->tree.nodes;
for(i=0;i<nclistlength(cdfnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(cdfnodes,i);
OCobject dds = node->dds;
if(dds == OCNULL) continue;
node->active = oc_datadds_active(nccomm->oc.conn,dds);
node->active = oc_datadds_active(dapcomm->oc.conn,dds);
if(node->nctype == NC_Dimension) {
oc_datadds_dimsize(nccomm->oc.conn,node->dds,&node->dim.datasize);
oc_datadds_dimsize(dapcomm->oc.conn,node->dds,&node->dim.datasize);
}
}
return NC_NOERR;
@ -457,7 +452,7 @@ through any nested sequence. This is possible because of the way
that sequencecheck() works.
*/
static NCerror
computeminconstraints3(NCDAPCOMMON* nccomm, CDFnode* seq, NCbytes* minconstraints)
computeminconstraints3(NCDAPCOMMON* dapcomm, CDFnode* seq, NCbytes* minconstraints)
{
NClist* path = nclistnew();
CDFnode* var;
@ -467,8 +462,8 @@ computeminconstraints3(NCDAPCOMMON* nccomm, CDFnode* seq, NCbytes* minconstraint
/* Locate a variable that is inside this sequence */
/* Preferably one that is a numeric type*/
for(candidate=NULL,var=NULL,i=0;i<nclistlength(nccomm->cdf.varnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(nccomm->cdf.varnodes,i);
for(candidate=NULL,var=NULL,i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* node = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
if(node->array.sequence == seq) {
if(node->nctype == NC_Primitive) {
switch(node->etype) {
@ -534,8 +529,8 @@ computeminconstraints3(NCDAPCOMMON* nccomm, CDFnode* seq, NCbytes* minconstraint
}
nclistfree(path);
/* Finally, add in any selection from the original URL */
if(nccomm->oc.uri->selection != NULL)
ncbytescat(minconstraints,nccomm->oc.uri->selection);
if(dapcomm->oc.uri->selection != NULL)
ncbytescat(minconstraints,dapcomm->oc.uri->selection);
nullfree(prefix);
return NC_NOERR;
}
@ -558,14 +553,14 @@ cdftotalsize3(NClist* dimensions)
by that size
*/
void
estimatevarsizes3(NCDAPCOMMON* nccomm)
estimatevarsizes3(NCDAPCOMMON* dapcomm)
{
int ivar;
unsigned int rank;
size_t totalsize = 0;
for(ivar=0;ivar<nclistlength(nccomm->cdf.varnodes);ivar++) {
CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.varnodes,ivar);
for(ivar=0;ivar<nclistlength(dapcomm->cdf.varnodes);ivar++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,ivar);
NClist* ncdims = var->array.dimensions;
rank = nclistlength(ncdims);
if(rank == 0) { /* use instance size of the type */
@ -588,11 +583,11 @@ fprintf(stderr,"array %s(%u).estimatedsize = %lu\n",
#ifdef DEBUG
fprintf(stderr,"total estimatedsize = %lu\n",totalsize);
#endif
nccomm->cdf.totalestimatedsize = totalsize;
dapcomm->cdf.totalestimatedsize = totalsize;
}
NCerror
fetchtemplatemetadata3(NCDAPCOMMON* nccomm)
fetchtemplatemetadata3(NCDAPCOMMON* dapcomm)
{
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
@ -606,22 +601,22 @@ fetchtemplatemetadata3(NCDAPCOMMON* nccomm)
/* Get (almost) unconstrained DDS; In order to handle functions
correctly, those selections must always be included
*/
if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE))
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
ce = NULL;
else
ce = nulldup(nccomm->oc.uri->selection);
ce = nulldup(dapcomm->oc.uri->selection);
/* Get selection constrained DDS */
ocstat = dap_oc_fetch(nccomm,nccomm->oc.conn,ce,OCDDS,&ocroot);
ocstat = dap_oc_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
if(ocstat != OC_NOERR) {
/* Special Hack. If the protocol is file, then see if
we can get the dds from the .dods file
*/
if(strcmp(nccomm->oc.uri->protocol,"file") != 0) {
if(strcmp(dapcomm->oc.uri->protocol,"file") != 0) {
THROWCHK(ocstat); goto done;
}
/* Fetch the data dds */
ocstat = dap_oc_fetch(nccomm,nccomm->oc.conn,ce,OCDATADDS,&ocroot);
ocstat = dap_oc_fetch(dapcomm,dapcomm->oc.conn,ce,OCDATADDS,&ocroot);
if(ocstat != OC_NOERR) {
THROWCHK(ocstat); goto done;
}
@ -630,35 +625,22 @@ fetchtemplatemetadata3(NCDAPCOMMON* nccomm)
}
/* Get selection constrained DAS */
if(nccomm->oc.ocdasroot != OCNULL)
oc_root_free(nccomm->oc.conn,nccomm->oc.ocdasroot);
nccomm->oc.ocdasroot = OCNULL;
ocstat = dap_oc_fetch(nccomm,nccomm->oc.conn,ce,OCDAS,&nccomm->oc.ocdasroot);
ocstat = dap_oc_fetch(dapcomm,dapcomm->oc.conn,ce,OCDAS,&dapcomm->oc.ocdasroot);
if(ocstat != OC_NOERR) {
/* Ignore but complain */
nclog(NCLOGWARN,"Could not read DAS; ignored");
nccomm->oc.ocdasroot = OCNULL;
dapcomm->oc.ocdasroot = OCNULL;
ocstat = OC_NOERR;
}
/* Construct our parallel dds tree */
ncstat = buildcdftree34(nccomm,ocroot,OCDDS,&ddsroot);
ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
#ifdef IGNORE
if(nccomm->cdf.ddsroot != NULL)
freecdfroot34(&drno->dap->cdf.ddsroot);
#endif
dapcomm->cdf.fullddsroot = ddsroot;
#ifdef DDSNEW
nccomm->cdf.fullddsroot = ddsroot;
#else
nccomm->cdf.ddsroot = ddsroot;
#endif
#ifdef DDSNEW
#else
#ifdef NOTUSED
/* Combine DDS and DAS */
ncstat = dapmerge3(nccomm,ddsroot,nccomm->oc.ocdasroot);
ncstat = dapmerge3(dapcomm,ddsroot,dapcomm->oc.ocdasroot);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
#endif
@ -669,7 +651,7 @@ done:
}
NCerror
fetchconstrainedmetadata3(NCDAPCOMMON* nccomm)
fetchconstrainedmetadata3(NCDAPCOMMON* dapcomm)
{
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
@ -677,38 +659,31 @@ fetchconstrainedmetadata3(NCDAPCOMMON* nccomm)
CDFnode* ddsroot; /* constrained */
char* ce = NULL;
if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE))
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
ce = NULL;
else
ce = buildconstraintstring3(nccomm->oc.dapconstraint);
ce = buildconstraintstring3(dapcomm->oc.dapconstraint);
#ifdef DDSNEW
#else
#ifdef NOTUSED
if(ce == NULL || strlen(ce) == 0) {
/* no need to get the dds again; just imprint on self */
ncstat = imprintself3(nccomm->cdf.ddsroot);
ncstat = imprintself3(dapcomm->cdf.ddsroot);
if(ncstat) goto fail;
} else
#endif
{
ocstat = dap_oc_fetch(nccomm,nccomm->oc.conn,ce,OCDDS,&ocroot);
ocstat = dap_oc_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
/* Construct our parallel dds tree; including attributes*/
ncstat = buildcdftree34(nccomm,ocroot,OCDDS,&ddsroot);
ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot);
if(ncstat) goto fail;
#ifdef DDSNEW
nccomm->cdf.ddsroot = ddsroot;
#endif
dapcomm->cdf.ddsroot = ddsroot;
if(!FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) {
if(!FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
/* fix DAP server problem by adding back any missing grid structure nodes */
#ifdef DDSNEW
ncstat = regrid3(ddsroot,nccomm->cdf.fullddsroot,nccomm->oc.dapconstraint->projections);
#else
ncstat = regrid3(ddsroot,nccomm->cdf.ddsroot,nccomm->oc.dapconstraint->projections);
#endif
ncstat = regrid3(ddsroot,dapcomm->cdf.fullddsroot,dapcomm->oc.dapconstraint->projections);
if(ncstat) goto fail;
}
@ -716,19 +691,18 @@ fetchconstrainedmetadata3(NCDAPCOMMON* nccomm)
fprintf(stderr,"constrained:\n%s",dumptree(ddsroot));
#endif
#ifdef DDSNEW
/* Combine DDS and DAS */
if(nccomm->oc.ocdasroot != NULL) {
ncstat = dapmerge3(nccomm,ddsroot,nccomm->oc.ocdasroot);
if(dapcomm->oc.ocdasroot != NULL) {
ncstat = dapmerge3(dapcomm,ddsroot,dapcomm->oc.ocdasroot);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
}
/* map the constrained DDS to the unconstrained DDS */
ncstat = mapnodes3(ddsroot,nccomm->cdf.fullddsroot);
ncstat = mapnodes3(ddsroot,dapcomm->cdf.fullddsroot);
if(ncstat) goto fail;
#else
#ifdef NOTUSED
/* Imprint the constrained DDS data over the unconstrained DDS */
ncstat = imprint3(nccomm->cdf.ddsroot,ddsroot);
ncstat = imprint3(dapcomm->cdf.ddsroot,ddsroot);
if(ncstat) goto fail;
/* Throw away the constrained DDS */
freecdfroot34(ddsroot);
@ -743,15 +717,15 @@ fail:
/* Suppress variables not in usable sequences */
NCerror
suppressunusablevars3(NCDAPCOMMON* nccomm)
suppressunusablevars3(NCDAPCOMMON* dapcomm)
{
int i,j;
int found = 1;
NClist* path = nclistnew();
while(found) {
found = 0;
for(i=0;i<nclistlength(nccomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.varnodes,i);
for(i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
/* See if this var is under an unusable sequence */
nclistclear(path);
collectnodepath3(var,path,WITHOUTDATASET);
@ -762,7 +736,7 @@ suppressunusablevars3(NCDAPCOMMON* nccomm)
#ifdef DEBUG
fprintf(stderr,"suppressing sequence var: %s\n",node->ncfullname);
#endif
nclistremove(nccomm->cdf.varnodes,i);
nclistremove(dapcomm->cdf.varnodes,i);
found = 1;
break;
}
@ -780,11 +754,11 @@ For variables which have a zero size dimension,
either use unlimited, or make them invisible.
*/
NCerror
fixzerodims3(NCDAPCOMMON* nccomm)
fixzerodims3(NCDAPCOMMON* dapcomm)
{
int i,j;
for(i=0;i<nclistlength(nccomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.varnodes,i);
for(i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
NClist* ncdims = var->array.dimensions;
if(nclistlength(ncdims) == 0) continue;
for(j=0;j<nclistlength(ncdims);j++) {
@ -792,7 +766,7 @@ fixzerodims3(NCDAPCOMMON* nccomm)
if(DIMFLAG(dim,CDFDIMUNLIM)) continue;
if(dim->dim.declsize == 0) {
if(j == 0) {/* can make it unlimited */
nclistset(ncdims,j,(ncelem)nccomm->cdf.unlimited);
nclistset(ncdims,j,(ncelem)dapcomm->cdf.unlimited);
} else { /* make node invisible */
var->visible = 0;
var->zerodim = 1;
@ -804,26 +778,26 @@ fixzerodims3(NCDAPCOMMON* nccomm)
}
void
applyclientparamcontrols3(NCDAPCOMMON* nccomm)
applyclientparamcontrols3(NCDAPCOMMON* dapcomm)
{
const char* value;
OCURI* uri = nccomm->oc.uri;
OCURI* uri = dapcomm->oc.uri;
/* enable/disable caching */
value = ocurilookup(uri,"cache");
if(value == NULL)
SETFLAG(nccomm->controls,DFALTCACHEFLAG);
SETFLAG(dapcomm->controls,DFALTCACHEFLAG);
else if(strlen(value) == 0)
SETFLAG(nccomm->controls,NCF_CACHE);
SETFLAG(dapcomm->controls,NCF_CACHE);
else if(strcmp(value,"1")==0 || value[0] == 'y')
SETFLAG(nccomm->controls,NCF_CACHE);
SETFLAG(dapcomm->controls,NCF_CACHE);
if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE))
SETFLAG(nccomm->controls,NCF_CACHE);
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
SETFLAG(dapcomm->controls,NCF_CACHE);
nclog(NCLOGNOTE,"Caching=%d",FLAGSET(nccomm->controls,NCF_CACHE));
nclog(NCLOGNOTE,"Caching=%d",FLAGSET(dapcomm->controls,NCF_CACHE));
SETFLAG(nccomm->controls,(NCF_NC3|NCF_NCDAP));
SETFLAG(dapcomm->controls,(NCF_NC3|NCF_NCDAP));
}

View File

@ -21,34 +21,33 @@
#define DFALTMODELFLAGS (NCF_NC3|NCF_NCDAP)
/* Mnemonic */
#define getncid(drno) (((NC*)drno)->ext_ncid)
ptrdiff_t dapsinglestride4[NC_MAX_VAR_DIMS];
extern NC_FILE_INFO_T* nc_file;
extern NCerror cleanNCDAP4(NCDAP4* drno);
extern NCerror cleanNCDAP4(NCDAP4*);
static void nc4dinitialize(void);
static NCerror buildnc4(NCDAP4* drno);
static NCerror builddims4(NCDAP4*);
static NCerror buildtypes4(NCDAP4*);
static NCerror buildtypes4r(NCDAP4* drno, CDFnode* tnode);
static NCerror buildvars4(NCDAP4*);
static NCerror buildglobalattrs4(NCDAP4*, int, CDFnode* root);
static NCerror buildattribute4a(NCDAP4* drno, NCattribute* att, int varid, int ncid);
static NCerror showprojection4(NCDAPCOMMON* nccomm, CDFnode* var);
static size_t estimatesizes4r(NCDAPCOMMON* nccomm, CDFnode* node);
static void estimatesizes4(NCDAPCOMMON* nccomm);
static NCerror fixzerodims4(NCDAPCOMMON* nccomm);
static NCerror fixzerodims4r(NCDAPCOMMON* nccomm, CDFnode* node);
static NCerror cvtunlimiteddim(NCDAPCOMMON* nccomm, CDFnode* dim);
static void applyclientparamcontrols4(NCDAPCOMMON* nccomm);
static NCerror buildncstructures4(NCDAPCOMMON* dapcomm);
static NCerror builddims4(NCDAPCOMMON*);
static NCerror buildtypes4(NCDAPCOMMON*);
static NCerror buildtypes4r(NCDAPCOMMON*, CDFnode* tnode);
static NCerror buildvars4(NCDAPCOMMON*);
static NCerror buildglobalattrs4(NCDAPCOMMON*, int, CDFnode* root);
static NCerror buildattribute4a(NCDAPCOMMON*, NCattribute* att, int varid);
static NCerror showprojection4(NCDAPCOMMON* dapcomm, CDFnode* var);
static size_t estimatesizes4r(NCDAPCOMMON* dapcomm, CDFnode* node);
static void estimatesizes4(NCDAPCOMMON* dapcomm);
static NCerror fixzerodims4(NCDAPCOMMON* dapcomm);
static NCerror fixzerodims4r(NCDAPCOMMON* dapcomm, CDFnode* node);
static NCerror cvtunlimiteddim(NCDAPCOMMON* dapcomm, CDFnode* dim);
static void applyclientparamcontrols4(NCDAPCOMMON* dapcomm);
static int nc4dinitialized = 0;
/**************************************************/
#ifdef NOTUSED
int
NCD4_new_nc(NC** ncpp)
{
@ -59,6 +58,7 @@ NCD4_new_nc(NC** ncpp)
if(ncpp) *ncpp = (NC*)ncp;
return NC_NOERR;
}
#endif
/**************************************************/
/* See ncd4dispatch.c for other version */
@ -71,13 +71,11 @@ NCD4_open(const char * path, int mode,
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
OCURI* tmpurl;
NCDAP4* drno = NULL; /* reuse the ncdap3 structure*/
NC_HDF5_FILE_INFO_T* h5 = NULL;
NC_GRP_INFO_T *grp = NULL;
NC* drno = NULL;
NCDAPCOMMON* dapcomm = NULL;
int ncid = -1;
char* modifiedpath = NULL;
const char* value;
int fd;
char* tmpname = NULL;
LOG((1, "nc_open_file: path %s mode %d", path, mode));
@ -110,82 +108,84 @@ ocdebug = 1;
modifiedpath = nulldup(path);
#endif
/* Use NC4 code to establish a pseudo file */
tmpname = nulldup(PSEUDOFILE);
fd = mkstemp(tmpname);
if(fd < 0) {THROWCHK(errno); goto done;}
/* Now, use the file to create the hdf5 file */
ncstat = NC4_create(tmpname,NC_NETCDF4|NC_CLOBBER,
0,0,NULL,0,NULL,dispatch,(NC**)&drno);
ncid = drno->info.ext_ncid;
/* unlink the temp file so it will automatically be reclaimed */
unlink(tmpname);
nullfree(tmpname);
/* Avoid fill */
dispatch->set_fill(ncid,NC_NOFILL,NULL);
if(ncstat)
{THROWCHK(ncstat); goto done;}
/* Find our metadata for this file. */
ncstat = nc4_find_nc_grp_h5(ncid, (NC_FILE_INFO_T**)&drno, &grp, &h5);
if(ncstat)
{THROWCHK(ncstat); goto done;}
/* Setup our NC and NCDAPCOMMON state*/
drno = (NC*)calloc(1,sizeof(NC));
if(drno == NULL) {ncstat = NC_ENOMEM; goto done;}
/* compute an ncid */
ncstat = add_to_NCList(drno);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
ncid = drno->ext_ncid;
/* Setup tentative DRNO state*/
drno->dap.controller = (NC*)drno;
drno->dap.oc.urltext = modifiedpath;
drno->dap.cdf.separator = ".";
ocuriparse(drno->dap.oc.urltext,&drno->dap.oc.uri);
if(!constrainable34(drno->dap.oc.uri))
SETFLAG(drno->dap.controls,NCF_UNCONSTRAINABLE);
drno->dap.cdf.smallsizelimit = DFALTSMALLLIMIT;
drno->dap.cdf.smallsizelimit = DFALTSMALLLIMIT;
drno->dap.cdf.cache = createnccache();
dapcomm = (NCDAPCOMMON*)calloc(1,sizeof(NCDAPCOMMON));
if(dapcomm == NULL) {ncstat = NC_ENOMEM; goto done;}
drno->dispatch = dispatch;
drno->dispatchdata = dapcomm;
dapcomm->controller = (NC*)drno;
dapcomm->cdf.separator = ".";
dapcomm->oc.urltext = modifiedpath;
ocuriparse(dapcomm->oc.urltext,&dapcomm->oc.uri);
if(!constrainable34(dapcomm->oc.uri))
SETFLAG(dapcomm->controls,NCF_UNCONSTRAINABLE);
dapcomm->cdf.smallsizelimit = DFALTSMALLLIMIT;
dapcomm->cdf.cache = createnccache();
#ifdef IGNORE
drno->dap.cdf.cache->cachelimit = DFALTCACHELIMIT;
drno->dap.cdf.cache->cachesize = 0;
drno->dap.cdf.cache->nodes = nclistnew();
drno->dap.cdf.cache->cachecount = DFALTCACHECOUNT;
dapcomm->cdf.cache->cachelimit = DFALTCACHELIMIT;
dapcomm->cdf.cache->cachesize = 0;
dapcomm->cdf.cache->nodes = nclistnew();
dapcomm->cdf.cache->cachecount = DFALTCACHECOUNT;
#endif
#ifdef HAVE_GETRLIMIT
{ struct rlimit rl;
if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
drno->dap.cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2);
dapcomm->cdf.cache->cachecount = (size_t)(rl.rlim_cur / 2);
}
}
#endif
drno->info.dispatch = dispatch;
/* Use libsrc4 code for storing metadata */
tmpname = nulldup(PSEUDOFILE);
/* Now, use the file to create the netcdf file */
ncstat = nc_create(tmpname,NC_CLOBBER|NC_NETCDF4,&drno->substrate);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
/* free the filename so it will automatically go away*/
unlink(tmpname);
nullfree(tmpname);
/* Avoid fill */
nc_set_fill(drno->ext_ncid,NC_NOFILL,NULL);
/* Re-scan the client parameters */
applyclientparamcontrols4(&drno->dap);
applyclientparamcontrols4(dapcomm);
if(ncpp) *ncpp = (NC*)drno;
drno->dap.oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
drno->dap.oc.dapconstraint->projections = nclistnew();
drno->dap.oc.dapconstraint->selections = nclistnew();
dapcomm->oc.dapconstraint = (DCEconstraint*)dcecreate(CES_CONSTRAINT);
dapcomm->oc.dapconstraint->projections = nclistnew();
dapcomm->oc.dapconstraint->selections = nclistnew();
/* Check to see if we are unconstrainable */
if(FLAGSET(drno->dap.controls,NCF_UNCONSTRAINABLE)) {
if(drno->dap.oc.uri->constraint != NULL
&& strlen(drno->dap.oc.uri->constraint) > 0) {
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE)) {
if(dapcomm->oc.uri->constraint != NULL
&& strlen(dapcomm->oc.uri->constraint) > 0) {
nclog(NCLOGWARN,"Attempt to constrain an unconstrainable data source: %s",
drno->dap.oc.uri->constraint);
dapcomm->oc.uri->constraint);
}
/* ignore all constraints */
} else {
/* Parse constraints to make sure that they are syntactically correct */
ncstat = parsedapconstraints(&drno->dap,drno->dap.oc.uri->constraint,drno->dap.oc.dapconstraint);
ncstat = parsedapconstraints(dapcomm,dapcomm->oc.uri->constraint,dapcomm->oc.dapconstraint);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
}
ocstat = oc_open(drno->dap.oc.urltext,&drno->dap.oc.conn);
ocstat = oc_open(dapcomm->oc.urltext,&dapcomm->oc.conn);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;}
if(paramcheck34(&drno->dap,"show","fetch"))
SETFLAG(drno->dap.controls,NCF_SHOWFETCH);
if(paramcheck34(dapcomm,"show","fetch"))
SETFLAG(dapcomm->controls,NCF_SHOWFETCH);
/* Turn on logging */
value = oc_clientparam_get(drno->dap.oc.conn,"log");
value = oc_clientparam_get(dapcomm->oc.conn,"log");
if(value != NULL) {
ncloginit();
ncsetlogging(1);
@ -195,101 +195,108 @@ ocdebug = 1;
oc_logopen(value);
}
/* fetch and build the unconstrained DDS */
ncstat = fetchtemplatemetadata3(&drno->dap);
/* fetch and build the (almost) unconstrained DDS */
ncstat = fetchtemplatemetadata3(dapcomm);
if(ncstat != NC_NOERR) goto done;
/* fetch and build the constrained DDS */
ncstat = fetchconstrainedmetadata3(&drno->dap);
ncstat = fetchconstrainedmetadata3(dapcomm);
if(ncstat != NC_NOERR) goto done;
/* The following actions are WRT to the constrained tree */
/* Process the constraints to map the CDF tree */
ncstat = mapconstraints3(drno->dap.oc.dapconstraint,drno->dap.cdf.ddsroot);
ncstat = mapconstraints3(dapcomm->oc.dapconstraint,dapcomm->cdf.ddsroot);
if(ncstat != NC_NOERR) goto done;
/* Accumulate useful nodes sets */
ncstat = computecdfnodesets4(&drno->dap);
ncstat = computecdfnodesets4(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Fix grids */
ncstat = fixgrids4(&drno->dap);
ncstat = fixgrids4(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* apply client parameters (after computcdfinfo and computecdfvars)*/
ncstat = applyclientparams34(&drno->dap);
ncstat = applyclientparams34(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Accumulate the nodes representing user types*/
ncstat = computeusertypes4(&drno->dap);
ncstat = computeusertypes4(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Re-compute the type names*/
ncstat = shortentypenames4(&drno->dap);
ncstat = shortentypenames4(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Re-compute the dimension names*/
ncstat = computecdfdimnames34(&drno->dap);
ncstat = computecdfdimnames34(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* deal with zero-size dimensions */
ncstat = fixzerodims4(&drno->dap);
ncstat = fixzerodims4(dapcomm);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Estimate the variable sizes */
estimatesizes4(&drno->dap);
estimatesizes4(dapcomm);
ncstat = buildnc4(drno);
ncstat = buildncstructures4(dapcomm);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
/* Do any necessary data prefetch */
ncstat = prefetchdata3(&drno->dap);
ncstat = prefetchdata3(dapcomm);
if(ncstat != NC_NOERR)
{THROWCHK(ncstat); goto done;}
/* Mark as no longer indef and no longer writable*/
h5->flags &= ~(NC_INDEF);
h5->no_write = 1;
{
/* Mark as no longer writable and no longer indef;
requires breaking abstraction */
NC* nc;
NC_FILE_INFO_T* nfit = NULL;
NC_HDF5_FILE_INFO_T* h5 = NULL;
NC_GRP_INFO_T *grp = NULL;
ncstat = NC_check_id(drno->substrate, &nc);
/* Find our metadata for this file. */
ncstat = nc4_find_nc_grp_h5(drno->substrate, &nfit, &grp, &h5);
if(ncstat) {THROWCHK(ncstat); goto done;}
/* Mark as no longer indef (do NOT use nc_enddef until diskless is working)*/
h5->flags &= ~(NC_INDEF);
/* Mark as no longer writeable */
h5->no_write = 1;
}
if(ncpp) *ncpp = (NC*)drno;
return ncstat;
done:
if(drno != NULL) {
int ncid = drno->info.ext_ncid;
cleanNCDAP4(drno);
NC4_abort(ncid);
}
if(drno != NULL) NCD4_abort(drno->ext_ncid);
if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
return THROW(ncstat);
}
int
NCD4_close(int ncid)
NCD4_abort(int ncid)
{
NC_GRP_INFO_T *grp;
NC_HDF5_FILE_INFO_T *h5;
NCDAP4* drno = NULL;
NC* drno;
NCDAPCOMMON* dapcomm;
int ncstat = NC_NOERR;
LOG((1, "nc_close: ncid 0x%x", ncid));
LOG((1, "nc_abort: ncid 0x%x", ncid));
/* Avoid repeated close */
ncstat = NC_check_id(ncid, (NC**)&drno);
if(ncstat != NC_NOERR) return THROW(ncstat);
/* Find our metadata for this file. */
ncstat = nc4_find_nc_grp_h5(ncid, (NC_FILE_INFO_T**)&drno, &grp, &h5);
if(ncstat != NC_NOERR) return THROW(ncstat);
/* This must be the root group. */
if (grp->parent) ncstat = NC_EBADGRPID;
/* Destroy/close the NCDAP4 state */
cleanNCDAP4(drno);
NC4_abort(ncid);
dapcomm = (NCDAPCOMMON*)drno->dispatchdata;
ncstat = nc_abort(drno->substrate);
/* remove ourselves from NClist */
del_from_NCList(drno);
/* clean NC* */
cleanNCDAPCOMMON(dapcomm);
if(drno->path != NULL) free(drno->path);
free(drno);
return THROW(ncstat);
}
@ -304,49 +311,49 @@ nc4dinitialize()
nc4dinitialized = 1;
}
NCerror
cleanNCDAP4(NCDAP4* drno)
{
return cleanNCDAPCOMMON(&drno->dap);
}
/*
Note: never use any of the libncdap3 code to call
netcdf API functions because it will use the netcdf-3 API.
*/
static NCerror
buildnc4(NCDAP4* drno)
buildncstructures4(NCDAPCOMMON* dapcomm)
{
NCerror ncstat = NC_NOERR;
CDFnode* dds = drno->dap.cdf.ddsroot;
ncstat = buildglobalattrs4(drno,getncid(drno),dds);
CDFnode* dds = dapcomm->cdf.ddsroot;
NC* drno = dapcomm->controller;
ncstat = buildglobalattrs4(dapcomm,drno->substrate,dds);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
ncstat = builddims4(drno);
ncstat = builddims4(dapcomm);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
ncstat = buildtypes4(drno);
ncstat = buildtypes4(dapcomm);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
ncstat = buildvars4(drno);
ncstat = buildvars4(dapcomm);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
done:
return THROW(ncstat);
}
/* Define dim info for top-level dims */
static NCerror
builddims4(NCDAP4* drno)
builddims4(NCDAPCOMMON* dapcomm)
{
unsigned int i,j;
NCerror ncstat = NC_NOERR;
int dimid;
int ncid = getncid(drno);
NClist* dimset = nclistnew();
NC* drno = dapcomm->controller;
/* collect all dimensions from variables,
including duplicates; note we use array.dimensions
not array.ncdimensions.
*/
for(i=0;i<nclistlength(drno->dap.cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(drno->dap.cdf.varnodes,i);
for(i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
if(!var->visible) continue;
nclistextend(dimset,nclistlength(var->array.dimensions));
for(j=0;j<nclistlength(var->array.dimensions);j++) {
@ -360,6 +367,7 @@ builddims4(NCDAP4* drno)
inserted = 1;
break;
}
}
if(!inserted) nclistpush(dimset,(ncelem)dim);
}
@ -369,7 +377,10 @@ builddims4(NCDAP4* drno)
for(i=0;i<nclistlength(dimset);i++) {
CDFnode* dim = (CDFnode*)nclistget(dimset,i);
if(dim->dim.basedim != NULL) continue;
ncstat = nc_def_dim(ncid,dim->ncfullname,dim->dim.declsize,&dimid);
ncstat = nc_def_dim(drno->substrate,
dim->ncfullname,
dim->dim.declsize,
&dimid);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
dim->ncid = dimid;
}
@ -389,16 +400,16 @@ done:
}
static NCerror
buildtypes4(NCDAP4* drno)
buildtypes4(NCDAPCOMMON* dapcomm)
{
unsigned int i;
NCerror ncstat = NC_NOERR;
/* Define user types in postorder */
for(i=0;i<nclistlength(drno->dap.cdf.usertypes);i++) {
CDFnode* node = (CDFnode*)nclistget(drno->dap.cdf.usertypes,i);
for(i=0;i<nclistlength(dapcomm->cdf.usertypes);i++) {
CDFnode* node = (CDFnode*)nclistget(dapcomm->cdf.usertypes,i);
if(!node->visible) continue;
ncstat = buildtypes4r(drno,node);
ncstat = buildtypes4r(dapcomm,node);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
}
done:
@ -406,11 +417,12 @@ done:
}
static NCerror
buildtypes4r(NCDAP4* drno, CDFnode* tnode)
buildtypes4r(NCDAPCOMMON* dapcomm, CDFnode* tnode)
{
unsigned int i,j;
int typeid;
NCerror ncstat = NC_NOERR;
NC* drno = dapcomm->controller;
if(!tnode->visible) goto done;
@ -426,7 +438,7 @@ buildtypes4r(NCDAP4* drno, CDFnode* tnode)
/* Find the first primitive visible field */
CDFnode* prim = getsingletonfield(tnode->subnodes);
ASSERT((prim != NULL));
ncstat = nc_def_vlen(getncid(drno),tnode->vlenname,
ncstat = nc_def_vlen(drno->substrate,tnode->vlenname,
prim->etype,&typeid);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
tnode->basetypeid = prim->etype;
@ -436,7 +448,7 @@ buildtypes4r(NCDAP4* drno, CDFnode* tnode)
/* fall thru */
case NC_Grid:
case NC_Structure:
ncstat = nc_def_compound(getncid(drno),tnode->typesize.instance.size,
ncstat = nc_def_compound(drno->substrate,tnode->typesize.instance.size,
tnode->typename,&typeid);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
tnode->typeid = typeid;
@ -444,7 +456,7 @@ buildtypes4r(NCDAP4* drno, CDFnode* tnode)
CDFnode* field = (CDFnode*)nclistget(tnode->subnodes,i);
if(!field->visible) continue;
if(nclistlength(field->array.dimensions) == 0) {
ncstat = nc_insert_compound(getncid(drno),typeid,
ncstat = nc_insert_compound(drno->substrate,typeid,
field->ncbasename,
field->typesize.field.offset,
field->typeid);
@ -455,7 +467,7 @@ buildtypes4r(NCDAP4* drno, CDFnode* tnode)
CDFnode* dim=(CDFnode*)nclistget(field->array.dimensions,j);
dimsizes[j] = dim->dim.declsize;
}
ncstat = nc_insert_array_compound(getncid(drno),typeid,
ncstat = nc_insert_array_compound(drno->substrate,typeid,
field->ncbasename,
field->typesize.field.offset,
field->typeid,
@ -466,7 +478,7 @@ buildtypes4r(NCDAP4* drno, CDFnode* tnode)
}
/* If the node is a sequence, also define the corresponding vlen type*/
if(tnode->nctype == NC_Sequence) {
ncstat = nc_def_vlen(getncid(drno),tnode->vlenname,tnode->typeid,&typeid);
ncstat = nc_def_vlen(drno->substrate,tnode->vlenname,tnode->typeid,&typeid);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
tnode->basetypeid = typeid;
tnode->typeid = typeid;
@ -485,17 +497,17 @@ done:
/* Simultaneously build any associated attributes */
static NCerror
buildvars4(NCDAP4* drno)
buildvars4(NCDAPCOMMON* dapcomm)
{
/* Variables (in this translation) are (mostly)
the direct fields of the Dataset*/
unsigned int i,j;
NCerror ncstat = NC_NOERR;
int varid;
int ncid = getncid(drno);
NC* drno = dapcomm->controller;
for(i=0;i<nclistlength(drno->dap.cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(drno->dap.cdf.varnodes,i);
for(i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
NClist* vardims = var->array.dimensions;
int dimids[NC_MAX_VAR_DIMS];
int ncrank,dimindex=0;
@ -510,9 +522,9 @@ buildvars4(NCDAP4* drno)
dimids[dimindex++] = dim->ncid;
}
}
setvarbasetype(&drno->dap,var);
setvarbasetype(dapcomm,var);
ASSERT((var->typeid > 0));
ncstat = nc_def_var(getncid(drno),var->ncfullname,
ncstat = nc_def_var(drno->substrate,var->ncfullname,
var->typeid,
nclistlength(var->array.dimensions),
(ncrank==0?NULL:dimids),
@ -522,13 +534,13 @@ buildvars4(NCDAP4* drno)
if(var->attributes != NULL) {
for(j=0;j<nclistlength(var->attributes);j++) {
NCattribute* att = (NCattribute*)nclistget(var->attributes,j);
ncstat = buildattribute4a(drno,att,varid,ncid);
ncstat = buildattribute4a(dapcomm,att,varid);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
}
}
/* Tag the variable with its DAP path */
if(paramcheck34(&drno->dap,"show","projection"))
showprojection4(&drno->dap,var);
if(paramcheck34(dapcomm,"show","projection"))
showprojection4(dapcomm,var);
}
done:
@ -536,17 +548,17 @@ done:
}
static NCerror
buildglobalattrs4(NCDAP4* drno, int ncid, CDFnode* root)
buildglobalattrs4(NCDAPCOMMON* dapcomm, int ncid, CDFnode* root)
{
int i;
const char* txt;
char *nltxt, *p;
NCerror ncstat = NC_NOERR;
NC* drno = dapcomm->controller;
if(root->attributes != NULL) {
for(i=0;i<nclistlength(root->attributes);i++) {
NCattribute* att = (NCattribute*)nclistget(root->attributes,i);
ncstat = buildattribute4a(drno,att,NC_GLOBAL,ncid);
ncstat = buildattribute4a(dapcomm,att,NC_GLOBAL);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
}
}
@ -555,37 +567,37 @@ buildglobalattrs4(NCDAP4* drno, int ncid, CDFnode* root)
on show= clientparams*/
/* Ignore doneures*/
if(paramcheck34(&drno->dap,"show","translate")) {
if(paramcheck34(dapcomm,"show","translate")) {
/* Add a global attribute to show the translation */
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_translate",
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_translate",
strlen("netcdf-4"),"netcdf-4");
}
if(paramcheck34(&drno->dap,"show","url")) {
if(drno->dap.oc.urltext != NULL)
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_url",
strlen(drno->dap.oc.urltext),drno->dap.oc.urltext);
if(paramcheck34(dapcomm,"show","url")) {
if(dapcomm->oc.urltext != NULL)
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_url",
strlen(dapcomm->oc.urltext),dapcomm->oc.urltext);
}
if(paramcheck34(&drno->dap,"show","dds")) {
if(paramcheck34(dapcomm,"show","dds")) {
txt = NULL;
if(drno->dap.cdf.ddsroot != NULL)
txt = oc_inq_text(drno->dap.oc.conn,drno->dap.cdf.ddsroot->dds);
if(dapcomm->cdf.ddsroot != NULL)
txt = oc_inq_text(dapcomm->oc.conn,dapcomm->cdf.ddsroot->dds);
if(txt != NULL) {
/* replace newlines with spaces*/
nltxt = nulldup(txt);
for(p=nltxt;*p;p++) {if(*p == '\n' || *p == '\r' || *p == '\t') {*p = ' ';}};
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_DDS",strlen(nltxt),nltxt);
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_DDS",strlen(nltxt),nltxt);
nullfree(nltxt);
}
}
if(paramcheck34(&drno->dap,"show","das")) {
if(paramcheck34(dapcomm,"show","das")) {
txt = NULL;
if(drno->dap.oc.ocdasroot != OCNULL)
txt = oc_inq_text(drno->dap.oc.conn,drno->dap.oc.ocdasroot);
if(dapcomm->oc.ocdasroot != OCNULL)
txt = oc_inq_text(dapcomm->oc.conn,dapcomm->oc.ocdasroot);
if(txt != NULL) {
nltxt = nulldup(txt);
for(p=nltxt;*p;p++) {if(*p == '\n' || *p == '\r' || *p == '\t') {*p = ' ';}};
ncstat = nc_put_att_text(ncid,NC_GLOBAL,"_DAS",strlen(nltxt),nltxt);
ncstat = nc_put_att_text(drno->substrate,NC_GLOBAL,"_DAS",strlen(nltxt),nltxt);
nullfree(nltxt);
}
}
@ -595,16 +607,17 @@ done:
}
static NCerror
buildattribute4a(NCDAP4* drno, NCattribute* att, int varid, int ncid)
buildattribute4a(NCDAPCOMMON* dapcomm, NCattribute* att, int varid)
{
NCerror ncstat = NC_NOERR;
char* cname = cdflegalname3(att->name);
unsigned int nvalues = nclistlength(att->values);
unsigned int typesize = nctypesizeof(att->etype);
void* mem = malloc(typesize * nvalues);
NC* drno = dapcomm->controller;
ncstat = dapcvtattrval3(att->etype,mem,att->values);
ncstat = nc_put_att(ncid,varid,cname,att->etype,nvalues,mem);
ncstat = nc_put_att(drno->substrate,varid,cname,att->etype,nvalues,mem);
if(att->etype == NC_STRING) {
int i;
for(i=0;i<nvalues;i++) nullfree(((char**)mem)[i]);
@ -615,12 +628,13 @@ buildattribute4a(NCDAP4* drno, NCattribute* att, int varid, int ncid)
}
static NCerror
showprojection4(NCDAPCOMMON* nccomm, CDFnode* var)
showprojection4(NCDAPCOMMON* dapcomm, CDFnode* var)
{
int i,rank;
NCerror ncstat = NC_NOERR;
NCbytes* projection = ncbytesnew();
NClist* path = nclistnew();
NC* drno = dapcomm->controller;
/* If this is not a true leaf variable, then ignore it */
if(var->nctype == NC_Sequence) return NC_NOERR;
@ -643,7 +657,7 @@ showprojection4(NCDAPCOMMON* nccomm, CDFnode* var)
ncbytescat(projection,"]");
}
/* Define the attribute */
ncstat = nc_put_att_text(getncid(nccomm),var->ncid,
ncstat = nc_put_att_text(drno->substrate,var->ncid,
"_projection",
ncbyteslength(projection),
ncbytescontents(projection));
@ -666,7 +680,7 @@ cdftotalsize4(NClist* dimensions)
}
static size_t
estimatesizes4r(NCDAPCOMMON* nccomm, CDFnode* node)
estimatesizes4r(NCDAPCOMMON* dapcomm, CDFnode* node)
{
int i;
size_t size = 0;
@ -677,7 +691,7 @@ estimatesizes4r(NCDAPCOMMON* nccomm, CDFnode* node)
for(i=0;i<nclistlength(node->subnodes);i++) {
CDFnode* subnode = (CDFnode*)nclistget(node->subnodes,i);
size += estimatesizes4r(nccomm,subnode);
size += estimatesizes4r(dapcomm,subnode);
}
switch (node->nctype) {
case NC_Primitive:
@ -713,12 +727,12 @@ fprintf(stderr,"estimatedsize: %s%s/%u = %lu (= %lu = %lu * %lu)\n",
static void
estimatesizes4(NCDAPCOMMON* nccomm)
estimatesizes4(NCDAPCOMMON* dapcomm)
{
size_t totalsize;
CDFnode* root = nccomm->cdf.ddsroot;
CDFnode* root = dapcomm->cdf.ddsroot;
/* Recursively compute the sizes of each node */
totalsize = estimatesizes4r(nccomm,root);
totalsize = estimatesizes4r(dapcomm,root);
}
/*
@ -726,19 +740,19 @@ For variables which have a zero size dimension,
either use unlimited, or make them invisible.
*/
static NCerror
fixzerodims4(NCDAPCOMMON* nccomm)
fixzerodims4(NCDAPCOMMON* dapcomm)
{
int i;
NCerror ncstat = NC_NOERR;
for(i=0;i<nclistlength(nccomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(nccomm->cdf.varnodes,i);
ncstat = fixzerodims4r(nccomm,var);
for(i=0;i<nclistlength(dapcomm->cdf.varnodes);i++) {
CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.varnodes,i);
ncstat = fixzerodims4r(dapcomm,var);
}
return ncstat;
}
static NCerror
fixzerodims4r(NCDAPCOMMON* nccomm, CDFnode* node)
fixzerodims4r(NCDAPCOMMON* dapcomm, CDFnode* node)
{
int i;
NCerror ncstat = NC_NOERR;
@ -747,7 +761,7 @@ fixzerodims4r(NCDAPCOMMON* nccomm, CDFnode* node)
CDFnode* dim = (CDFnode*)nclistget(node->array.dimensions,i);
if(dim->dim.declsize == 0) {
if(node->container->nctype == NC_Dataset) { /* use unlimited */
ncstat = cvtunlimiteddim(nccomm,dim);
ncstat = cvtunlimiteddim(dapcomm,dim);
} else { /* make node invisible */
node->visible = 0;
node->zerodim = 1;
@ -758,35 +772,35 @@ fixzerodims4r(NCDAPCOMMON* nccomm, CDFnode* node)
/* walk the subnodes */
for(i=0;i<nclistlength(node->subnodes);i++) {
CDFnode* subnode = (CDFnode*)nclistget(node->subnodes,i);
ncstat = fixzerodims4r(nccomm,subnode);
ncstat = fixzerodims4r(dapcomm,subnode);
}
return ncstat;
}
/* Convert a dimension to unlimited */
static NCerror
cvtunlimiteddim(NCDAPCOMMON* nccomm, CDFnode* dim)
cvtunlimiteddim(NCDAPCOMMON* dapcomm, CDFnode* dim)
{
DIMFLAGSET(dim,CDFDIMUNLIM);
nccomm->cdf.unlimited = dim;
dapcomm->cdf.unlimited = dim;
return NC_NOERR;
}
static void
applyclientparamcontrols4(NCDAPCOMMON* nccomm)
applyclientparamcontrols4(NCDAPCOMMON* dapcomm)
{
OCURI* uri = nccomm->oc.uri;
OCURI* uri = dapcomm->oc.uri;
const char* value;
/* enable/disable caching */
value = ocurilookup(uri,"cache");
if(value == NULL)
SETFLAG(nccomm->controls,DFALTCACHEFLAG);
SETFLAG(dapcomm->controls,DFALTCACHEFLAG);
else if(strlen(value) == 0)
SETFLAG(nccomm->controls,NCF_CACHE);
SETFLAG(dapcomm->controls,NCF_CACHE);
else if(strcmp(value,"1")==0 || value[0] == 'y')
SETFLAG(nccomm->controls,NCF_CACHE);
SETFLAG(dapcomm->controls,NCF_CACHE);
/* Set the translation base */
SETFLAG(nccomm->controls,NCF_NC4);
SETFLAG(dapcomm->controls,NCF_NC4);
}

View File

@ -19,7 +19,8 @@ libdispatch_la_SOURCES = dparallel.c dcopy.c dfile.c ddim.c datt.c \
dattinq.c dattput.c dattget.c derror.c dvar.c dvarget.c dvarput.c \
dvarinq.c ddispatch.c \
dnclog.c dstring.c dutf8proc.c utf8proc_data.h \
nc_uri.c nclist.c ncbytes.c nchashmap.c
nc_uri.c nclist.c ncbytes.c nchashmap.c nctime.c \
dsubstrate.c
# Add functions only found in netCDF-4.
if USE_NETCDF4

View File

@ -1,6 +1,8 @@
#include "ncdispatch.h"
#include "nc_uri.h"
extern int NCSUBSTRATE_intialize(void);
#define INITCOORD1 if(coord_one[0] != 1) {int i; for(i=0;i<NC_MAX_VAR_DIMS;i++) coord_one[i] = 1;}
/* Define the known protocols and their manipulations */
@ -26,6 +28,7 @@ static nc_type longtype = (sizeof(long) == sizeof(int)?NC_INT:NC_INT64);
static nc_type ulongtype = (sizeof(unsigned long) == sizeof(unsigned int)?NC_UINT:NC_UINT64);
*/
NC_Dispatch* NCSUBSTRATE_dispatch_table = NULL;
NC_Dispatch* NC3_dispatch_table = NULL;
NC_Dispatch* NCD_dispatch_table = NULL;
@ -33,6 +36,7 @@ NC_Dispatch* NCD_dispatch_table = NULL;
NC_Dispatch* NC4_dispatch_table = NULL;
#endif
#ifdef IGNORE
#ifdef USE_DAP
NC_Dispatch* NCD3_dispatch_table = NULL;
#endif
@ -45,6 +49,16 @@ NC_Dispatch* NCD4_dispatch_table = NULL;
NC_Dispatch* NCCR_dispatch_table = NULL;
#endif
#endif /*IGNORE*/
/* Allow dispatch to do initialization */
int
NCDISPATCH_initialize(void)
{
NCSUBSTRATE_initialize();
return NC_NOERR;
}
/* return 1 if path looks like a url; 0 otherwise */
int
NC_testurl(const char* path)

913
libdispatch/dsubstrate.c Normal file
View File

@ -0,0 +1,913 @@
/** \substrate
Define the substrate dispatch table and functions
These functions end up calling functions in one of the dispatch layers
(netCDF-4, dap server, etc) using the substrate field of struct NC.
Copyright 2010 University Corporation for Atmospheric
Research/Unidata. See COPYRIGHT file for more info.
*/
#include "netcdf.h"
#include "ncdispatch.h"
/* forward */
static NC_Dispatch NCSUBSTRATE_dispatch_base;
/*
Note that because many of the signatures differ
from the netcdf API, we need to break
the abstraction and invoke the
substrate dispatch table directly.
*/
int
NCSUBSTRATE_initialize(void)
{
NCSUBSTRATE_dispatch_table = &NCSUBSTRATE_dispatch_base;
return NC_NOERR;
}
static int
NCSUB_new_nc(NC** ncp)
{
NC* nc;
/* Allocate memory for this info. */
if (!(nc = calloc(1, sizeof(struct NC))))
return NC_ENOMEM;
if(ncp) *ncp = nc;
return NC_NOERR;
}
static int
NCSUB_redef(int ncid)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate,&ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->redef(nc->substrate);
}
static int
NCSUB__enddef(int ncid, size_t a1, size_t a2, size_t a3, size_t a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->_enddef(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_sync(int ncid)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->sync(nc->substrate);
}
static int
NCSUB_abort(int ncid)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->abort(nc->substrate);
}
static int
NCSUB_close(int ncid)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->close(nc->substrate);
}
static int
NCSUB_set_fill(int ncid, int a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->set_fill(nc->substrate,a1,a2);
}
static int
NCSUB_inq_base_pe(int ncid, int* a1)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_base_pe(nc->substrate,a1);
}
static int
NCSUB_set_base_pe(int ncid, int a1)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->set_base_pe(nc->substrate,a1);
}
static int
NCSUB_inq_format(int ncid, int* a1)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_format(nc->substrate,a1);
}
static int
NCSUB_inq(int ncid, int* a1, int* a2, int* a3, int* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_inq_type(int ncid, nc_type a1, char* a2, size_t* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_type(nc->substrate,a1,a2,a3);
}
static int
NCSUB_def_dim(int ncid, const char* a1, size_t a2, int* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_dim(nc->substrate,a1,a2,a3);
}
static int
NCSUB_inq_dimid(int ncid, const char* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_dimid(nc->substrate,a1,a2);
}
static int
NCSUB_inq_dim(int ncid, int a1, char* a2, size_t* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_dim(nc->substrate,a1,a2,a3);
}
static int
NCSUB_inq_unlimdim(int ncid, int* a1)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_unlimdim(nc->substrate,a1);
}
static int
NCSUB_rename_dim(int ncid, int a1, const char* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->rename_dim(nc->substrate,a1,a2);
}
static int
NCSUB_inq_att(int ncid, int a1, const char* a2, nc_type* a3, size_t* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_att(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_inq_attid(int ncid, int a1, const char* a2, int* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_attid(nc->substrate,a1,a2,a3);
}
static int
NCSUB_inq_attname(int ncid, int a1, int a2, char* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_attname(nc->substrate,a1,a2,a3);
}
static int
NCSUB_rename_att(int ncid, int a1, const char* a2, const char* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->rename_att(nc->substrate,a1,a2,a3);
}
static int
NCSUB_del_att(int ncid, int a1, const char* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->del_att(nc->substrate,a1,a2);
}
static int
NCSUB_get_att(int ncid, int a1, const char* a2, void* a3, nc_type a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->get_att(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_put_att(int ncid, int a1, const char* a2, nc_type a3, size_t a4, const void* a5, nc_type a6)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->put_att(nc->substrate,a1,a2,a3,a4,a5,a6);
}
static int
NCSUB_def_var(int ncid, const char* a1, nc_type a2, int a3, const int* a4, int* a5)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_var(nc->substrate,a1,a2,a3,a4,a5);
}
static int
NCSUB_inq_varid(int ncid, const char* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_varid(nc->substrate,a1,a2);
}
static int
NCSUB_rename_var(int ncid, int a1, const char* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->rename_var(nc->substrate,a1,a2);
}
static int
NCSUB_get_vara(int ncid, int a1, const size_t* a2, const size_t* a3, void* a4, nc_type a5)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->get_vara(nc->substrate,a1,a2,a3,a4,a5);
}
static int
NCSUB_put_vara(int ncid, int a1, const size_t* a2, const size_t* a3, const void* a4, nc_type a5)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->put_vara(nc->substrate,a1,a2,a3,a4,a5);
}
/* Added to solve Ferret performance problem with Opendap */
static int
NCSUB_get_vars(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, void* a5, nc_type a6)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->get_vars(nc->substrate,a1,a2,a3,a4,a5,a6);
}
static int
NCSUB_put_vars(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, const void* a5, nc_type a6)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->put_vars(nc->substrate,a1,a2,a3,a4,a5,a6);
}
static int
NCSUB_get_varm(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, const ptrdiff_t* a5, void* a6, nc_type a7)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->get_varm(nc->substrate,a1,a2,a3,a4,a5,a6,a7);
}
static int
NCSUB_put_varm(int ncid, int a1, const size_t* a2, const size_t* a3, const ptrdiff_t* a4, const ptrdiff_t* a5, const void* a6, nc_type a7)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->put_varm(nc->substrate,a1,a2,a3,a4,a5,a6,a7);
}
static int
NCSUB_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,
int* options_maskp, int* pixels_per_blockp)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_var_all(nc->substrate,varid,name,xtypep,
ndimsp,dimidsp,nattsp,shufflep,
deflatep,deflate_levelp,fletcher32p,
contiguousp,chunksizesp,
no_fill,fill_valuep,
endiannessp,
options_maskp,pixels_per_blockp);
}
#ifdef USE_NETCDF4
static int
NCSUB_show_metadata(int ncid)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->show_metadata(nc->substrate);
}
static int
NCSUB_inq_unlimdims(int ncid, int* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_unlimdims(nc->substrate,a1,a2);
}
static int
NCSUB_var_par_access(int ncid, int a1, int a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->var_par_access(nc->substrate,a1,a2);
}
static int
NCSUB_inq_ncid(int ncid, const char* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_ncid(nc->substrate,a1,a2);
}
static int
NCSUB_inq_grps(int ncid, int* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_grps(nc->substrate,a1,a2);
}
static int
NCSUB_inq_grpname(int ncid, char* a1)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_grpname(nc->substrate,a1);
}
static int
NCSUB_inq_grpname_full(int ncid, size_t* a1, char* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_grpname_full(nc->substrate,a1,a2);
}
static int
NCSUB_inq_grp_parent(int ncid, int* a1)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_grp_parent(nc->substrate,a1);
}
static int
NCSUB_inq_grp_full_ncid(int ncid, const char* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_grp_full_ncid(nc->substrate,a1,a2);
}
static int
NCSUB_inq_varids(int ncid, int* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_varids(nc->substrate,a1,a2);
}
static int
NCSUB_inq_dimids(int ncid, int* a1, int* a2, int a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_dimids(nc->substrate,a1,a2,a3);
}
static int
NCSUB_inq_typeids(int ncid, int* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_typeids(nc->substrate,a1,a2);
}
static int
NCSUB_inq_type_equal(int ncid, nc_type a1, int a2, nc_type a3, int* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_type_equal(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_def_grp(int ncid, const char* a1, int* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_grp(nc->substrate,a1,a2);
}
static int
NCSUB_inq_user_type(int ncid, nc_type a1, char* a2, size_t* a3, nc_type* a4, size_t* a5, int* a6)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_user_type(nc->substrate,a1,a2,a3,a4,a5,a6);
}
static int
NCSUB_inq_typeid(int ncid, const char* a1, nc_type* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_typeid(nc->substrate,a1,a2);
}
static int
NCSUB_def_compound(int ncid, size_t a1, const char* a2, nc_type* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_compound(nc->substrate,a1,a2,a3);
}
static int
NCSUB_insert_compound(int ncid, nc_type a1, const char* a2, size_t a3, nc_type a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->insert_compound(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_insert_array_compound(int ncid, nc_type a1, const char* a2, size_t a3, nc_type a4, int a5, const int* a6)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->insert_array_compound(nc->substrate,a1,a2,a3,a4,a5,a6);
}
static int
NCSUB_inq_compound_field(int ncid, nc_type a1, int a2, char* a3, size_t* a4, nc_type* a5, int* a6, int* a7)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_compound_field(nc->substrate,a1,a2,a3,a4,a5,a6,a7);
}
static int
NCSUB_inq_compound_fieldindex(int ncid, nc_type a1, const char* a2, int* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_compound_fieldindex(nc->substrate,a1,a2,a3);
}
static int
NCSUB_def_vlen(int ncid, const char* a1, nc_type a2, nc_type* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_vlen(nc->substrate,a1,a2,a3);
}
static int
NCSUB_put_vlen_element(int ncid, int a1, void* a2, size_t a3, const void* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->put_vlen_element(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_get_vlen_element(int ncid, int a1, const void* a2, size_t* a3, void* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->get_vlen_element(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_def_enum(int ncid, nc_type a1, const char* a2, nc_type* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_enum(nc->substrate,a1,a2,a3);
}
static int
NCSUB_insert_enum(int ncid, nc_type a1, const char* a2, const void* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->insert_enum(nc->substrate,a1,a2,a3);
}
static int
NCSUB_inq_enum_member(int ncid, nc_type a1, int a2, char* a3, void* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_enum_member(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_inq_enum_ident(int ncid, nc_type a1, long long a2, char* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->inq_enum_ident(nc->substrate,a1,a2,a3);
}
static int
NCSUB_def_opaque(int ncid, size_t a1, const char* a2, nc_type* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_opaque(nc->substrate,a1,a2,a3);
}
static int
NCSUB_def_var_deflate(int ncid, int a1, int a2, int a3, int a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_var_deflate(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_def_var_fletcher32(int ncid, int a1, int a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_var_fletcher32(nc->substrate,a1,a2);
}
static int
NCSUB_def_var_chunking(int ncid, int a1, int a2, const size_t* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_var_chunking(nc->substrate,a1,a2,a3);
}
static int
NCSUB_def_var_fill(int ncid, int a1, int a2, const void* a3)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_var_fill(nc->substrate,a1,a2,a3);
}
static int
NCSUB_def_var_endian(int ncid, int a1, int a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->def_var_endian(nc->substrate,a1,a2);
}
static int
NCSUB_set_var_chunk_cache(int ncid, int a1, size_t a2, size_t a3, float a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->set_var_chunk_cache(nc->substrate,a1,a2,a3,a4);
}
static int
NCSUB_get_var_chunk_cache(int ncid, int a1, size_t* a2, size_t* a3, float* a4)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->get_var_chunk_cache(nc->substrate,a1,a2,a3,a4);
}
#endif /*USE_NETCDF4*/
/* Declare here to avoid having a bunch of static forward declarations */
static NC_Dispatch NCSUBSTRATE_dispatch_base = {
0,
NCSUB_new_nc,
NULL, /*NC_create*/
NULL, /*NC_open*/
NCSUB_redef,
NCSUB__enddef,
NCSUB_sync,
NCSUB_abort,
NCSUB_close,
NCSUB_set_fill,
NCSUB_inq_base_pe,
NCSUB_set_base_pe,
NCSUB_inq_format,
NCSUB_inq,
NCSUB_inq_type,
NCSUB_def_dim,
NCSUB_inq_dimid,
NCSUB_inq_dim,
NCSUB_inq_unlimdim,
NCSUB_rename_dim,
NCSUB_inq_att,
NCSUB_inq_attid,
NCSUB_inq_attname,
NCSUB_rename_att,
NCSUB_del_att,
NCSUB_get_att,
NCSUB_put_att,
NCSUB_def_var,
NCSUB_inq_varid,
NCSUB_rename_var,
NCSUB_get_vara,
NCSUB_put_vara,
NCSUB_get_vars,
NCSUB_put_vars,
NCSUB_get_varm,
NCSUB_put_varm,
NCSUB_inq_var_all,
#ifdef USE_NETCDF4
NCSUB_show_metadata,
NCSUB_inq_unlimdims,
NCSUB_var_par_access,
NCSUB_inq_ncid,
NCSUB_inq_grps,
NCSUB_inq_grpname,
NCSUB_inq_grpname_full,
NCSUB_inq_grp_parent,
NCSUB_inq_grp_full_ncid,
NCSUB_inq_varids,
NCSUB_inq_dimids,
NCSUB_inq_typeids,
NCSUB_inq_type_equal,
NCSUB_def_grp,
NCSUB_inq_user_type,
NCSUB_inq_typeid,
NCSUB_def_compound,
NCSUB_insert_compound,
NCSUB_insert_array_compound,
NCSUB_inq_compound_field,
NCSUB_inq_compound_fieldindex,
NCSUB_def_vlen,
NCSUB_put_vlen_element,
NCSUB_get_vlen_element,
NCSUB_def_enum,
NCSUB_insert_enum,
NCSUB_inq_enum_member,
NCSUB_inq_enum_ident,
NCSUB_def_opaque,
NCSUB_def_var_deflate,
NCSUB_def_var_fletcher32,
NCSUB_def_var_chunking,
NCSUB_def_var_fill,
NCSUB_def_var_endian,
NCSUB_set_var_chunk_cache,
NCSUB_get_var_chunk_cache
#endif /*USE_NETCDF4*/
};

View File

@ -25,7 +25,6 @@ Author: D. Heimbigner 10/7/2008
#include "ncaux.h"
struct NCAUX_FIELD {
char* name;
nc_type fieldtype;

View File

@ -23,14 +23,8 @@
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include "utils.h"
#include "nccomps.h"
#include "dumplib.h" /* for sbuf_... prototypes */
#include "ncdump.h" /* for fspec_t def */
#include "nctime.h"
extern fspec_t formatting_specs; /* set from command-line options */
static int cuErrOpts; /* Error options */
static int cuErrorOccurred = 0; /* True iff cdError was called */
@ -41,8 +35,6 @@ static int cuErrorOccurred = 0; /* True iff cdError was called */
#define VALCMP(a,b) ((a)<(b)?-1:(b)<(a)?1:0)
/* forward declarations */
static void Cdh2e(CdTime *htime, double *etime);
static void cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime);
static void cdComp2Rel(cdCalenType timetype, cdCompTime comptime, char* relunits, double* reltime);
static void cdRel2CompMixed(double reltime, cdUnitTime unit, cdCompTime basetime, cdCompTime *comptime);
static void cdRel2Comp(cdCalenType timetype, char* relunits, double reltime, cdCompTime* comptime);
@ -188,7 +180,7 @@ CdDayOfYear(CdTime *date, int *doy)
*
* Derived from NRL Neons V3.6
*/
static void
void
Cde2h(double etime, CdTimeType timeType, long baseYear, CdTime *htime)
{
long ytemp; /* temporary year holder */
@ -309,7 +301,7 @@ CdAddDelTime(double begEtm, long nDel, CdDeltaTime delTime, CdTimeType timeType,
/* Parse relative units, returning the unit and base component time. */
/* Function returns 1 if error, 0 on success */
static int
int
cdParseRelunits(cdCalenType timetype, char* relunits, cdUnitTime* unit, cdCompTime* base_comptime)
{
char charunits[CD_MAX_RELUNITS];
@ -624,7 +616,7 @@ cdToOldTimetype(cdCalenType newtype, CdTimeType* oldtype)
*
* Derived from NRL Neons V3.6
*/
static void
void
Cdh2e(CdTime *htime, double *etime)
{
long ytemp, year; /* temporary year holder */
@ -682,7 +674,7 @@ cdValidateTime(cdCalenType timetype, cdCompTime comptime)
return 0;
}
static void
void
cdChar2Comp(cdCalenType timetype, char* chartime, cdCompTime* comptime)
{
double sec;
@ -1176,258 +1168,3 @@ cdRel2Iso(cdCalenType timetype, char* relunits, int separator, double reltime, c
return;
}
/* rkr: added bounds functions to detect bounds variables of time variables */
static void
bounds_add(char *bounds_name, int ncid, int varid) {
bounds_node_t *bnode = emalloc(sizeof(bounds_node_t) + 1);
bounds_list.nbnds++;
bnode->ncid = ncid;
bnode->varid = varid;
bnode->bounds_name = strdup(bounds_name);
bnode->next = bounds_list.first;
bounds_list.first = bnode;
}
boolean
is_bounds_var(char *varname, int *pargrpidp, int *parvaridp) {
bounds_node_t *bp = bounds_list.first;
for(; bp; bp = bp->next) {
if(STREQ(bp->bounds_name, varname)) {
*pargrpidp = bp->ncid;
*parvaridp = bp->varid;
return true;
}
}
return false;
}
/* Return true only if this is a "bounds" attribute */
boolean
is_bounds_att(ncatt_t *attp) {
if(attp->type == NC_CHAR && attp->valgp && STREQ((char *)attp->name, "bounds")) {
return true;
}
#ifdef USE_NETCDF4
if(attp->type == NC_STRING && attp->valgp && STREQ((char *)attp->name, "bounds")) {
return true;
}
#endif /* USE_NETCDF4 */
return false;
}
/* Insert info about a bounds attribute into bounds list, so we can
* later determine which variables are bounds variables for which
* other variables. att must be a variable "bounds" attribute. */
void
insert_bounds_info(int ncid, int varid, ncatt_t att) {
static boolean uninitialized = true;
if(uninitialized) {
bounds_list.nbnds = 0;
bounds_list.first = NULL;
}
assert(is_bounds_att(&att));
bounds_add(att.valgp, ncid, varid);
}
/* Check for optional "calendar" attribute and return specified
* calendar type, if present. */
static cdCalenType
calendar_type(int ncid, int varid) {
int ctype;
int stat;
ncatt_t catt;
static struct {
char* attname;
int type;
} calmap[] = {
{"gregorian", cdMixed},
{"standard", cdMixed}, /* synonym */
{"proleptic_gregorian", cdStandard},
{"noleap", cdNoLeap},
{"no_leap", cdNoLeap},
{"365_day", cdNoLeap}, /* synonym */
{"allleap", cd366},
{"all_leap", cd366}, /* synonym */
{"366_day", cd366}, /* synonym */
{"360_day", cd360},
{"julian", cdJulian},
{"none", cdClim} /* TODO: test this */
};
#define CF_CAL_ATT_NAME "calendar"
int ncals = (sizeof calmap)/(sizeof calmap[0]);
ctype = cdMixed; /* default mixed Gregorian/Julian ala udunits */
stat = nc_inq_att(ncid, varid, CF_CAL_ATT_NAME, &catt.type, &catt.len);
if(stat == NC_NOERR && catt.type == NC_CHAR && catt.len > 0) {
char *calstr = (char *)emalloc(catt.len + 1);
int itype;
NC_CHECK(nc_get_att(ncid, varid, CF_CAL_ATT_NAME, calstr));
calstr[catt.len] = '\0';
for(itype = 0; itype < ncals; itype++) {
if(strncmp(calstr, calmap[itype].attname, catt.len) == 0) {
ctype = calmap[itype].type;
break;
}
}
free(calstr);
}
return ctype;
}
void
get_timeinfo(int ncid1, int varid1, ncvar_t *vp) {
ncatt_t uatt; /* units attribute */
int nc_status; /* return from netcdf calls */
char *units;
int ncid = ncid1;
int varid = varid1;
vp->has_timeval = false; /* by default, turn on if criteria met */
vp->timeinfo = 0;
vp->is_bnds_var = false;
/* for timeinfo, treat a bounds variable like its "parent" time variable */
if(is_bounds_var(vp->name, &ncid, &varid)) {
vp->is_bnds_var = true;
}
/* time variables must have appropriate units attribute or be a bounds variable */
nc_status = nc_inq_att(ncid, varid, "units", &uatt.type, &uatt.len);
if(nc_status == NC_NOERR && uatt.type == NC_CHAR) { /* TODO: NC_STRING? */
units = emalloc(uatt.len + 1);
NC_CHECK(nc_get_att(ncid, varid, "units", units));
units[uatt.len] = '\0';
/* check for calendar attribute (not required even for time vars) */
vp->timeinfo = (timeinfo_t *)emalloc(sizeof(timeinfo_t));
memset((void*)vp->timeinfo,0,sizeof(timeinfo_t));
vp->timeinfo->calendar = calendar_type(ncid, varid);
/* Parse relative units, returning the unit and base component time. */
if(cdParseRelunits(vp->timeinfo->calendar, units,
&vp->timeinfo->unit, &vp->timeinfo->origin) != 0) {
/* error parsing units so just treat as not a time variable */
free(vp->timeinfo);
free(units);
vp->timeinfo = NULL;
return;
}
/* Currently this gets reparsed for every value, need function
* like cdRel2Comp that resuses parsed units? */
vp->timeinfo->units = strdup(units);
vp->has_timeval = true;
free(units);
}
return;
}
/* print_att_times
* by Dave Allured, NOAA/PSD/CIRES.
* This version supports only primitive attribute types; do not call
* for user defined types. Print interpreted, human readable (ISO)
* time strings for an attribute of a CF-like time variable.
*
* Print strings as CDL comments, following the normal non-decoded
* numeric values, which were already printed by the calling function.
* In the following example, this function prints only the right hand
* side, starting at the two slashes:
*
* time:actual_range = 51133., 76670. ; // "1940-01-01", "2009-12-01"
*
* This function may be called for ALL primitive attributes.
* This function qualifies the attribute for numeric type and
* inheriting valid time attributes (has_time). If the attribute
* does not qualify, this function prints nothing and safely
* returns.
*
* This function interprets and formats time values with the SAME
* methods already used in ncdump -t for data variables.
*
* This version has special line wrapping rules:
*
* (1) If the attribute has one or two values, the time strings are
* always printed on the same line.
*
* (2) If the attribute has three or more values, the time strings
* are always printed on successive lines, with line wrapping
* as needed.
*
* Assume: Preceeding call to pr_att_valgs has already screened
* this attribute for valid primitive types for the current netcdf
* model (netcdf 3 or 4).
*/
void
print_att_times(
int ncid,
int varid, /* parent var ID */
ncatt_t att /* attribute structure */
)
{
nc_type type = att.type; /* local copy */
boolean wrap;
boolean first_item;
ncvar_t var; /* fake var structure for the att values; */
/* will add only the minimum necessary info */
/* For common disqualifications, print nothing and return immediately. */
if (type == NC_CHAR || type == NC_STRING) /* must be numeric */
return;
if (varid == NC_GLOBAL) /* time units not defined for global atts */
return;
assert (att.len > 0); /* should already be eliminated by caller */
#ifdef USE_NETCDF4
assert ( type == NC_BYTE || type == NC_SHORT || type == NC_INT
|| type == NC_FLOAT || type == NC_DOUBLE || type == NC_UBYTE
|| type == NC_USHORT || type == NC_UINT || type == NC_INT64
|| type == NC_UINT64 );
#else /* NETCDF3 */
assert ( type == NC_BYTE || type == NC_SHORT || type == NC_INT
|| type == NC_FLOAT || type == NC_DOUBLE );
#endif
/* Get time info from parent variable, and qualify. */
memset((void*)&var,0,sizeof(var)); /* clear the fake var structure */
get_timeinfo(ncid, varid, &var); /* sets has_timeval, timeinfo members */
if (var.has_timeval) { /* no print unless time qualified */
/* Convert each value to ISO date/time string, and print. */
size_t iel; /* attrib index */
const char *valp = (const char *)att.valgp; /* attrib value pointer */
safebuf_t *sb = sbuf_new(); /* allocate new string buffer */
int func; /* line wrap control */
int separator = ' '; /* default between data and time */
if(formatting_specs.iso_separator)
separator = 'T';
var.type = att.type; /* insert attrib type into fake var */
for (iel = 0; iel < att.len; iel++) {
nctime_val_tostring(&var, sb, (void *)valp); /* convert to str. */
valp += att.tinfo->size; /* increment value pointer, by type */
if (iel < att.len - 1) /* add comma, except for final value */
sbuf_cat(sb, ",");
first_item = (iel == 0); /* identify start of list */
wrap = (att.len > 2); /* specify line wrap variations: */
/* 1 or 2 values: keep on same line, */
/* more than 2: enable line wrap */
lput2 (sbuf_str(sb), first_item, wrap);
/* print string in CDL comment, */
/* with auto newline */
}
sbuf_free(sb); /* clean up */
if(var.timeinfo->units) /* clean up from get_timeinfo */
free(var.timeinfo->units);
free(var.timeinfo);
}
}

View File

@ -27,6 +27,11 @@ NC_initialize(void)
{
int stat = NC_NOERR;
/* Allow libdispatch to do initialization */
if((stat = NCDISPATCH_initialize())) return stat;
/* Initialize each active protocol */
if((stat = NC3_initialize())) return stat;
#ifdef USE_NETCDF4

View File

@ -4,8 +4,8 @@
# This automake file is in charge of building the libsrc directory,
# which contains the classic library code.
# We may have to add to these later.
AM_CPPFLAGS = -I$(top_srcdir)/include
include $(top_srcdir)/lib_flags.am
libnetcdf3_la_CPPFLAGS = ${AM_CPPFLAGS}
# Turn on a pre-processor flag when building a DLL for windows.

View File

@ -1549,7 +1549,5 @@ unwind_alloc:
int
nc_delete(const char * path)
{
return nc_delete_mp(path, 0);
return nc_delete_mp(path, 0);
}

View File

@ -10,8 +10,8 @@ LDADD = ${top_builddir}/liblib/libnetcdf.la
# This is the program we're building, and it's sources.
bin_PROGRAMS = ncdump
ncdump_SOURCES = ncdump.c vardata.c dumplib.c indent.c nctime.c \
ncdump.h vardata.h dumplib.h indent.h isnan.h nctime.h cdl.h \
ncdump_SOURCES = ncdump.c vardata.c dumplib.c indent.c nctime0.c \
ncdump.h vardata.h dumplib.h indent.h isnan.h nctime0.h cdl.h \
utils.h utils.c nciter.h nciter.c nccomps.h
# Another utility program that copies any netCDF file using only the

View File

@ -25,7 +25,7 @@
#include "ncdump.h"
#include "dumplib.h"
#include "isnan.h"
#include "nctime.h"
#include "nctime0.h"
static float float_eps;
static double double_eps;

View File

@ -139,6 +139,7 @@ void print_name(const char *name);
* Escape any special chars. */
void print_type_name(int locid, int typeid);
int nctime_val_tostring(const ncvar_t *varp, safebuf_t *sfbf, const void *valp);
#ifdef __cplusplus
}
#endif

View File

@ -22,7 +22,7 @@ Research/Unidata. See \ref copyright file for more info. */
#include <netcdf.h>
#include "utils.h"
#include "nccomps.h"
#include "nctime.h" /* new iso time and calendar stuff */
#include "nctime0.h" /* new iso time and calendar stuff */
#include "ncdump.h"
#include "dumplib.h"
#include "vardata.h"

296
ncdump/nctime0.c Normal file
View File

@ -0,0 +1,296 @@
/*********************************************************************
* Copyright 2008, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Id: nctime.c,v 1.9 2010/05/05 22:15:39 dmh Exp $
*********************************************************************/
/*
* This code was extracted with permission from the CDMS time
* conversion and arithmetic routines developed by Bob Drach, Lawrence
* Livermore National Laboratory as part of the cdtime library. Russ
* Rew of the UCAR Unidata Program made changes and additions to
* support the "-t" option of the netCDF ncdump utility, including a
* 366-day climate calendar.
*
* For the complete time conversion and climate calendar facilities of
* the CDMS library, get the original sources from LLNL.
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include "utils.h"
#include "nccomps.h"
#include "dumplib.h" /* for sbuf_... prototypes */
#include "ncdump.h" /* for fspec_t def */
#include "vardata.h"
#include "nctime0.h"
static struct {
size_t nbnds; /* number of bounds variables */
bounds_node_t *first;
} bounds_list;
extern fspec_t formatting_specs; /* set from command-line options */
/* rkr: added bounds functions to detect bounds variables of time variables */
void
bounds_add(char *bounds_name, int ncid, int varid) {
bounds_node_t *bnode = emalloc(sizeof(bounds_node_t) + 1);
bounds_list.nbnds++;
bnode->ncid = ncid;
bnode->varid = varid;
bnode->bounds_name = strdup(bounds_name);
bnode->next = bounds_list.first;
bounds_list.first = bnode;
}
/* Check for optional "calendar" attribute and return specified
* calendar type, if present. */
cdCalenType
calendar_type(int ncid, int varid) {
int ctype;
int stat;
ncatt_t catt;
static struct {
char* attname;
int type;
} calmap[] = {
{"gregorian", cdMixed},
{"standard", cdMixed}, /* synonym */
{"proleptic_gregorian", cdStandard},
{"noleap", cdNoLeap},
{"no_leap", cdNoLeap},
{"365_day", cdNoLeap}, /* synonym */
{"allleap", cd366},
{"all_leap", cd366}, /* synonym */
{"366_day", cd366}, /* synonym */
{"360_day", cd360},
{"julian", cdJulian},
{"none", cdClim} /* TODO: test this */
};
#define CF_CAL_ATT_NAME "calendar"
int ncals = (sizeof calmap)/(sizeof calmap[0]);
ctype = cdMixed; /* default mixed Gregorian/Julian ala udunits */
stat = nc_inq_att(ncid, varid, CF_CAL_ATT_NAME, &catt.type, &catt.len);
if(stat == NC_NOERR && catt.type == NC_CHAR && catt.len > 0) {
char *calstr = (char *)emalloc(catt.len + 1);
int itype;
NC_CHECK(nc_get_att(ncid, varid, CF_CAL_ATT_NAME, calstr));
calstr[catt.len] = '\0';
for(itype = 0; itype < ncals; itype++) {
if(strncmp(calstr, calmap[itype].attname, catt.len) == 0) {
ctype = calmap[itype].type;
break;
}
}
free(calstr);
}
return ctype;
}
boolean
is_bounds_var(char *varname, int *pargrpidp, int *parvaridp) {
bounds_node_t *bp = bounds_list.first;
for(; bp; bp = bp->next) {
if(STREQ(bp->bounds_name, varname)) {
*pargrpidp = bp->ncid;
*parvaridp = bp->varid;
return true;
}
}
return false;
}
/* Return true only if this is a "bounds" attribute */
boolean
is_bounds_att(ncatt_t *attp) {
if(attp->type == NC_CHAR && attp->valgp && STREQ((char *)attp->name, "bounds")) {
return true;
}
#ifdef USE_NETCDF4
if(attp->type == NC_STRING && attp->valgp && STREQ((char *)attp->name, "bounds")) {
return true;
}
#endif /* USE_NETCDF4 */
return false;
}
/* Insert info about a bounds attribute into bounds list, so we can
* later determine which variables are bounds variables for which
* other variables. att must be a variable "bounds" attribute. */
void
insert_bounds_info(int ncid, int varid, ncatt_t att) {
static boolean uninitialized = true;
if(uninitialized) {
bounds_list.nbnds = 0;
bounds_list.first = NULL;
}
assert(is_bounds_att(&att));
bounds_add(att.valgp, ncid, varid);
}
void
get_timeinfo(int ncid1, int varid1, ncvar_t *vp) {
ncatt_t uatt; /* units attribute */
int nc_status; /* return from netcdf calls */
char *units;
int ncid = ncid1;
int varid = varid1;
vp->has_timeval = false; /* by default, turn on if criteria met */
vp->timeinfo = 0;
vp->is_bnds_var = false;
/* for timeinfo, treat a bounds variable like its "parent" time variable */
if(is_bounds_var(vp->name, &ncid, &varid)) {
vp->is_bnds_var = true;
}
/* time variables must have appropriate units attribute or be a bounds variable */
nc_status = nc_inq_att(ncid, varid, "units", &uatt.type, &uatt.len);
if(nc_status == NC_NOERR && uatt.type == NC_CHAR) { /* TODO: NC_STRING? */
units = emalloc(uatt.len + 1);
NC_CHECK(nc_get_att(ncid, varid, "units", units));
units[uatt.len] = '\0';
/* check for calendar attribute (not required even for time vars) */
vp->timeinfo = (timeinfo_t *)emalloc(sizeof(timeinfo_t));
memset((void*)vp->timeinfo,0,sizeof(timeinfo_t));
vp->timeinfo->calendar = calendar_type(ncid, varid);
/* Parse relative units, returning the unit and base component time. */
if(cdParseRelunits(vp->timeinfo->calendar, units,
&vp->timeinfo->unit, &vp->timeinfo->origin) != 0) {
/* error parsing units so just treat as not a time variable */
free(vp->timeinfo);
free(units);
vp->timeinfo = NULL;
return;
}
/* Currently this gets reparsed for every value, need function
* like cdRel2Comp that resuses parsed units? */
vp->timeinfo->units = strdup(units);
vp->has_timeval = true;
free(units);
}
return;
}
/* print_att_times
* by Dave Allured, NOAA/PSD/CIRES.
* This version supports only primitive attribute types; do not call
* for user defined types. Print interpreted, human readable (ISO)
* time strings for an attribute of a CF-like time variable.
*
* Print strings as CDL comments, following the normal non-decoded
* numeric values, which were already printed by the calling function.
* In the following example, this function prints only the right hand
* side, starting at the two slashes:
*
* time:actual_range = 51133., 76670. ; // "1940-01-01", "2009-12-01"
*
* This function may be called for ALL primitive attributes.
* This function qualifies the attribute for numeric type and
* inheriting valid time attributes (has_time). If the attribute
* does not qualify, this function prints nothing and safely
* returns.
*
* This function interprets and formats time values with the SAME
* methods already used in ncdump -t for data variables.
*
* This version has special line wrapping rules:
*
* (1) If the attribute has one or two values, the time strings are
* always printed on the same line.
*
* (2) If the attribute has three or more values, the time strings
* are always printed on successive lines, with line wrapping
* as needed.
*
* Assume: Preceeding call to pr_att_valgs has already screened
* this attribute for valid primitive types for the current netcdf
* model (netcdf 3 or 4).
*/
void
print_att_times(
int ncid,
int varid, /* parent var ID */
ncatt_t att /* attribute structure */
)
{
nc_type type = att.type; /* local copy */
boolean wrap;
boolean first_item;
ncvar_t var; /* fake var structure for the att values; */
/* will add only the minimum necessary info */
/* For common disqualifications, print nothing and return immediately. */
if (type == NC_CHAR || type == NC_STRING) /* must be numeric */
return;
if (varid == NC_GLOBAL) /* time units not defined for global atts */
return;
assert (att.len > 0); /* should already be eliminated by caller */
#ifdef USE_NETCDF4
assert ( type == NC_BYTE || type == NC_SHORT || type == NC_INT
|| type == NC_FLOAT || type == NC_DOUBLE || type == NC_UBYTE
|| type == NC_USHORT || type == NC_UINT || type == NC_INT64
|| type == NC_UINT64 );
#else /* NETCDF3 */
assert ( type == NC_BYTE || type == NC_SHORT || type == NC_INT
|| type == NC_FLOAT || type == NC_DOUBLE );
#endif
/* Get time info from parent variable, and qualify. */
memset((void*)&var,0,sizeof(var)); /* clear the fake var structure */
get_timeinfo(ncid, varid, &var); /* sets has_timeval, timeinfo members */
if (var.has_timeval) { /* no print unless time qualified */
/* Convert each value to ISO date/time string, and print. */
size_t iel; /* attrib index */
const char *valp = (const char *)att.valgp; /* attrib value pointer */
safebuf_t *sb = sbuf_new(); /* allocate new string buffer */
#ifdef NOTUSED
int func; /* line wrap control */
#endif
int separator = ' '; /* default between data and time */
if(formatting_specs.iso_separator)
separator = 'T';
var.type = att.type; /* insert attrib type into fake var */
for (iel = 0; iel < att.len; iel++) {
nctime_val_tostring(&var, sb, (void *)valp); /* convert to str. */
valp += att.tinfo->size; /* increment value pointer, by type */
if (iel < att.len - 1) /* add comma, except for final value */
sbuf_cat(sb, ",");
first_item = (iel == 0); /* identify start of list */
wrap = (att.len > 2); /* specify line wrap variations: */
/* 1 or 2 values: keep on same line, */
/* more than 2: enable line wrap */
lput2 (sbuf_str(sb), first_item, wrap);
/* print string in CDL comment, */
/* with auto newline */
}
sbuf_free(sb); /* clean up */
if(var.timeinfo->units) /* clean up from get_timeinfo */
free(var.timeinfo->units);
free(var.timeinfo);
}
}

13
ncdump/nctime0.h Normal file
View File

@ -0,0 +1,13 @@
/*********************************************************************
* Copyright 2008, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* $Id: nctime.h,v 1.6 2010/03/18 19:24:26 russ Exp $
*********************************************************************/
#include "nctime.h"
extern void insert_bounds_info(int ncid, int varid, ncatt_t att);
extern int is_bounds_att(ncatt_t *attp);
extern void get_timeinfo(int ncid, int varid, ncvar_t *vp);
extern void print_att_times(int ncid, int varid, ncatt_t att);

View File

@ -14,11 +14,12 @@ static char SccsId[] = "$Id: ncgen.y,v 1.42 2010/05/18 21:32:46 dmh Exp $";
*/
#include "includes.h"
#include "offsets.h"
#include <time.h>
#include <math.h>
#define TIMEFORMAT "%Y-%m-%d"
extern char *strptime(const char *s, const char *format, struct tm *tm);
/* Following are in ncdump (for now)*/
/* Need some (unused) definitions to get it to compile */
#define ncatt_t void*
#define ncvar_t void
#include "nctime.h"
/* parser controls */
#define YY_NO_INPUT 1
@ -1406,9 +1407,11 @@ vercheck(int ncid)
}
/*
Since the arguments are all simple constant,
Since the arguments are all simple constants,
we can evaluate the function immediately
and return its value.
Note that currently, only a single value can
be returned.
*/
static Constant
@ -1420,64 +1423,54 @@ evaluate(Symbol* fcn, Datalist* arglist)
result.lineno = fcn->lineno;
result.filled = 0;
#if defined(HAVE_STRPTIME) && defined(HAVE_MKTIME)
if(strcasecmp(fcn->name,"time") == 0) {
result.nctype = NC_INT;
result.value.int32v = 0;
/* int time(string,string) */
if(arglist->length != 2
|| arglist->data[0].nctype != NC_STRING
|| arglist->data[1].nctype != NC_STRING) {
derror("Expected function signature: time(string,string)");
goto done;
} else {
char* timekind = arglist->data[0].value.stringv.stringv;
char* timevalue = arglist->data[1].value.stringv.stringv;
if(strcasecmp(timekind,"timetest")==0) {
struct tm time;
memset(&time,0,sizeof(time));
if(strptime(timevalue,TIMEFORMAT,&time) == NULL) {
derror("Malformed time string: %s",timevalue);
goto done;
} else {
result.value.int32v = (int)mktime(&time);
}
} else {
derror("Time conversion '%s' not supported",timekind);
char* timekind = NULL;
char* timevalue = NULL;
result.nctype = NC_DOUBLE;
result.value.doublev = 0;
/* int time([string],string) */
switch (arglist->length) {
case 2:
if(arglist->data[1].nctype != NC_STRING) {
derror("Expected function signature: time([string,]string)");
goto done;
}
}
} else if(strcasecmp(fcn->name,"math") == 0) {
/* int match(string,string) */
if(arglist->length != 2
|| arglist->data[0].nctype != NC_STRING
|| arglist->data[1].nctype != NC_STRING) {
derror("Expected function signature: math(string,string)");
goto done;
} else {
char* fcn = arglist->data[0].value.stringv.stringv;
char* arg = arglist->data[1].value.stringv.stringv;
double matharg = 0.0;
result.nctype = NC_INT64;
result.value.int64v = 0;
if(sscanf(arg,"%le",&matharg) != 1) {
derror("Malformed math function value: %s",arg);
goto done;
}
if(strcasecmp(fcn,"sin")==0) {
result.value.int64v = sin(matharg);
} else if(strcasecmp(fcn,"cos")==0) {
result.value.int64v = cos(matharg);
} else if(strcasecmp(fcn,"tan")==0) {
result.value.int64v = tan(matharg);
} else {
derror("Math function '%s' not supported",fcn);
/* fall thru */
case 1:
if(arglist->data[0].nctype != NC_STRING) {
derror("Expected function signature: time([string,]string)");
goto done;
}
break;
case 0:
default:
derror("Expected function signature: time([string,]string)");
goto done;
}
} else
#endif
{ /* Unknown function */
if(arglist->length == 2) {
timekind = arglist->data[0].value.stringv.stringv;
timevalue = arglist->data[1].value.stringv.stringv;
} else
timevalue = arglist->data[0].value.stringv.stringv;
if(timekind == NULL) { /* use cd time as the default */
cdCompTime comptime;
CdTime cdtime;
cdCalenType timetype = cdStandard;
cdChar2Comp(timetype,timevalue,&comptime);
/* convert comptime to cdTime */
cdtime.year = comptime.year;
cdtime.month = comptime.month;
cdtime.day = comptime.day;
cdtime.hour = comptime.hour;
cdtime.baseYear = 1970;
cdtime.timeType = CdChron;
/* convert to double value */
Cdh2e(&cdtime,&result.value.doublev);
} else {
derror("Time conversion '%s' not supported",timekind);
goto done;
}
} else { /* Unknown function */
derror("Unknown function name: %s",fcn->name);
goto done;
}

File diff suppressed because it is too large Load Diff