stream_int.c 14.5 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <stdio.h>
#include <stdarg.h>
#include <string.h> 
#include <errno.h>
#include <math.h>
#include <ctype.h>

#include "dmemory.h"

#include "cdi.h"
#include "stream_int.h"

17
18
19
#if  defined  (HAVE_LIBCGRIBEX)
#include "cgribex.h"
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
20

Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
22
23
24
25
26
int cdiDefaultCalendar = CALENDAR_PROLEPTIC;

int cdiDefaultInstID   = CDI_UNDEFID;
int cdiDefaultModelID  = CDI_UNDEFID;
int cdiDefaultTableID  = CDI_UNDEFID;
int cdiNcMissingValue  = CDI_UNDEFID;
27
int cdiNcChunksizehint = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
int cdiSplitLtype105   = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29

30
int cdiIgnoreAttCoordinates = FALSE;
31
int cdiSkipRecords          = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
int cdiInventoryMode        = 1;
33

Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
35
36
char *cdiPartabPath   = NULL;
int   cdiPartabIntern = 1;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
38
39
40
41
42
43
44
45
double cdiDefaultMissval = -9.E33;


char *Filetypes[] = {
  "UNKNOWN",
  "GRIB",
  "GRIB2",
  "netCDF",
  "netCDF2",
46
  "netCDF4",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
47
48
49
  "SERVICE",
  "EXTRA",
  "IEG",
50
  "HDF5",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
51
52
53
54
55
56
57
58
59
60
61
};

#undef  UNDEFID
#define UNDEFID  CDI_UNDEFID


int CDI_Debug   = 0;    /* If set to 1, debugging           */


int cdiDefaultLeveltype = -1;
static int cdiDataUnreduced = 0;
62
static int cdiSortName = 0;
63
static int cdiHaveMissval = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89


long cdiGetenvInt(char *envName)
{
  char *envString;
  long envValue = -1;
  long fact = 1;

  envString = getenv(envName);

  if ( envString )
    {
      int loop, len;

      len = (int) strlen(envString);
      for ( loop = 0; loop < len; loop++ )
	{
	  if ( ! isdigit((int) envString[loop]) )
	    {
	      switch ( tolower((int) envString[loop]) )
		{
		case 'k':  fact = 1024;        break;
		case 'm':  fact = 1048576;     break;
		case 'g':  fact = 1073741824;  break;
		default:
		  fact = 0;
90
91
		  Message("Invalid number string in %s: %s", envName, envString);
		  Warning("%s must comprise only digits [0-9].",envName);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
93
94
95
96
97
98
		}
	      break;
	    }
	}

      if ( fact ) envValue = fact*atol(envString);

99
      if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    }

  return (envValue);
}


void cdiInitialize(void)
{
  static int Init_CDI = FALSE;
  char *envString;
  long value;

  if ( ! Init_CDI )
    {
      Init_CDI = TRUE;

116
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
117
118
      gribFixZSE(1);   // 1: Fix ZeroShiftError of simple packed spherical harmonics
      gribSetConst(1); // 1: Don't pack constant fields on regular grids
119
120
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
123
      value = cdiGetenvInt("CD_REGULARGRID");
      if ( value >= 0 ) cdiDataUnreduced = (int) value;

124
125
126
127
128
129
      value = cdiGetenvInt("CDI_REGULARGRID");
      if ( value >= 0 ) cdiDataUnreduced = (int) value;

      value = cdiGetenvInt("CDI_SORTNAME");
      if ( value >= 0 ) cdiSortName = (int) value;

130
131
132
      value = cdiGetenvInt("CDI_HAVE_MISSVAL");
      if ( value >= 0 ) cdiHaveMissval = (int) value;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
134
135
      value = cdiGetenvInt("CD_LEVELTYPE");
      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;

136
137
138
      value = cdiGetenvInt("CDI_LEVELTYPE");
      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
140
      envString = getenv("CD_MISSVAL");
      if ( envString ) cdiDefaultMissval = atof(envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
141

142
143
144
      envString = getenv("CDI_MISSVAL");
      if ( envString ) cdiDefaultMissval = atof(envString);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
      envString = getenv("NC_MISSING_VALUE");
146
      if ( envString ) cdiNcMissingValue = atoi(envString);
147

148
149
150
      envString = getenv("NC_CHUNKSIZEHINT");
      if ( envString ) cdiNcChunksizehint = atoi(envString);

151
152
      envString = getenv("SPLIT_LTYPE_105");
      if ( envString ) cdiSplitLtype105 = atoi(envString);
153
154
155

      envString = getenv("IGNORE_ATT_COORDINATES");
      if ( envString ) cdiIgnoreAttCoordinates = atoi(envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156

157
158
159
160
161
162
163
      envString = getenv("CDI_SKIP_RECORDS");
      if ( envString )
	{
	  cdiSkipRecords = atoi(envString);
	  cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
165
166
167
168
169
170
      envString = getenv("GRIB_INVENTORY_MODE");
      if ( envString )
	{
	  if ( strncmp(envString, "time", 4) == 0 )
	    {
	      cdiInventoryMode = 2;
	      if ( CDI_Debug )
171
		Message("Inventory mode was set to timestep!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
172
173
174
	    }
	}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
      envString = getenv("CDI_CALENDAR");
      if ( envString )
	{
	  if      ( strncmp(envString, "standard", 8) == 0 )
	    cdiDefaultCalendar = CALENDAR_STANDARD;
	  else if ( strncmp(envString, "proleptic", 9) == 0 )
	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
	  else if ( strncmp(envString, "360days", 7) == 0 )
	    cdiDefaultCalendar = CALENDAR_360DAYS;
	  else if ( strncmp(envString, "365days", 7) == 0 )
	    cdiDefaultCalendar = CALENDAR_365DAYS;
	  else if ( strncmp(envString, "366days", 7) == 0 )
	    cdiDefaultCalendar = CALENDAR_366DAYS;
	  else if ( strncmp(envString, "none", 4) == 0 )
	    cdiDefaultCalendar = CALENDAR_NONE;

	  if ( CDI_Debug )
192
	    Message("Default calendar set to %s!", envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
193
	}
194
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
195
      gribSetCalendar(cdiDefaultCalendar);
196
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
197

Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
199
200
201
202
      envString = getenv("PARTAB_INTERN");
      if ( envString ) cdiPartabIntern = atoi(envString);

      envString = getenv("PARTAB_PATH");
      if ( envString ) cdiPartabPath = strdup(envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203
204
205
206
    }
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
207
char *strfiletype(int filetype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
210
  char *name;
  int size = (int) (sizeof(Filetypes)/sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211

Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213
214
215
  if ( filetype > 0 && filetype < size )
    name = Filetypes[filetype];
  else
    name = Filetypes[0];  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216

Uwe Schulzweida's avatar
Uwe Schulzweida committed
217
  return (name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
219
220
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
222
static int  STREAM_Debug = 0;   /* If set to 1, debugging */

223
static int _stream_min = MIN_STREAMS;
224
static int _stream_max = MAX_STREAMS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
226
227
228
229
230
231
232

static void stream_initialize(void);

static int _stream_init = FALSE;

#if  defined  (HAVE_LIBPTHREAD)
#  include <pthread.h>

233
static pthread_once_t  _stream_init_thread = PTHREAD_ONCE_INIT;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
234
235
static pthread_mutex_t _stream_mutex;

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
236
237
238
239
#  define STREAM_LOCK()         pthread_mutex_lock(&_stream_mutex)
#  define STREAM_UNLOCK()       pthread_mutex_unlock(&_stream_mutex)
#  define STREAM_INIT()        \
   if ( _stream_init == FALSE ) pthread_once(&_stream_init_thread, stream_initialize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
242

#else

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
243
244
245
246
#  define STREAM_LOCK()
#  define STREAM_UNLOCK()
#  define STREAM_INIT()        \
   if ( _stream_init == FALSE ) stream_initialize()
Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
248
249
250
251

#endif


typedef struct _streamPtrToIdx {
252
253
  int       idx;
  int       next;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
  stream_t *ptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
256
257
} streamPtrToIdx;


Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
static streamPtrToIdx *_streamList  = NULL;
259
static int             _streamAvail = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
261
262
static
void stream_list_new(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
  assert(_streamList == NULL);

266
  _streamList = (streamPtrToIdx *) malloc(_stream_min*sizeof(streamPtrToIdx));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
268
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
269
270
static
void stream_list_delete(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
271
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272
273
  if ( _streamList ) free(_streamList);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
275
276
static
void stream_init_pointer(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
{
278
  int i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
  
280
  for ( i = 0; i < _stream_min; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
281
282
    {
      _streamList[i].idx  = i;
283
      _streamList[i].next = i + 1;
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
284
      _streamList[i].ptr  = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
286
    }

287
  _streamList[_stream_min-1].next = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  _streamAvail = 0;
}

static
void stream_list_extend(void)
{
  int nstreams;
  int i;

  assert(_streamList != NULL);

  nstreams = _stream_min + MIN_STREAMS;

  if ( nstreams <= _stream_max)
    {
      _streamList = (streamPtrToIdx *) realloc(_streamList, nstreams*sizeof(streamPtrToIdx));
  
      for ( i = _stream_min; i < nstreams; ++i )
	{
	  _streamList[i].idx  = i;
	  _streamList[i].next = i + 1;
	  _streamList[i].ptr  = NULL;
	}

      _streamAvail = _stream_min;
      _streamList[_stream_min-1].next = _stream_min;
      _stream_min = nstreams;
      _streamList[_stream_min-1].next = -1;
    }
  else
319
    Warning("Too many open streams (limit is %d)!", _stream_max);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
320
321
322
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
stream_t *stream_to_pointer(int idx)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
325
  stream_t *streamptr = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
326

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
327
  STREAM_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
328

329
  if ( idx >= 0 && idx < _stream_min )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
    {
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
331
      STREAM_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332

Uwe Schulzweida's avatar
Uwe Schulzweida committed
333
      streamptr = _streamList[idx].ptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
334

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
335
      STREAM_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
337
    }
  else
338
    Error("stream index %d undefined!", idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
339
340
341
342

  return (streamptr);
}

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
343
344
345
/* Create an index from a pointer (add the pointer to the stream list) */
static
int stream_from_pointer(stream_t *ptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
{
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
347
  int idx = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
349

  if ( ptr )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
350
    {
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
351
      STREAM_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
352

353
354
355
      if ( _streamAvail < 0 ) stream_list_extend();

      if ( _streamAvail >= 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
	{
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
357
358
	  streamPtrToIdx *newptr;

359
360
361
	  newptr       = &_streamList[_streamAvail];
	  _streamAvail = newptr->next;
	  newptr->next = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
362
363
364
365
	  idx	       = newptr->idx;
	  newptr->ptr  = ptr;
      
	  if ( STREAM_Debug )
366
	    Message("Pointer %p has idx %d from stream list", ptr, idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
367
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
369
      STREAM_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
  else
372
    Error("Internal problem (pointer %p undefined)", ptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373

Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
  return (idx);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
377
378
static
void stream_init_entry(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
379
380
381
{
  int i;

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
382
  streamptr->self              = stream_from_pointer(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

  streamptr->accesstype        = UNDEFID;
  streamptr->accessmode        = 0;
  streamptr->filetype          = UNDEFID;
  streamptr->byteorder         = UNDEFID;
  streamptr->fileID            = 0;
  streamptr->dimgroupID        = UNDEFID;
  streamptr->filemode          = 0;
  streamptr->numvals           = 0;
  streamptr->filename          = NULL;
  streamptr->record            = NULL;
  streamptr->varsAllocated     = 0;
  streamptr->nrecs             = 0;
  streamptr->nvars             = 0;
  streamptr->vars              = NULL;
  streamptr->varinit           = 0;
  streamptr->ncmode            = 0;
  streamptr->curTsID           = UNDEFID;
  streamptr->rtsteps           = 0;
  streamptr->ntsteps           = UNDEFID;
  streamptr->numTimestep       = 0;
  streamptr->tsteps            = NULL;
  streamptr->tstepsTableSize   = 0;
  streamptr->tstepsNextID      = 0;
  streamptr->historyID         = UNDEFID;
  streamptr->vlistID           = UNDEFID;
  streamptr->globalatts        = 0;
  streamptr->localatts         = 0;
  streamptr->vct.ilev          = 0;
  streamptr->vct.mlev          = 0;
  streamptr->vct.ilevID        = UNDEFID;
  streamptr->vct.mlevID        = UNDEFID;
  streamptr->unreduced         = cdiDataUnreduced;
416
  streamptr->sortname          = cdiSortName;
417
  streamptr->have_missval      = cdiHaveMissval;
418
  streamptr->comptype          = COMPRESS_NONE;
419
  streamptr->complevel         = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
420
421
422

  basetimeInit(&streamptr->basetime);

423
424
  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->xdimID[i]   = UNDEFID;
  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ydimID[i]   = UNDEFID;
425
  for ( i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->zaxisID[i]  = UNDEFID;
426
427
428
  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncxvarID[i] = UNDEFID;
  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncyvarID[i] = UNDEFID;
  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncavarID[i] = UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432

  streamptr->curfile           = 0;
  streamptr->nfiles            = 0;
  streamptr->fnames            = NULL;
433

Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
  streamptr->gribContainers    = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
436
437
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
438
stream_t *stream_new_entry(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
441

Uwe Schulzweida's avatar
Uwe Schulzweida committed
442
  cdiInitialize(); /* ***************** make MT version !!! */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
444
  STREAM_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445

Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
  streamptr = (stream_t *) malloc(sizeof(stream_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
447
448
449
450
451
452
453

  if ( streamptr ) stream_init_entry(streamptr);

  return (streamptr);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
void stream_delete_entry(stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
456
457
458
459
{
  int idx;

  idx = streamptr->self;

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
460
  STREAM_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
463
464
465

  free(streamptr);

  _streamList[idx].next = _streamAvail;
  _streamList[idx].ptr  = 0;
466
  _streamAvail          = idx;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
468
  STREAM_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469
470

  if ( STREAM_Debug )
471
    Message("Removed idx %d from stream list", idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
472
473
474
}


Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
475
476
static
void stream_initialize(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
477
478
479
480
481
482
483
484
485
486
487
488
489
490
{
  char *env;

#if  defined  (HAVE_LIBPTHREAD)
  /* initialize global API mutex lock */
  pthread_mutex_init(&_stream_mutex, NULL);
#endif

  env = getenv("STREAM_DEBUG");
  if ( env ) STREAM_Debug = atoi(env);

  stream_list_new();
  atexit(stream_list_delete);

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
491
  STREAM_LOCK();
492

Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
494
  stream_init_pointer();

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
495
  STREAM_UNLOCK();
496

Uwe Schulzweida's avatar
Uwe Schulzweida committed
497
498
499
500
  _stream_init = TRUE;
}


501
void stream_check_ptr(const char *caller, stream_t *streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
503
{
  if ( streamptr == NULL )
504
    Errorc("stream undefined!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
506
507
508
509
510
511
512
}


int streamSize(void)
{
  int streamsize = 0;
  int i;
  
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
513
  STREAM_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
515
  STREAM_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516

517
  for ( i = 0; i < _stream_min; i++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
518
519
    if ( _streamList[i].ptr ) streamsize++;

Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
520
  STREAM_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
522
523
524
525

  return (streamsize);
}


526
void cdiDefGlobal(const char *string, int val)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
{
528
  if ( strcmp(string, "REGULARGRID") == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
530
    {
      cdiDataUnreduced = val;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
    }
532
533
534
535
  else if ( strcmp(string, "SORTNAME") == 0 )
    {
      cdiSortName = val;
    }
536
537
538
539
  else if ( strcmp(string, "HAVE_MISSVAL") == 0 )
    {
      cdiHaveMissval = val;
    }
540
541
542
543
  else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 )
    {
      cdiNcChunksizehint = val;
    }
544
545
  else
    {
546
      Warning("Unsupported global key: %s", string);
547
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
550


Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
552
553
554
555
556
557
558
559
560
561
562
void cdiDefMissval(double missval)
{
  cdiInitialize();

  cdiDefaultMissval = missval;
}


double cdiInqMissval(void)
{
  cdiInitialize();

563
  return (cdiDefaultMissval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
564
565
566
567
568
569
570
}


void cdiCheckContents(int streamID)
{
  int index, nzaxis, zaxisID;
  int vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
571
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572

Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
574
  streamptr = stream_to_pointer(streamID);

575
  stream_check_ptr(__func__, streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590

  vlistID = streamInqVlist(streamID);
  nzaxis = vlistNzaxis(vlistID);

  for ( index = 0; index < nzaxis; index++ )
    {
      zaxisID = vlistZaxis(vlistID, index);
      if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
	cdiCheckZaxis(zaxisID);
    }
}


int streamInqFileID(int streamID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595

  streamptr = stream_to_pointer(streamID);

  return (streamptr->fileID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597
598
599
600
}


void streamDefineTaxis(int streamID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602

Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
604
605
  streamptr = stream_to_pointer(streamID);

  if ( streamptr->tsteps == NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607
608
    {
      int varID, nvars;
      int vlistID;
609

Uwe Schulzweida's avatar
Uwe Schulzweida committed
610
611
612
613
      vlistID = streamInqVlist(streamID);

      nvars = vlistNvars(vlistID);
      for ( varID = 0; varID < nvars; varID++ )
614
	if ( vlistInqVarTsteptype(vlistID, varID) == TSTEP_CONSTANT ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
615
616
617
618
619
620
621
622

      if ( varID == nvars )
	{
	  int taxisID;

	  taxisID = vlistInqTaxis(vlistID);
	  if ( taxisID == CDI_UNDEFID )
	    {
623
	      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
625
	      vlistDefTaxis(vlistID, taxisID);
	    }
626

Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
628
629
	  (void) streamDefTimestep(streamID, 0);
	}
      else
630
	Error("time axis undefined");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
632
633
634
635
636
    }
}


void streamDefDimgroupID(int streamID, int dimgroupID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
639
640
641

  streamptr = stream_to_pointer(streamID);

  streamptr->dimgroupID = dimgroupID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
643
644
645
646
}


int streamInqDimgroupID(int streamID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
647
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
649
650
651

  streamptr = stream_to_pointer(streamID);

  return (streamptr->dimgroupID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
655
656
}


void cdiDefAccesstype(int streamID, int type)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658
659

  streamptr = stream_to_pointer(streamID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660

Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
  if ( streamptr->accesstype == UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
      streamptr->accesstype = type;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
665
666
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
      if ( streamptr->accesstype != type )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
668
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
	  if ( streamptr->accesstype == TYPE_REC )
670
	    Error("Changing access type from REC to VAR not allowed!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
671
	  else
672
	    Error("Changing access type from VAR to REC not allowed!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
675
676
677
678
679
	}
    }
}


int cdiInqAccesstype(int streamID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680
  stream_t *streamptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
682
683
684

  streamptr = stream_to_pointer(streamID);

  return (streamptr->accesstype);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
}
686
687
688
689
690
691
692
693
694
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */