vlist_att.c 11.6 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
Uwe Schulzweida's avatar
Uwe Schulzweida committed
13
cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
14
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
  cdi_atts_t *attsp = NULL;
16
17
18
19
20
21
22

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

  return (attsp);
}

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

  assert(attsp != NULL);

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

  slen = strlen(name);

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

  return (NULL);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
58
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
  cdi_att_t *attp;
60
61
62
63
64
65
66
  size_t slen;

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

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

67
  attp = &(attsp->value[attsp->nelems]);
68
69
70
71
  attsp->nelems++;

  slen = strlen(name);

72
73
74
  attp->name = (char *) malloc(slen+1);
  memcpy(attp->name, name, slen+1);
  attp->namesz = slen;
75
  attp->xvalue = NULL;
76

77
  return (attp);
78
79
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
static
81
void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t xsz, const void *xvalue)
82
{
83
  assert(attp != NULL);
84

85
  attp->xsz = xsz;
86
87
88
  attp->indtype = indtype;
  attp->exdtype = exdtype;
  attp->nelems  = nelems;
89

90
91
  if ( xsz > 0 )
    {
92
      attp->xvalue = (void *) realloc(attp->xvalue, xsz);
93
94
      memcpy(attp->xvalue, xvalue, xsz);
    }
95
96
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
@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
*/
112
113
114
int vlistInqNatts(int vlistID, int varID, int *nattsp)
{
  int status = CDI_NOERR;
115
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
  cdi_atts_t *attsp;
117
118
119
120

  vlistptr = vlist_to_pointer(vlistID);
  
  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
  assert(attsp != NULL);
122
123
124
125
126
127

  *nattsp = attsp->nelems;

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
@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
*/
146
int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
147
148
{
  int status = CDI_NOERR;
149
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150
151
  cdi_att_t *attp = NULL;
  cdi_atts_t *attsp;
152
153
154
155
156
157

  assert(name != NULL);

  vlistptr = vlist_to_pointer(vlistID);

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

160
161
  if ( attnum >= 0 && attnum < (int)attsp->nelems )
    attp = &(attsp->value[attnum]);
162

163
  if ( attp != NULL ) /* name in use */
164
    {
165
      memcpy(name, attp->name, attp->namesz+1);
166
      *typep  = attp->exdtype;
167
      *lenp   = attp->nelems;
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    }
  else
    {
      name[0] =  0;
      *typep  = -1;
      *lenp   =  0;
    }

  return (status);
}


int vlistDelAtts(int vlistID, int varID)
{
  int status = CDI_NOERR;
183
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
184
185
  cdi_att_t *attp = NULL;
  cdi_atts_t *attsp;
186
  int attid;
187
188
189
190

  vlistptr = vlist_to_pointer(vlistID);

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

193
  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
194
    {
195
196
197
      attp = &(attsp->value[attid]);
      if ( attp->name   ) free(attp->name);
      if ( attp->xvalue ) free(attp->xvalue);
198
199
200
201
202
203
204
205
    }

  attsp->nelems = 0;

  return (status);
}


206
int vlistDelAtt(int vlistID, int varID, const char *name)
207
208
209
{
  int status = CDI_NOERR;

210
  fprintf(stderr, "vlistDelAtt not implemented!\n");
211
212
213
214

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
static
216
int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
217
218
{
  int status = CDI_NOERR;
219
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
221
  cdi_att_t *attp;
  cdi_atts_t *attsp;
222
223
224
225
226
227
228
229
230

  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
231
  assert(attsp != NULL);
232

233
  attp = find_att(attsp, name);
234
235
  if ( attp == NULL )
    attp = new_att(attsp, name);
236

237
  if ( attp != NULL )
238
    fill_att(attp, indtype, exdtype, len, xsz, xp);
239
  
240
241
242
  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
243
static
244
int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
245
246
{
  int status = CDI_NOERR;
247
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
249
  cdi_att_t *attp;
  cdi_atts_t *attsp;
250
251
252
253
254
255
256
257
258
259
  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
260
  assert(attsp != NULL);
261

262
263
  attp = find_att(attsp, name);
  if ( attp != NULL ) /* name in use */
264
    {
265
266
267
268
269
270
271
272
273
274
275
      if ( attp->indtype == indtype )
	{
	  xsz = attp->xsz;
	  if ( mxsz < xsz ) xsz = mxsz;
	  if ( xsz > 0 )
	    memcpy(xp, attp->xvalue, xsz);
	}
      else
	{
	  Warning("Attribute %s has wrong data type!", name);
	}
276
277
278
    }
  else
    {
279
      Warning("Internal problem, attribute %s not found!", name);
280
281
282
283
284
285
286
287
288
    }

  return (status);
}


int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2)
{
  int status = CDI_NOERR;
289
  vlist_t *vlistptr1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
290
291
  cdi_att_t *attp = NULL;
  cdi_atts_t *attsp1;
292
  int attid;
293
294
295
296

  vlistptr1 = vlist_to_pointer(vlistID1);

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

299
  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
300
    {
301
      attp = &(attsp1->value[attid]);
302
      vlist_def_att(attp->indtype, attp->exdtype, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
303
304
305
306
307
    }

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
308
309
310
311
/*
@Function  vlistDefAttInt
@Title     Define an integer attribute

312
@Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
316
317

@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
318
    @Item  type     External data type (DATATYPE_INT16 or DATATYPE_INT32)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
320
321
322
323
324
325
326
    @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
*/
327
int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
328
329
330
{
  int status;

331
  status = vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
332
333
334
335

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
337
338
339
/*
@Function  vlistDefAttFlt
@Title     Define a floating point attribute

340
@Prototype int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341
342
343
344
345

@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
346
    @Item  type     External data type (DATATYPE_FLT32 or DATATYPE_FLT64)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
348
349
350
351
352
353
354
    @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
*/
355
int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
356
357
358
{
  int status;

359
  status = vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
360
361
362
363

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
/*
@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
*/
382
int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
383
384
385
{
  int status;

386
  status = vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
387
388
389
390

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
392
393
394
395
396
397
398
399
400
401
/*
@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)
402

Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405
406
407
@Description
The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.

@EndFunction
*/
408
int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
409
410
411
{
  int status = CDI_NOERR;

412
  status = vlist_inq_att(DATATYPE_INT, vlistID, varID, name, mlen*sizeof(int), (void *) ip);
413
414
415
416

  return (CDI_NOERR);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
/*
@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
*/
434
int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
435
436
437
{
  int status = CDI_NOERR;

438
  status = vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
439
440
441
442

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
/*
@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
*/
460
int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
461
462
463
{
  int status = CDI_NOERR;

464
  status = vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
465
466
467

  return (status);
}