vlist_att.c 10.2 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
13
static
CDI_atts *get_attsp(VLIST *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
104
105
106
107
108
109
110
111
112
113
}


int vlistInqNatts(int vlistID, int varID, int *nattsp)
{
  static char func[] = "vlistInqNatts";
  int status = CDI_NOERR;
  VLIST *vlistptr;
  CDI_atts *attsp;

  vlistptr = vlist_to_pointer(vlistID);
  
  attsp = get_attsp(vlistptr, varID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
  assert(attsp != NULL);
115
116
117
118
119
120
121

  *nattsp = attsp->nelems;

  return (status);
}


122
int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
123
{
124
  static char func[] = "vlistInqAtt";
125
126
  int status = CDI_NOERR;
  VLIST *vlistptr;
127
  CDI_att *attp = NULL;
128
129
130
131
132
133
134
  CDI_atts *attsp;

  assert(name != NULL);

  vlistptr = vlist_to_pointer(vlistID);

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

137
138
  if ( attnum >= 0 && attnum < (int)attsp->nelems )
    attp = &(attsp->value[attnum]);
139

140
  if ( attp != NULL ) /* name in use */
141
    {
142
143
144
      memcpy(name, attp->name, attp->namesz+1);
      *typep  = attp->type;
      *lenp   = attp->nelems;
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
    }
  else
    {
      name[0] =  0;
      *typep  = -1;
      *lenp   =  0;
    }

  return (status);
}


int vlistDelAtts(int vlistID, int varID)
{
  static char func[] = "vlistDelAtts";
  int status = CDI_NOERR;
  VLIST *vlistptr;
162
  CDI_att *attp = NULL;
163
  CDI_atts *attsp;
164
  int attid;
165
166
167
168

  vlistptr = vlist_to_pointer(vlistID);

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

171
  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
172
    {
173
174
175
      attp = &(attsp->value[attid]);
      if ( attp->name   ) free(attp->name);
      if ( attp->xvalue ) free(attp->xvalue);
176
177
178
179
180
181
182
183
    }

  attsp->nelems = 0;

  return (status);
}


184
int vlistDelAtt(int vlistID, int varID, const char *name)
185
186
187
{
  int status = CDI_NOERR;

188
  fprintf(stderr, "vlistDelAtt not implemented!\n");
189
190
191
192
193

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
static
195
int vlist_def_att(int type, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
196
{
197
  static char func[] = "vlist_def_att";
198
199
  int status = CDI_NOERR;
  VLIST *vlistptr;
200
  CDI_att *attp;
201
202
203
204
205
206
207
208
209
210
  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
211
  assert(attsp != NULL);
212

213
  attp = find_att(attsp, name);
214
215
  if ( attp == NULL )
    attp = new_att(attsp, name);
216

217
218
219
  if ( attp != NULL )
    fill_att(attp, type, len, xsz, xp);
  
220
221
222
223
  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
static
225
int vlist_inq_att(int type, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
226
{
227
  static char func[] = "vlist_inq_att";
228
229
  int status = CDI_NOERR;
  VLIST *vlistptr;
230
  CDI_att *attp;
231
232
233
234
235
236
237
238
239
240
241
  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
242
  assert(attsp != NULL);
243

244
245
  attp = find_att(attsp, name);
  if ( attp != NULL ) /* name in use */
246
    {
247
      xsz = attp->xsz;
248
      if ( mxsz < xsz ) xsz = mxsz;
249
250
      if ( xsz > 0 )
	memcpy(xp, attp->xvalue, xsz);
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    }
  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;
  VLIST *vlistptr1;
266
  CDI_att *attp = NULL;
267
  CDI_atts *attsp1;
268
  int attid;
269
270
271
272

  vlistptr1 = vlist_to_pointer(vlistID1);

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

275
  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
276
    {
277
278
      attp = &(attsp1->value[attid]);
      vlist_def_att(attp->type, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
279
280
281
282
283
284
    }

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/*
@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
*/
303
int vlistDefAttInt(int vlistID, int varID, const char *name, int len, const int *ip)
304
305
306
{
  int status;

307
  status = vlist_def_att(DATATYPE_INT, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
308
309
310
311
312

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
/*
@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
*/
331
int vlistDefAttFlt(int vlistID, int varID, const char *name, int len, const double *dp)
332
333
334
{
  int status;

335
  status = vlist_def_att(DATATYPE_FLT, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
336
337
338
339
340

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/*
@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
*/
359
int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
360
361
362
{
  int status;

363
  status = vlist_def_att(DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
364
365
366
367
368

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
370
371
372
373
374
375
376
377
378
379
/*
@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)
380

Uwe Schulzweida's avatar
Uwe Schulzweida committed
381
382
383
384
385
@Description
The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.

@EndFunction
*/
386
int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
387
388
389
{
  int status = CDI_NOERR;

390
  status = vlist_inq_att(DATATYPE_INT, vlistID, varID, name, mlen*sizeof(int), (void *) ip);
391
392
393
394
395

  return (CDI_NOERR);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
/*
@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
*/
413
int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
414
415
416
{
  int status = CDI_NOERR;

417
  status = vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
418
419
420
421
422

  return (status);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/*
@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
*/
440
int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
441
442
443
{
  int status = CDI_NOERR;

444
  status = vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
445
446
447

  return (status);
}