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