/********************************************************************* * Copyright 2018, UCAR/Unidata * See netcdf/COPYRIGHT file for copying and redistribution conditions. *********************************************************************/ #ifndef NCCOMMON_H #define NCCOMMON_H 1 #include "dapincludes.h" /* Mnemonics */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* Define an alias for int to indicate an error return */ typedef int NCerror; #ifndef nullfree #define nullfree(m) {if((m)!=NULL) {free(m);} else {}} #endif /* Misc. code controls */ #define FILLCONSTRAINT TRUE /* Hopefully, this flag will someday not be needed */ #define COLUMBIA_HACK "columbia.edu" /* Use an extended version of the netCDF-4 type system */ #define NC_URL 50 #define NC_SET 51 /* Merge relevant translations of OC types */ #define NC_Dataset 52 #define NC_Sequence 53 #define NC_Structure 54 #define NC_Grid 55 #define NC_Dimension 56 #define NC_Atomic 57 #undef OCCOMPILEBYDEFAULT #define DEFAULTSTRINGLENGTH 64 /* The sequence limit default is zero because most servers do not implement projections on sequences. */ #define DEFAULTSEQLIMIT 0 /**************************************************/ /* sigh, do the forwards */ struct NCDAPCOMMON; struct NCprojection; struct NCselection; struct Getvara; struct NCcachenode; struct NCcache; struct NCslice; struct NCsegment; struct OClist; struct NCTMODEL { int translation; char* model; unsigned int flags; }; /* Define the cache control flags */ /* Detail information about each cache item */ typedef struct NCcachenode { int wholevariable; /* does this cache node only have wholevariables? */ int isprefetch; off_t xdrsize; DCEconstraint* constraint; /* as used to create this node */ NClist* vars; /* vars potentially covered by this cache node */ struct CDFnode* datadds; OCddsnode ocroot; OCdatanode content; } NCcachenode; /* All cache info */ typedef struct NCcache { size_t cachelimit; /* max total size for all cached entries */ size_t cachesize; /* current size */ size_t cachecount; /* max # nodes in cache */ NCcachenode* prefetch; NClist* nodes; /* cache nodes other than prefetch */ } NCcache; /**************************************************/ /* The DAP packet info from OC */ typedef struct NCOC { OClink conn; char* rawurltext; /* as given to nc3d_open */ char* urltext; /* as modified by nc3d_open */ NCURI* url; /* parse of rawuritext */ OCdasnode ocdasroot; DCEconstraint* dapconstraint; /* from url */ int inmemory; /* store fetched data in memory? */ } NCOC; typedef struct NCCDF { struct CDFnode* ddsroot; /* constrained dds */ struct CDFnode* fullddsroot; /* unconstrained dds */ NClist* projectedvars; /* vars appearing in nc_open url projections */ unsigned int defaultstringlength; unsigned int defaultsequencelimit; /* global sequence limit;0=>no limit */ struct NCcache* cache; size_t fetchlimit; size_t smallsizelimit; /* what constitutes a small object? */ size_t totalestimatedsize; const char* separator; /* constant; do not free */ /* Following fields should be set from the unconstrained dds only */ /* global string dimension */ struct CDFnode* globalstringdim; char* recorddimname; /* From DODS_EXTRA */ struct CDFnode* recorddim; } NCCDF; /* Define a structure holding common info for NCDAP */ typedef struct NCDAPCOMMON { NC* controller; /* Parent instance of NCDAPCOMMON */ NCCDF cdf; NCOC oc; NCCONTROLS controls; /* Control flags and parameters */ struct { int realfile; /* 1 => we created actual temp file */ char* filename; /* of the substrate file */ int nc3id; /* substrate nc4 file ncid used to hold metadata; not same as external id */ } substrate; } NCDAPCOMMON; /**************************************************/ /* Create our own node tree to mimic ocnode trees*/ /* Each root CDFnode contains info about the whole tree */ typedef struct CDFtree { OCddsnode ocroot; OCdxd occlass; NClist* nodes; /* all nodes in tree*/ struct CDFnode* root; /* cross link */ struct NCDAPCOMMON* owner; /* Collected sets of useful nodes */ NClist* varnodes; /* nodes which can represent netcdf variables */ NClist* seqnodes; /* sequence nodes; */ NClist* gridnodes; /* grid nodes */ NClist* dimnodes; /* (base) dimension nodes */ /* Classification flags */ int restructed; /* Was this tree passed thru restruct? */ } CDFtree; /* Track the kinds of dimensions */ typedef int CDFdimflags; #define CDFDIMNORMAL 0x0 #define CDFDIMSEQ 0x1 #define CDFDIMSTRING 0x2 #define CDFDIMCLONE 0x4 #define CDFDIMRECORD 0x20 #define DIMFLAG(d,flag) ((d)->dim.dimflags & (flag)) #define DIMFLAGSET(d,flag) ((d)->dim.dimflags |= (flag)) #define DIMFLAGCLR(d,flag) ((d)->dim.dimflags &= ~(flag)) typedef struct CDFdim { CDFdimflags dimflags; struct CDFnode* basedim; /* for duplicate dimensions*/ struct CDFnode* array; /* parent array node */ size_t declsize; /* from constrained DDS*/ size_t declsize0; /* from unconstrained DDS*/ int index1; /* dimension name index +1; 0=>no index */ } CDFdim; typedef struct CDFarray { NClist* dimsetall; /* dimsetplus + inherited */ NClist* dimsettrans; /* dimset0 plus inherited(transitive closure) */ NClist* dimsetplus; /* dimset0 + pseudo */ NClist* dimset0; /* original dims from the dds */ struct CDFnode* stringdim; /* Track sequence related information */ struct CDFnode* seqdim; /* if this node is a sequence */ /* note: unlike string dim; seqdim is also stored in dimensions vector */ struct CDFnode* sequence; /* containing usable sequence, if any */ struct CDFnode* basevar; /* for duplicate grid variables*/ } CDFarray; typedef struct NCattribute { char* name; nc_type etype; /* dap type of the attribute */ NClist* values; /* strings come from the oc values */ int invisible; /* Do not materialize to the user */ } NCattribute; /* Extend as additional DODS attribute values are defined */ typedef struct NCDODS { size_t maxstrlen; char* dimname; } NCDODS; typedef struct NCD2alignment { unsigned long size; /* size of single instance of this type*/ unsigned long alignment; /* alignment of this field */ unsigned long offset; /* offset of this field in parent */ } NCD2alignment; typedef struct NCtypesize { int aligned; /* have instance and field been defined? */ NCD2alignment instance; /* Alignment, etc for instance data */ NCD2alignment field; /* Alignment, etc WRT to parent */ } NCtypesize; /* Closely mimics struct OCnode*/ typedef struct CDFnode { nc_type nctype; /* e.g. var, dimension */ nc_type etype; /* e.g. NC_INT, NC_FLOAT if applicable,*/ char* ocname; /* oc base name */ char* ncbasename; /* generally cdflegalname(ocname) */ char* ncfullname; /* complete path name from root to this node*/ OCddsnode ocnode; /* oc mirror node*/ struct CDFnode* group; /* null => in root group */ struct CDFnode* container; /* e.g. struct or sequence, but not group */ struct CDFnode* root; CDFtree* tree; /* root level metadata;only defined if root*/ CDFdim dim; /* nctype == dimension */ CDFarray array; /* nctype == grid,var,etc. with dimensions */ NClist* subnodes; /* if nctype == grid, sequence, etc. */ NClist* attributes; /*NClist*/ NCDODS dodsspecial; /* special attributes like maxStrlen */ nc_type externaltype; /* the type as represented to nc_inq*/ int ncid; /* relevant NC id for this object*/ unsigned long maxstringlength; unsigned long sequencelimit; /* 0=>unlimited */ int usesequence; /* If this sequence is usable */ int elided; /* 1 => node does not partipate in naming*/ struct CDFnode* basenode; /* derived tree map to pattern tree */ int invisible; /* 1 => do not show to user */ int zerodim; /* 1 => node has a zero dimension */ /* These two flags track the effects on grids of constraints */ int nc_virtual; /* node added by regrid */ struct CDFnode* attachment; /* DDS<->DATADDS cross link*/ struct CDFnode* pattern; /* temporary field for regridding */ /* Fields for use by libncdap4 */ NCtypesize typesize; int typeid; /* when treating field as type */ int basetypeid; /* when typeid is vlen */ char* typename; char* vlenname; /* for sequence types */ int singleton; /* for singleton sequences */ unsigned long estimatedsize; /* > 0 Only for var nodes */ int whole; /* projected as whole node */ int prefetchable; /* eligible to be prefetched (if whole) */ } CDFnode; /**************************************************/ /* Shared procedures */ /* From error.c*/ extern NCerror ocerrtoncerr(OCerror); extern NCerror attach(CDFnode* xroot, CDFnode* ddstarget); extern void unattach(CDFnode*); extern int nodematch(CDFnode* node1, CDFnode* node2); extern int simplenodematch(CDFnode* node1, CDFnode* node2); extern CDFnode* findxnode(CDFnode* target, CDFnode* xroot); extern int constrainable(NCURI*); extern char* makeconstraintstring(DCEconstraint*); extern size_t estimatedataddssize(CDFnode* datadds); extern void canonicalprojection(NClist*, NClist*); extern NClist* getalldims(NCDAPCOMMON* nccomm, int visibleonly); /* From cdf.c */ extern NCerror fixgrid(NCDAPCOMMON* drno, CDFnode* grid); extern NCerror computecdfinfo(NCDAPCOMMON*, NClist*); extern char* cdfname(char* basename); extern NCerror augmentddstree(NCDAPCOMMON*, NClist*); extern NCerror computecdfdimnames(NCDAPCOMMON*); extern NCerror buildcdftree(NCDAPCOMMON*, OCddsnode, OCdxd, CDFnode**); extern CDFnode* makecdfnode(NCDAPCOMMON*, char* nm, OCtype, /*optional*/ OCddsnode ocnode, CDFnode* container); extern void freecdfroot(CDFnode*); extern NCerror dimimprint(NCDAPCOMMON*); extern NCerror definedimsets(NCDAPCOMMON*,CDFtree*); extern NCerror definedimsettrans(NCDAPCOMMON*,CDFtree*); /* From cache.c */ extern int iscached(NCDAPCOMMON*, CDFnode* target, NCcachenode** cachenodep); extern NCerror prefetchdata(NCDAPCOMMON*); extern NCerror markprefetch(NCDAPCOMMON*); extern NCerror buildcachenode(NCDAPCOMMON*, DCEconstraint* constraint, NClist* varlist, NCcachenode** cachep, NCFLAGS flags); extern NCcachenode* createnccachenode(void); extern void freenccachenode(NCDAPCOMMON*, NCcachenode* node); extern NCcache* createnccache(void); extern void freenccache(NCDAPCOMMON*, NCcache* cache); /* Add an extra function whose sole purpose is to allow configure(.ac) to test for the presence of thiscode. */ extern int nc__opendap(void); /* Define accessors for the dispatchdata */ #define NCD2_DATA(nc) ((NCDAPCOMMON*)(nc)->dispatchdata) #define NCD2_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data)) #define getncid(drno) (((NC*)drno)->ext_ncid) #define getdap(drno) ((NCDAPCOMMON*)((NC*)drno)->dispatchdata) #define getnc3id(drno) (getdap(drno)->substrate.nc3id) #endif /*NCCOMMON_H*/