mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-01 17:06:03 +08:00
modified libdap to use a new metadata handling mechanism
This commit is contained in:
commit
79ebcb38b8
@ -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])
|
||||
|
@ -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
|
||||
|
19
include/nc.h
19
include/nc.h
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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*/
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;}
|
||||
|
@ -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*/
|
||||
|
@ -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}
|
||||
|
@ -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)
|
||||
|
48
libdap2/env
48
libdap2/env
@ -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'"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
304
libdap2/ncdap3.c
304
libdap2/ncdap3.c
@ -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);
|
||||
|
@ -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*/
|
||||
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
386
libdap2/ncdap4.c
386
libdap2/ncdap4.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
913
libdispatch/dsubstrate.c
Normal 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*/
|
||||
|
||||
};
|
@ -25,7 +25,6 @@ Author: D. Heimbigner 10/7/2008
|
||||
|
||||
#include "ncaux.h"
|
||||
|
||||
|
||||
struct NCAUX_FIELD {
|
||||
char* name;
|
||||
nc_type fieldtype;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -1549,7 +1549,5 @@ unwind_alloc:
|
||||
int
|
||||
nc_delete(const char * path)
|
||||
{
|
||||
return nc_delete_mp(path, 0);
|
||||
return nc_delete_mp(path, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
296
ncdump/nctime0.c
Normal 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
13
ncdump/nctime0.h
Normal 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);
|
107
ncgen/ncgen.y
107
ncgen/ncgen.y
@ -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;
|
||||
}
|
||||
|
387
ncgen/ncgentab.c
387
ncgen/ncgentab.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user