1 #ifndef CDI_INT_H
2 #define CDI_INT_H
3
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7
8 #include <assert.h>
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <limits.h>
14 #include <math.h>
15 #include <sys/types.h>
16
17 #include "cdi.h"
18 #include "cdf_config.h"
19
20 // Base file types
21
22 #define CDI_FILETYPE_GRIB 100 // File type GRIB
23 #define CDI_FILETYPE_NETCDF 101 // File type NetCDF
24
25 // dummy use of unused parameters to silence compiler warnings
26 #ifndef UNUSED
27 #define UNUSED(x) (void)x
28 #endif
29
30 #ifndef strdupx
31 #ifndef strdup
32 char *strdup(const char *s);
33 #endif
34 #define strdupx strdup
35 /*
36 #define strdupx(s) \
37 ({ \
38 const char *__old = (s); \
39 size_t __len = strlen(__old) + 1; \
40 char *__new = (char *) Malloc(__len); \
41 (char *) memcpy(__new, __old, __len); \
42 })
43 */
44 #endif
45
46 char *strToLower(char *str);
47 bool strStartsWith(const char *vstr, const char *cstr);
48
49 static inline bool
strIsEqual(const char * x,const char * y)50 strIsEqual(const char *x, const char *y)
51 {
52 return (*x == *y) && strcmp(x, y) == 0;
53 }
54
55
56 #ifndef M_PI
57 #define M_PI 3.14159265358979323846 /* pi */
58 #endif
59
60
61 #ifndef ERROR_H
62 # include "error.h"
63 #endif
64 #ifndef _BASETIME_H
65 # include "basetime.h"
66 #endif
67 #ifndef TIMEBASE_H
68 # include "timebase.h"
69 #endif
70 #ifndef TAXIS_H
71 # include "taxis.h"
72 #endif
73 #ifndef CDI_LIMITS_H
74 # include "cdi_limits.h"
75 #endif
76 #ifndef _SERVICE_H
77 # include "service.h"
78 #endif
79 #ifndef _EXTRA_H
80 # include "extra.h"
81 #endif
82 #ifndef _IEG_H
83 # include "ieg.h"
84 #endif
85 #ifndef RESOURCE_HANDLE_H
86 # include "resource_handle.h"
87 #endif
88
89
90 #define check_parg(arg) if ( arg == 0 ) Warning("Argument '" #arg "' not allocated!")
91
92 #ifdef __xlC__ /* performance problems on IBM */
93 #ifndef DBL_IS_NAN
94 # define DBL_IS_NAN(x) ((x) != (x))
95 #endif
96 #else
97 #ifndef DBL_IS_NAN
98 #if defined (HAVE_DECL_ISNAN)
99 # define DBL_IS_NAN(x) (isnan(x))
100 #elif defined (FP_NAN)
101 # define DBL_IS_NAN(x) (fpclassify(x) == FP_NAN)
102 #else
103 # define DBL_IS_NAN(x) ((x) != (x))
104 #endif
105 #endif
106 #endif
107
108 #ifndef DBL_IS_EQUAL
109 //#define DBL_IS_EQUAL(x,y) (!(x < y || y < x))
110 # define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)):!(x < y || y < x))
111 #endif
112
113 #ifndef IS_EQUAL
114 # define IS_NOT_EQUAL(x,y) (x < y || y < x)
115 # define IS_EQUAL(x,y) (!IS_NOT_EQUAL(x,y))
116 #endif
117
118 enum {
119 TYPE_REC,
120 TYPE_VAR,
121 };
122
123 enum {
124 MEMTYPE_DOUBLE = 1,
125 MEMTYPE_FLOAT,
126 };
127
128 typedef struct
129 {
130 void *buffer; // gribapi, cgribex
131 size_t buffersize; // gribapi, cgribex
132 off_t position; // file position
133 int param;
134 int level;
135 int date;
136 int time;
137 int gridID;
138 int varID;
139 int levelID;
140 int prec; // ext, srv
141 void *exsep; // ieg, ext, srv container
142 void *cgribexp; // cgribex container
143 }
144 Record;
145
146 // data structure specifying tile-related meta-data. structure contains "-1" if this is no tile-variable.
147 typedef struct {
148 int
149 tileindex,
150 totalno_of_tileattr_pairs,
151 tileClassification,
152 numberOfTiles,
153 numberOfAttributes,
154 attribute;
155 } var_tile_t;
156
157
158 typedef struct {
159 short perturbationNumber;
160 short typeOfGeneratingProcess;
161 } VarScanKeys;
162
163 static inline void
varScanKeysInit(VarScanKeys * s)164 varScanKeysInit(VarScanKeys *s)
165 {
166 memset(s, 0, sizeof(VarScanKeys));
167 }
168
169 static inline bool
varScanKeysIsEqual(const VarScanKeys * s1,const VarScanKeys * s2)170 varScanKeysIsEqual(const VarScanKeys *s1, const VarScanKeys *s2)
171 {
172 return memcmp(s1, s2, sizeof(VarScanKeys)) == 0;
173 }
174
175 typedef struct
176 {
177 off_t position;
178 size_t size;
179 size_t gridsize;
180 int zip;
181 int param;
182 int ilevel;
183 int ilevel2;
184 int ltype;
185 short tsteptype;
186 short varID;
187 int levelID;
188 short used;
189 char varname[32]; // needed for grib decoding with GRIB_API
190 VarScanKeys scanKeys;
191 var_tile_t tiles; // tile-related meta-data, currently for GRIB-API only.
192 #ifdef HAVE_LIBFDB5
193 void *fdbItem;
194 #endif
195 }
196 record_t;
197
198
199 typedef struct {
200 record_t *records;
201 int *recIDs; // IDs of non constant records
202 int recordSize; // number of allocated records
203 int nrecs; // number of used records
204 // tsID=0 nallrecs
205 // tsID>0 number of non constant records
206 int nallrecs; // number of all records
207 int curRecID; // current record ID
208 bool next;
209 off_t position; // timestep file position
210 taxis_t taxis;
211 }
212 tsteps_t;
213
214
215 typedef struct {
216 int nlevs;
217 int subtypeIndex; // corresponding tile in subtype_t structure (subtype->self)
218 int *recordID; // record IDs: [nlevs]
219 int *lindex; // level index
220 } sleveltable_t;
221
222
223 typedef struct {
224 sleveltable_t *recordTable; // record IDs for each subtype
225 int ncvarid;
226 int subtypeSize;
227 bool defmiss; // true: if missval is defined in file
228 bool isUsed;
229
230 int gridID;
231 int zaxisID;
232 int tsteptype; // TSTEP_*
233 int subtypeID; // subtype ID, e.g. for tile-related meta-data (currently for GRIB-API only).
234 }
235 svarinfo_t;
236
237
238 typedef struct {
239 int ilev;
240 int mlev;
241 int ilevID;
242 int mlevID;
243 }
244 VCT;
245
246 #ifdef HAVE_LIBNETCDF
247 enum cdfIDIdx {
248 CDF_DIMID_E, // 3rd dimID of cube sphere grid (len=6)
249 CDF_DIMID_X,
250 CDF_DIMID_Y,
251 CDF_DIMID_RP, // reducedPoints
252 CDF_VARID_X,
253 CDF_VARID_Y,
254 CDF_VARID_RP, // reducedPoints
255 CDF_VARID_A,
256 CDF_SIZE_ncIDs,
257 };
258
259 typedef struct {
260 int ncIDs[CDF_SIZE_ncIDs];
261 int gridID;
262 }
263 ncgrid_t;
264 #endif
265
266 typedef struct {
267 int self;
268 int accesstype; // TYPE_REC or TYPE_VAR
269 int accessmode;
270 int filetype;
271 int byteorder;
272 int fileID;
273 int filemode;
274 int nrecs; // number of records
275 SizeType numvals;
276 char *filename;
277 Record *record;
278 svarinfo_t *vars;
279 int nvars; // number of variables
280 int varsAllocated;
281 int curTsID; // current timestep ID
282 int rtsteps; // number of tsteps accessed
283 long ntsteps; // number of tsteps : only set if all records accessed
284 tsteps_t *tsteps;
285 int tstepsTableSize;
286 int tstepsNextID;
287 basetime_t basetime;
288 int ncmode;
289 int vlistID;
290 #ifdef HAVE_LIBNETCDF
291 int nc_complex_float_id;
292 int nc_complex_double_id;
293 ncgrid_t ncgrid[MAX_GRIDS_PS];
294 int zaxisID[MAX_ZAXES_PS]; // Warning: synchronous array to vlist_to_pointer(vlistID)->zaxisIDs
295 int nczvarID[MAX_ZAXES_PS];
296 VCT vct;
297 #endif
298 int globalatts;
299 int localatts;
300 int unreduced;
301 int have_missval;
302 int comptype; // compression type
303 int complevel; // compression level
304 bool sortname;
305 bool sortparam;
306 void *gribContainers;
307
308 int numWorker;
309 int nextRecID;
310 int cachedTsID;
311 void *jobs;
312 void *jobManager;
313
314 bool fdbRetrieve;
315 bool fdbStore;
316 #ifdef HAVE_LIBFDB5
317 void *fdbHandle;
318 #endif
319 }
320 stream_t;
321
322
323 // Length of optional keyword/value pair list
324 #define MAX_OPT_GRIB_ENTRIES 500
325
326 enum cdi_convention {CDI_CONVENTION_ECHAM, CDI_CONVENTION_CF};
327
328 // Data type specification for optional key/value pairs (GRIB)
329 typedef enum {
330 t_double = 0,
331 t_int = 1
332 } key_val_pair_datatype;
333
334 // Data structure holding optional key/value pairs for GRIB
335 typedef struct
336 {
337 char* keyword; // keyword string
338 bool update;
339 key_val_pair_datatype data_type; // data type of this key/value pair
340 double dbl_val; // double value (data_type == t_double)
341 int int_val; // integer value (data_type == t_int)
342 int subtype_index; // tile index for this key-value pair
343 } opt_key_val_pair_t;
344
345 // enum for differenciating between the different times that we handle
346 typedef enum {
347 kCdiTimeType_referenceTime,
348 kCdiTimeType_startTime,
349 kCdiTimeType_endTime
350 } CdiTimeType;
351
352
353 #define CDI_FILETYPE_UNDEF -1 // Unknown/not yet defined file type
354
355
356 extern int cdiDebugExt;
357 extern int CDI_Debug; // If set to 1, debuggig (default 0)
358 extern int CDI_Recopt;
359 extern bool CDI_gribapi_debug;
360 extern bool CDI_gribapi_grib1;
361 extern double CDI_Default_Missval;
362 extern double CDI_Grid_Missval;
363 extern int CDI_Default_InstID;
364 extern int CDI_Default_ModelID;
365 extern int CDI_Default_TableID;
366 extern int cdiDefaultLeveltype;
367 extern int CDI_Default_Calendar;
368 //extern int cdiNcMissingValue;
369 extern int CDI_Netcdf_Chunksizehint;
370 extern int CDI_Chunk_Type;
371 extern int CDI_Split_Ltype105;
372 extern int cdiDataUnreduced;
373 extern int cdiSortName;
374 extern int cdiSortParam;
375 extern int cdiHaveMissval;
376 extern bool CDI_Ignore_Att_Coordinates;
377 extern bool CDI_Coordinates_Lon_Lat;
378 extern bool CDI_Ignore_Valid_Range;
379 extern int CDI_Skip_Records;
380 extern const char *CDI_GRIB1_Template;
381 extern const char *CDI_GRIB2_Template;
382 extern int CDI_Convention;
383 extern int CDI_Inventory_Mode;
384 extern int CDI_Version_Info;
385 extern int CDI_Convert_Cubesphere;
386 extern int CDI_Read_Cell_Corners;
387 extern int CDI_CMOR_Mode;
388 extern int CDI_Reduce_Dim;
389 extern size_t CDI_Netcdf_Hdr_Pad;
390 extern bool CDI_Netcdf_Lazy_Grid_Load;
391 extern int STREAM_Debug;
392
393
394 extern char *cdiPartabPath;
395 extern int cdiPartabIntern;
396 extern const resOps streamOps;
397
398 static inline stream_t *
stream_to_pointer(int idx)399 stream_to_pointer(int idx)
400 {
401 return (stream_t *)reshGetVal(idx, &streamOps);
402 }
403
404 static inline void
stream_check_ptr(const char * caller,stream_t * streamptr)405 stream_check_ptr(const char *caller, stream_t *streamptr)
406 {
407 if (streamptr == NULL) Errorc("stream undefined!");
408 }
409
410 int streamInqFileID(int streamID);
411
412 void gridDefHasDims(int gridID, int hasdims);
413 int gridInqHasDims(int gridID);
414 int zaxisInqLevelID(int zaxisID, double level);
415
416 void streamCheckID(const char *caller, int streamID);
417
418 void streamDefineTaxis(int streamID);
419
420 int streamsNewEntry(int filetype);
421 void streamsInitEntry(int streamID);
422 void cdiStreamSetupVlist(stream_t *streamptr, int vlistID);
423 // default implementation of the overridable function
424 void cdiStreamSetupVlist_(stream_t *streamptr, int vlistID);
425 int stream_new_var(stream_t *streamptr, int gridID, int zaxisID, int tilesetID);
426
427 int tstepsNewEntry(stream_t *streamptr);
428
429 const char *strfiletype(int filetype);
430
431 void cdi_generate_vars(stream_t *streamptr);
432
433 void vlist_check_contents(int vlistID);
434
435 void cdi_create_records(stream_t *streamptr, int tsID);
436
437 void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name);
438
439 int recordNewEntry(stream_t *streamptr, int tsID);
440
441 void cdiCreateTimesteps(stream_t *streamptr);
442
443 void recordInitEntry(record_t *record);
444
445 void cdiCheckZaxis(int zaxisID);
446
447 void cdiDefAccesstype(int streamID, int type);
448 int cdiInqAccesstype(int streamID);
449
450 int getByteswap(int byteorder);
451
452 void cdiStreamGetIndexList(unsigned numIDs, int IDs[]);
453
454 void cdiInitialize(void);
455
456 char *cdiEscapeSpaces(const char *string);
457 char *cdiUnescapeSpaces(const char *string, const char **outStringEnd);
458
459 enum {
460 CDI_UNIT_PA = 1,
461 CDI_UNIT_HPA,
462 CDI_UNIT_MM,
463 CDI_UNIT_CM,
464 CDI_UNIT_DM,
465 CDI_UNIT_M,
466 };
467
468 struct streamAssoc
469 {
470 int streamID, vlistID;
471 };
472
473 struct streamAssoc
474 streamUnpack(char *unpackBuffer, int unpackBufferSize,
475 int *unpackBufferPos, int originNamespace, void *context);
476
477 int
478 cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
479 int filetype, stream_t *streamptr,
480 int recordBufIsToBeCreated);
481
482 int
483 streamOpenID(const char *filename, char filemode, int filetype, int resH);
484
485 void
486 cdiStreamDefVlist_(int streamID, int vlistID);
487
488 int
489 cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, SizeType nmiss);
490
491 void
492 cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
493 const int rect[][2], const void *data, SizeType nmiss);
494 void
495 cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted);
496
497 int cdiStreamDefTimestep_(stream_t *streamptr, int tsID);
498
499 void cdiStreamSync_(stream_t *streamptr);
500
501 const char *cdiUnitNamePtr(int cdi_unit);
502
503 enum {
504 // 8192 is known to work on most systems (4096 isn't on Alpha)
505 commonPageSize = 8192,
506 };
507
508 size_t cdiGetPageSize(bool largePageAlign);
509
510 void zaxisGetIndexList(int nzaxis, int *zaxisIndexList);
511
512 #ifdef __cplusplus
513 extern "C" {
514 #endif
515
516 // functions used in CDO !!!
517
518 void cdiDefTableID(int tableID);
519
520 void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals);
521 void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals);
522
523 static inline
cdi_check_gridsize_int_limit(const char * format,SizeType gridsize)524 void cdi_check_gridsize_int_limit(const char *format, SizeType gridsize)
525 {
526 if (gridsize > INT_MAX) Error("%s format grid size (%zu) limit exceeded (%zu)!", format, gridsize, INT_MAX);
527 }
528
529 int cdiBaseFiletype(int filetype);
530
531 #ifdef __cplusplus
532 }
533 #endif
534
535 #endif /* CDI_INT_H */
536 /*
537 * Local Variables:
538 * c-file-style: "Java"
539 * c-basic-offset: 2
540 * indent-tabs-mode: nil
541 * show-trailing-whitespace: t
542 * require-trailing-newline: t
543 * End:
544 */
545