1 /*********************************************************************
2   *   Copyright 2018, UCAR/Unidata
3   *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4   *********************************************************************/
5 
6 #ifndef NCCOMMON_H
7 #define NCCOMMON_H 1
8 
9 #include "dapincludes.h"
10 
11 /* Mnemonics */
12 #ifndef BOOL
13 #define BOOL int
14 #endif
15 #ifndef TRUE
16 #define TRUE 1
17 #define FALSE 0
18 #endif
19 
20 #ifndef nullfree
21 #define nullfree(m) {if((m)!=NULL) {free(m);} else {}}
22 #endif
23 
24 /* Misc. code controls */
25 #define FILLCONSTRAINT TRUE
26 
27 /* Hopefully, this flag will someday not  be needed */
28 #define COLUMBIA_HACK "columbia.edu"
29 
30 /* Use an extended version of the netCDF-4 type system */
31 #define NC_URL		50
32 #define NC_SET		51
33 /* Merge relevant translations of OC types */
34 #define NC_Dataset	52
35 #define NC_Sequence	53
36 #define NC_Structure	54
37 #define NC_Grid		55
38 #define NC_Dimension	56
39 #define NC_Atomic	57
40 
41 #undef OCCOMPILEBYDEFAULT
42 
43 #define DEFAULTSTRINGLENGTH 64
44 /* The sequence limit default is zero because
45    most servers do not implement projections
46    on sequences.
47 */
48 #define DEFAULTSEQLIMIT 0
49 
50 /**************************************************/
51 /* sigh, do the forwards */
52 struct NCDAPCOMMON;
53 struct NCprojection;
54 struct NCselection;
55 struct Getvara;
56 struct NCcachenode;
57 struct NCcache;
58 struct NCslice;
59 struct NCsegment;
60 struct OClist;
61 struct NCTMODEL {
62     int translation;
63     char* model;
64     unsigned int flags;
65 };
66 
67 /* Define the cache control flags */
68 
69 
70 /* Detail information about each cache item */
71 typedef struct NCcachenode {
72     int wholevariable; /* does this cache node only have wholevariables? */
73     int isprefetch;
74     off_t xdrsize;
75     DCEconstraint* constraint; /* as used to create this node */
76     NClist* vars; /* vars potentially covered by this cache node */
77     struct CDFnode* datadds;
78     OCddsnode ocroot;
79     OCdatanode content;
80 } NCcachenode;
81 
82 
83 /* All cache info */
84 typedef struct NCcache {
85     size_t cachelimit; /* max total size for all cached entries */
86     size_t cachesize; /* current size */
87     size_t cachecount; /* max # nodes in cache */
88     NCcachenode* prefetch;
89     NClist* nodes; /* cache nodes other than prefetch */
90 } NCcache;
91 
92 /**************************************************/
93 /* The DAP packet info from OC */
94 typedef struct NCOC {
95     OClink conn;
96     char* rawurltext; /* as given to nc3d_open */
97     char* urltext;    /* as modified by nc3d_open */
98     NCURI* url;      /* parse of rawuritext */
99     OCdasnode ocdasroot;
100     DCEconstraint* dapconstraint; /* from url */
101     int inmemory; /* store fetched data in memory? */
102 } NCOC;
103 
104 typedef struct NCCDF {
105     struct CDFnode* ddsroot; /* constrained dds */
106     struct CDFnode* fullddsroot; /* unconstrained dds */
107     NClist*  projectedvars; /* vars appearing in nc_open url projections */
108     unsigned int defaultstringlength;
109     unsigned int defaultsequencelimit; /* global sequence limit;0=>no limit */
110     struct NCcache* cache;
111     size_t fetchlimit;
112     size_t smallsizelimit; /* what constitutes a small object? */
113     size_t totalestimatedsize;
114     const char* separator; /* constant; do not free */
115     /* Following fields should be set from the unconstrained dds only */
116     /* global string dimension */
117     struct CDFnode* globalstringdim;
118     char* recorddimname; /* From DODS_EXTRA */
119     struct CDFnode* recorddim;
120 } NCCDF;
121 
122 /* Define a structure holding common info for NCDAP */
123 
124 typedef struct NCDAPCOMMON {
125     NC*   controller; /* Parent instance of NCDAPCOMMON */
126     NCCDF cdf;
127     NCOC oc;
128     NCCONTROLS controls; /* Control flags and parameters */
129     struct {
130 	int realfile; /* 1 => we created actual temp file */
131 	char* filename; /* of the substrate file */
132         int nc3id; /* substrate nc4 file ncid used to hold metadata; not same as external id  */
133     } substrate;
134 } NCDAPCOMMON;
135 
136 /**************************************************/
137 /* Create our own node tree to mimic ocnode trees*/
138 
139 /* Each root CDFnode contains info about the whole tree */
140 typedef struct CDFtree {
141     OCddsnode ocroot;
142     OCdxd occlass;
143     NClist* nodes; /* all nodes in tree*/
144     struct CDFnode* root; /* cross link */
145     struct NCDAPCOMMON*          owner;
146     /* Collected sets of useful nodes */
147     NClist*  varnodes; /* nodes which can represent netcdf variables */
148     NClist*  seqnodes; /* sequence nodes; */
149     NClist*  gridnodes; /* grid nodes */
150     NClist*  dimnodes; /* (base) dimension nodes */
151     /* Classification flags */
152     int restructed; /* Was this tree passed thru restruct? */
153 } CDFtree;
154 
155 /* Track the kinds of dimensions */
156 typedef int CDFdimflags;
157 #define CDFDIMNORMAL	0x0
158 #define CDFDIMSEQ	0x1
159 #define CDFDIMSTRING	0x2
160 #define CDFDIMCLONE	0x4
161 #define CDFDIMRECORD	0x20
162 
163 #define DIMFLAG(d,flag) ((d)->dim.dimflags & (flag))
164 #define DIMFLAGSET(d,flag) ((d)->dim.dimflags |= (flag))
165 #define DIMFLAGCLR(d,flag) ((d)->dim.dimflags &= ~(flag))
166 
167 typedef struct CDFdim {
168     CDFdimflags    dimflags;
169     struct CDFnode* basedim; /* for duplicate dimensions*/
170     struct CDFnode* array; /* parent array node */
171     size_t declsize;	    /* from constrained DDS*/
172     size_t declsize0;	    /* from unconstrained DDS*/
173     int    index1;          /* dimension name index +1; 0=>no index */
174 } CDFdim;
175 
176 typedef struct CDFarray {
177     NClist*  dimsetall;   /* dimsetplus + inherited */
178     NClist*  dimsettrans; /* dimset0 plus inherited(transitive closure) */
179     NClist*  dimsetplus;  /* dimset0 + pseudo */
180     NClist*  dimset0;     /* original dims from the dds */
181     struct CDFnode* stringdim;
182     /* Track sequence related information */
183     struct CDFnode* seqdim; /* if this node is a sequence */
184     /* note: unlike string dim; seqdim is also stored in dimensions vector */
185     struct CDFnode* sequence; /* containing usable sequence, if any */
186     struct CDFnode* basevar; /* for duplicate grid variables*/
187 } CDFarray;
188 
189 typedef struct NCattribute {
190     char*   name;
191     nc_type etype; /* dap type of the attribute */
192     NClist* values; /* strings come from the oc values */
193     int     invisible; /* Do not materialize to the user */
194 } NCattribute;
195 
196 /* Extend as additional DODS attribute values are defined */
197 typedef struct NCDODS {
198     size_t maxstrlen;
199     char* dimname;
200 } NCDODS;
201 
202 typedef struct NCD2alignment {
203     unsigned long    size; /* size of single instance of this type*/
204     unsigned long    alignment; /* alignment of this field */
205     unsigned long    offset;    /* offset of this field in parent */
206 } NCD2alignment;
207 
208 typedef struct NCtypesize {
209     BOOL             aligned; /*  have instance and field been defined? */
210     NCD2alignment      instance; /* Alignment, etc for instance data */
211     NCD2alignment      field; /* Alignment, etc WRT to parent */
212 } NCtypesize;
213 
214 /* Closely mimics struct OCnode*/
215 typedef struct CDFnode {
216     nc_type          nctype;     /* e.g. var, dimension  */
217     nc_type          etype;      /* e.g. NC_INT, NC_FLOAT if applicable,*/
218     char*            ocname;     /* oc base name */
219     char*            ncbasename; /* generally cdflegalname(ocname) */
220     char*            ncfullname; /* complete path name from root to this node*/
221     OCddsnode        ocnode;     /* oc mirror node*/
222     struct CDFnode*  group;	 /* null => in root group */
223     struct CDFnode*  container;  /* e.g. struct or sequence, but not group */
224     struct CDFnode*  root;
225     CDFtree*         tree;       /* root level metadata;only defined if root*/
226     CDFdim           dim;        /* nctype == dimension */
227     CDFarray         array;      /* nctype == grid,var,etc. with dimensions */
228     NClist*          subnodes;      /* if nctype == grid, sequence, etc. */
229     NClist*          attributes;    /*NClist<NCattribute*>*/
230     NCDODS           dodsspecial;   /* special attributes like maxStrlen */
231     nc_type          externaltype;  /* the type as represented to nc_inq*/
232     int              ncid;          /* relevant NC id for this object*/
233     unsigned long    maxstringlength;
234     unsigned long    sequencelimit; /* 0=>unlimited */
235     BOOL	     usesequence;   /* If this sequence is usable */
236     BOOL             elided;        /* 1 => node does not partipate in naming*/
237     struct CDFnode*  basenode;      /* derived tree map to pattern tree */
238     BOOL	     invisible;     /* 1 => do not show to user */
239     BOOL	     zerodim;       /* 1 => node has a zero dimension */
240     /* These two flags track the effects on grids of constraints */
241     BOOL             nc_virtual;       /* node added by regrid */
242     struct CDFnode* attachment;     /* DDS<->DATADDS cross link*/
243     struct CDFnode* pattern;       /* temporary field for regridding */
244     /* Fields for use by libncdap4 */
245     NCtypesize       typesize;
246     int              typeid;        /* when treating field as type */
247     int              basetypeid;    /* when typeid is vlen */
248     char*            typename;
249     char*            vlenname;      /* for sequence types */
250     int              singleton;     /* for singleton sequences */
251     unsigned long    estimatedsize; /* > 0 Only for var nodes */
252     BOOL             whole;         /* projected as whole node */
253     BOOL             prefetchable;  /* eligible to be prefetched (if whole) */
254 } CDFnode;
255 
256 /**************************************************/
257 /* Shared procedures */
258 
259 /* From error.c*/
260 extern NCerror ocerrtoncerr(OCerror);
261 
262 extern NCerror attach(CDFnode* xroot, CDFnode* ddstarget);
263 extern void unattach(CDFnode*);
264 extern int nodematch(CDFnode* node1, CDFnode* node2);
265 extern int simplenodematch(CDFnode* node1, CDFnode* node2);
266 extern CDFnode* findxnode(CDFnode* target, CDFnode* xroot);
267 extern int constrainable(NCURI*);
268 extern char* makeconstraintstring(DCEconstraint*);
269 extern size_t estimatedataddssize(CDFnode* datadds);
270 extern void canonicalprojection(NClist*, NClist*);
271 extern NClist* getalldims(NCDAPCOMMON* nccomm, int visibleonly);
272 
273 /* From cdf.c */
274 extern NCerror fixgrid(NCDAPCOMMON* drno, CDFnode* grid);
275 extern NCerror computecdfinfo(NCDAPCOMMON*, NClist*);
276 extern char* cdfname(char* basename);
277 extern NCerror augmentddstree(NCDAPCOMMON*, NClist*);
278 extern NCerror computecdfdimnames(NCDAPCOMMON*);
279 extern NCerror buildcdftree(NCDAPCOMMON*, OCddsnode, OCdxd, CDFnode**);
280 extern CDFnode* makecdfnode(NCDAPCOMMON*, char* nm, OCtype,
281 			    /*optional*/ OCddsnode ocnode, CDFnode* container);
282 extern void freecdfroot(CDFnode*);
283 
284 extern NCerror dimimprint(NCDAPCOMMON*);
285 extern NCerror definedimsets(NCDAPCOMMON*,CDFtree*);
286 extern NCerror definedimsettrans(NCDAPCOMMON*,CDFtree*);
287 
288 /* From cache.c */
289 extern int iscached(NCDAPCOMMON*, CDFnode* target, NCcachenode** cachenodep);
290 extern NCerror prefetchdata(NCDAPCOMMON*);
291 extern NCerror markprefetch(NCDAPCOMMON*);
292 extern NCerror buildcachenode(NCDAPCOMMON*,
293 	        DCEconstraint* constraint,
294 		NClist* varlist,
295 		NCcachenode** cachep,
296 		NCFLAGS flags);
297 extern NCcachenode* createnccachenode(void);
298 extern void freenccachenode(NCDAPCOMMON*, NCcachenode* node);
299 extern NCcache* createnccache(void);
300 extern void freenccache(NCDAPCOMMON*, NCcache* cache);
301 
302 /* Add an extra function whose sole purpose is to allow
303    configure(.ac) to test for the presence of thiscode.
304 */
305 extern int nc__opendap(void);
306 
307 /* Define accessors for the dispatchdata */
308 #define NCD2_DATA(nc) ((NCDAPCOMMON*)(nc)->dispatchdata)
309 #define NCD2_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data))
310 
311 #define getncid(drno) (((NC*)drno)->ext_ncid)
312 #define getdap(drno) ((NCDAPCOMMON*)((NC*)drno)->dispatchdata)
313 #define getnc3id(drno) (getdap(drno)->substrate.nc3id)
314 
315 #endif /*NCCOMMON_H*/
316