vlist_att.c 11.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "dmemory.h"

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


Uwe Schulzweida's avatar
Uwe Schulzweida committed
12
static
13
CDI_atts *get_attsp(vlist_t *vlistptr, int varID)
14
15
16
17
18
19
20
21
22
23
{
  static char func[] = "get_attsp";
  CDI_atts *attsp = NULL;

  if ( varID == CDI_GLOBAL )
    {
      attsp = &vlistptr->atts;
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24
25
      if ( varID >= 0 && varID < vlistptr->nvars )
	attsp = &(vlistptr->vars[varID].atts);
26
27
28
29
30
31
    }

  return (attsp);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
static
33
CDI_att *find_att(CDI_atts *attsp, const char *name)
34
{
35
36
  CDI_att *attp;
  size_t attid;
37
38
39
40
41
42
43
44
  size_t slen;

  assert(attsp != NULL);

  if ( attsp->nelems == 0 ) return NULL;

  slen = strlen(name);

45
  for ( attid = 0; attid < attsp->nelems; attid++ )
46
    {
47
48
      attp = &(attsp->value[attid]);
      if ( attp->namesz == slen )
49
	if ( memcmp(attp->name, name, slen) == 0)
50
	  {
51
	    return (attp); /* Normal return */
52
53
54
55
56
57
58
	  }
    }

  return (NULL);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
static
60
CDI_att *new_att(CDI_atts *attsp, const char *name)
61
{
62
63
  static char func[] = "new_att";
  CDI_att *attp;
64
65
66
67
68
69
70
  size_t slen;

  assert(attsp != NULL);
  assert(name  != NULL);

  if ( attsp->nelems == attsp->nalloc ) return (NULL);

71
  attp = &(attsp->value[attsp->nelems]);
72
73
74
75
  attsp->nelems++;

  slen = strlen(name);

76
77
78
  attp->name = (char *) malloc(slen+1);
  memcpy(attp->name, name, slen+1);
  attp->namesz = slen;
79
  attp->xvalue = NULL;
80

81
  return (attp);
82
83
84
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
static
86
void fill_att(CDI_att *attp, int type, size_t nelems, size_t xsz, const void *xvalue)
87
{
88
  static char func[] = "fill_att";
89

90
  assert(attp != NULL);
91

92
93
94
  attp->xsz = xsz;
  attp->type = type;
  attp->nelems = nelems;
95

96
97
  if ( xsz > 0 )
    {
98
      attp->xvalue = (void *) realloc(attp->xvalue, xsz);
99
100
      memcpy(attp->xvalue, xvalue, xsz);
    }
101
102
103
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
@Function  vlistInqNatts
@Title     Get number of variable attributes

@Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  nattsp   Pointer to location for returned number of variable attributes

@Description
The function @func{vlistInqNatts} gets the number of variable attributes assigned to this variable.

@EndFunction
*/
119
120
121
122
int vlistInqNatts(int vlistID, int varID, int *nattsp)
{
  static char func[] = "vlistInqNatts";
  int status = CDI_NOERR;
123
  vlist_t *vlistptr;
124
125
126
127
128
  CDI_atts *attsp;

  vlistptr = vlist_to_pointer(vlistID);
  
  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
129
  assert(attsp != NULL);
130
131
132
133
134
135
136

  *nattsp = attsp->nelems;

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
@Function  vlistInqAtt
@Title     Get information about an attribute

@Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  attnum   Attribute number (from 0 to natts-1)
    @Item  name     Pointer to the location for the returned attribute name
    @Item  typep    Pointer to location for returned attribute type
    @Item  lenp     Pointer to location for returned attribute number

@Description
The function @func{vlistInqNatts} gets information about an attribute.

@EndFunction
*/
155
int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
156
{
157
  static char func[] = "vlistInqAtt";
158
  int status = CDI_NOERR;
159
  vlist_t *vlistptr;
160
  CDI_att *attp = NULL;
161
162
163
164
165
166
167
  CDI_atts *attsp;

  assert(name != NULL);

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
168
  assert(attsp != NULL);
169

170
171
  if ( attnum >= 0 && attnum < (int)attsp->nelems )
    attp = &(attsp->value[attnum]);
172

173
  if ( attp != NULL ) /* name in use */
174
    {
175
176
177
      memcpy(name, attp->name, attp->namesz+1);
      *typep  = attp->type;
      *lenp   = attp->nelems;
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    }
  else
    {
      name[0] =  0;
      *typep  = -1;
      *lenp   =  0;
    }

  return (status);
}


int vlistDelAtts(int vlistID, int varID)
{
  static char func[] = "vlistDelAtts";
  int status = CDI_NOERR;
194
  vlist_t *vlistptr;
195
  CDI_att *attp = NULL;
196
  CDI_atts *attsp;
197
  int attid;
198
199
200
201

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202
  assert(attsp != NULL);
203

204
  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
205
    {
206
207
208
      attp = &(attsp->value[attid]);
      if ( attp->name   ) free(attp->name);
      if ( attp->xvalue ) free(attp->xvalue);
209
210
211
212
213
214
215
216
    }

  attsp->nelems = 0;

  return (status);
}


217
int vlistDelAtt(int vlistID, int varID, const char *name)
218
219
220
{
  int status = CDI_NOERR;

221
  fprintf(stderr, "vlistDelAtt not implemented!\n");
222
223
224
225
226

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
static
228
int vlist_def_att(int type, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
229
{
230
  static char func[] = "vlist_def_att";
231
  int status = CDI_NOERR;
232
  vlist_t *vlistptr;
233
  CDI_att *attp;
234
235
236
237
238
239
240
241
242
243
  CDI_atts *attsp;

  if ( len != 0 && xp == NULL ) /* Null arg */
    {
      return (CDI_EINVAL);
    }

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
  assert(attsp != NULL);
245

246
  attp = find_att(attsp, name);
247
248
  if ( attp == NULL )
    attp = new_att(attsp, name);
249

250
251
252
  if ( attp != NULL )
    fill_att(attp, type, len, xsz, xp);
  
253
254
255
256
  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
static
258
int vlist_inq_att(int type, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
259
{
260
  static char func[] = "vlist_inq_att";
261
  int status = CDI_NOERR;
262
  vlist_t *vlistptr;
263
  CDI_att *attp;
264
265
266
267
268
269
270
271
272
273
274
  CDI_atts *attsp;
  size_t xsz;

  if ( mxsz != 0 && xp == NULL ) /* Null arg */
    {
      return (CDI_EINVAL);
    }

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
  assert(attsp != NULL);
276

277
278
  attp = find_att(attsp, name);
  if ( attp != NULL ) /* name in use */
279
    {
280
      xsz = attp->xsz;
281
      if ( mxsz < xsz ) xsz = mxsz;
282
283
      if ( xsz > 0 )
	memcpy(xp, attp->xvalue, xsz);
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    }
  else
    {
      Warning(func, "Internal problem, attribute %s not found!", name);
    }

  return (status);
}


int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2)
{
  static char func[] = "vlistCopyVarAtts";
  int status = CDI_NOERR;
298
  vlist_t *vlistptr1;
299
  CDI_att *attp = NULL;
300
  CDI_atts *attsp1;
301
  int attid;
302
303
304
305

  vlistptr1 = vlist_to_pointer(vlistID1);

  attsp1 = get_attsp(vlistptr1, varID_1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
306
  assert(attsp1 != NULL);
307

308
  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
309
    {
310
311
      attp = &(attsp1->value[attid]);
      vlist_def_att(attp->type, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
312
313
314
315
316
317
    }

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/*
@Function  vlistDefAttInt
@Title     Define an integer attribute

@Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int len, const int *ip)

@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  name     Attribute name
    @Item  len      Number of values provided for the attribute
    @Item  ip       Pointer to one or more integer values

@Description
The function @func{vlistDefAttInt} defines an integer attribute.

@EndFunction
*/
336
int vlistDefAttInt(int vlistID, int varID, const char *name, int len, const int *ip)
337
338
339
{
  int status;

340
  status = vlist_def_att(DATATYPE_INT, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
341
342
343
344
345

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
/*
@Function  vlistDefAttFlt
@Title     Define a floating point attribute

@Prototype int vlistDefAttFlt(int vlistID, int varID, const char *name, int len, const double *dp)

@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  name     Attribute name
    @Item  len      Number of values provided for the attribute
    @Item  dp       Pointer to one or more floating point values

@Description
The function @func{vlistDefAttFlt} defines a floating point attribute.

@EndFunction
*/
364
int vlistDefAttFlt(int vlistID, int varID, const char *name, int len, const double *dp)
365
366
367
{
  int status;

368
  status = vlist_def_att(DATATYPE_FLT, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
369
370
371
372
373

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
/*
@Function  vlistDefAttTxt
@Title     Define a text attribute

@Prototype int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)

@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  name     Attribute name
    @Item  len      Number of values provided for the attribute
    @Item  tp       Pointer to one or more character values

@Description
The function @func{vlistDefAttTxt} defines a text attribute.

@EndFunction
*/
392
int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
393
394
395
{
  int status;

396
  status = vlist_def_att(DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
397
398
399
400
401

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
402
403
404
405
406
407
408
409
410
411
412
/*
@Function  vlistInqAttInt
@Title     Get the value(s) of an integer attribute

@Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  name     Attribute name
    @Item  mlen     Number of allocated values provided for the attribute
    @Item  ip       Pointer location for returned integer attribute value(s)
413

Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
415
416
417
418
@Description
The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.

@EndFunction
*/
419
int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
420
421
422
{
  int status = CDI_NOERR;

423
  status = vlist_inq_att(DATATYPE_INT, vlistID, varID, name, mlen*sizeof(int), (void *) ip);
424
425
426
427
428

  return (CDI_NOERR);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
/*
@Function  vlistInqAttFlt
@Title     Get the value(s) of a floating point attribute

@Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, int *dp)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  name     Attribute name
    @Item  mlen     Number of allocated values provided for the attribute
    @Item  dp       Pointer location for returned floating point attribute value(s)

@Description
The function @func{vlistInqAttFlt} gets the values(s) of a floating point attribute.

@EndFunction
*/
446
int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
447
448
449
{
  int status = CDI_NOERR;

450
  status = vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
451
452
453
454
455

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
/*
@Function  vlistInqAttTxt
@Title     Get the value(s) of a text attribute

@Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, int *tp)
@Parameter
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
    @Item  varID    Variable identifier, or CDI_GLOBAL for a global attribute
    @Item  name     Attribute name
    @Item  mlen     Number of allocated values provided for the attribute
    @Item  tp       Pointer location for returned text attribute value(s)

@Description
The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.

@EndFunction
*/
473
int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
474
475
476
{
  int status = CDI_NOERR;

477
  status = vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
478
479
480

  return (status);
}