vlist_att.c 16.5 KB
Newer Older
1
2
3
4
#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

5
6
#include <stdio.h>
#include <string.h>
7
#include <assert.h>
8
9
10
11

#include "dmemory.h"

#include "cdi.h"
12
#include "cdi_int.h"
13
#include "vlist.h"
14
#include "error.h"
15
#include "serialize.h"
16

Uwe Schulzweida's avatar
Uwe Schulzweida committed
17
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
19
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
20
  cdi_atts_t *attsp = NULL;
21
22
23
24
25
26
27

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

  return (attsp);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
42
  xassert(attsp != NULL);
43
44
45
46
47

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

  slen = strlen(name);

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

  return (NULL);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
67
68
  xassert(attsp != NULL);
  xassert(name  != NULL);
69
70
71

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

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

  slen = strlen(name);

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

82
  return (attp);
83
84
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
static
86
void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t xsz, const void *xvalue)
87
{
Deike Kleberg's avatar
Deike Kleberg committed
88
  xassert(attp != NULL);
89

90
  attp->xsz = xsz;
91
92
93
  attp->indtype = indtype;
  attp->exdtype = exdtype;
  attp->nelems  = nelems;
94

95
96
  if ( xsz > 0 )
    {
97
      attp->xvalue = xrealloc(attp->xvalue, xsz);
98
99
      memcpy(attp->xvalue, xvalue, xsz);
    }
100
101
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
103
104
105
106
107
/*
@Function  vlistInqNatts
@Title     Get number of variable attributes

@Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
109
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
110
    @Item  nattsp   Pointer to location for returned number of variable attributes.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
114
115
116

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

@EndFunction
*/
117
118
119
int vlistInqNatts(int vlistID, int varID, int *nattsp)
{
  int status = CDI_NOERR;
120
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
  cdi_atts_t *attsp;
122
123

  vlistptr = vlist_to_pointer(vlistID);
124

125
  attsp = get_attsp(vlistptr, varID);
Deike Kleberg's avatar
Deike Kleberg committed
126
  xassert(attsp != NULL);
127
128
129
130
131
132

  *nattsp = attsp->nelems;

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
134
135
136
137
138
/*
@Function  vlistInqAtt
@Title     Get information about an attribute

@Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
140
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
141
    @Item  attnum   Attribute number (from 0 to natts-1).
142
    @Item  name     Pointer to the location for the returned attribute name. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
143
                    returned string. The maximum possible length, in characters, of
144
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Deike Kleberg's avatar
Deike Kleberg committed
145
146
    @Item  typep    Pointer to location for returned attribute type.
    @Item  lenp     Pointer to location for returned attribute number.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147
148

@Description
149
The function @func{vlistInqAtt} gets information about an attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150
151
152

@EndFunction
*/
153
int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
154
155
{
  int status = CDI_NOERR;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156
  cdi_att_t *attp = NULL;
157

Deike Kleberg's avatar
Deike Kleberg committed
158
  xassert(name != NULL);
159

160
  vlist_t *vlistptr = vlist_to_pointer(vlistID);
161

162
  cdi_atts_t *attsp = get_attsp(vlistptr, varID);
Deike Kleberg's avatar
Deike Kleberg committed
163
  xassert(attsp != NULL);
164

165
166
  if ( attnum >= 0 && attnum < (int)attsp->nelems )
    attp = &(attsp->value[attnum]);
167

168
  if ( attp != NULL ) /* name in use */
169
    {
170
      memcpy(name, attp->name, attp->namesz+1);
171
      *typep  = attp->exdtype;
172
      *lenp   = attp->nelems;
173
174
175
176
177
178
    }
  else
    {
      name[0] =  0;
      *typep  = -1;
      *lenp   =  0;
179
      status  = -1;
180
181
182
183
184
185
186
187
188
    }

  return (status);
}


int vlistDelAtts(int vlistID, int varID)
{
  int status = CDI_NOERR;
189
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
190
191
  cdi_att_t *attp = NULL;
  cdi_atts_t *attsp;
192
  int attid;
193
194
195
196

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Deike Kleberg's avatar
Deike Kleberg committed
197
  xassert(attsp != NULL);
198

199
  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
200
    {
201
202
203
      attp = &(attsp->value[attid]);
      if ( attp->name   ) free(attp->name);
      if ( attp->xvalue ) free(attp->xvalue);
204
205
206
207
208
209
210
211
    }

  attsp->nelems = 0;

  return (status);
}


212
int vlistDelAtt(int vlistID, int varID, const char *name)
213
214
215
{
  int status = CDI_NOERR;

216
  fprintf(stderr, "vlistDelAtt not implemented!\n");
217
218
219
220

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
static
222
int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
223
224
{
  int status = CDI_NOERR;
225
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
226
227
  cdi_att_t *attp;
  cdi_atts_t *attsp;
228
229
230
231
232
233
234
235
236

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

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Deike Kleberg's avatar
Deike Kleberg committed
237
  xassert(attsp != NULL);
238

239
  attp = find_att(attsp, name);
240
241
  if ( attp == NULL )
    attp = new_att(attsp, name);
242

243
  if ( attp != NULL )
244
    fill_att(attp, indtype, exdtype, len, xsz, xp);
245

246
247
248
  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
static
250
int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
251
252
{
  int status = CDI_NOERR;
253
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
255
  cdi_att_t *attp;
  cdi_atts_t *attsp;
256
257
258
259
260
261
262
263
264
265
  size_t xsz;

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

  vlistptr = vlist_to_pointer(vlistID);

  attsp = get_attsp(vlistptr, varID);
Deike Kleberg's avatar
Deike Kleberg committed
266
  xassert(attsp != NULL);
267

268
269
  attp = find_att(attsp, name);
  if ( attp != NULL ) /* name in use */
270
    {
271
272
273
274
275
276
277
278
279
280
281
      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);
	}
282
283
284
    }
  else
    {
285
      Warning("Internal problem, attribute %s not found!", name);
286
287
288
289
290
291
292
293
294
    }

  return (status);
}


int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2)
{
  int status = CDI_NOERR;
295
  vlist_t *vlistptr1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
296
297
  cdi_att_t *attp = NULL;
  cdi_atts_t *attsp1;
298
  int attid;
299
300
301
302

  vlistptr1 = vlist_to_pointer(vlistID1);

  attsp1 = get_attsp(vlistptr1, varID_1);
Deike Kleberg's avatar
Deike Kleberg committed
303
  xassert(attsp1 != NULL);
304

305
  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
306
    {
307
      attp = &(attsp1->value[attid]);
308
      vlist_def_att(attp->indtype, attp->exdtype, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
309
310
311
312
313
    }

  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
315
316
317
/*
@Function  vlistDefAttInt
@Title     Define an integer attribute

318
@Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
320

@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
321
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
322
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
323
    @Item  name     Attribute name.
324
    @Item  type     External data type (@func{DATATYPE_INT16} or @func{DATATYPE_INT32}).
Deike Kleberg's avatar
Deike Kleberg committed
325
326
    @Item  len      Number of values provided for the attribute.
    @Item  ip       Pointer to one or more integer values.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
328
329
330
331
332

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

@EndFunction
*/
333
int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
334
{
335
  return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
336
337
}

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

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

@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
345
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
346
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
347
    @Item  name     Attribute name.
348
    @Item  type     External data type (@func{DATATYPE_FLT32} or @func{DATATYPE_FLT64}).
Deike Kleberg's avatar
Deike Kleberg committed
349
350
    @Item  len      Number of values provided for the attribute.
    @Item  dp       Pointer to one or more floating point values.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
352
353
354
355
356

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

@EndFunction
*/
357
int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
358
{
359
  return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
360
361
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
362
363
364
365
366
367
368
/*
@Function  vlistDefAttTxt
@Title     Define a text attribute

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

@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
369
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
370
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
371
372
373
    @Item  name     Attribute name.
    @Item  len      Number of values provided for the attribute.
    @Item  tp       Pointer to one or more character values.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
374
375
376
377
378
379

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

@EndFunction
*/
380
int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
381
{
382
  return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
383
384
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
386
387
388
389
390
/*
@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
Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
392
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
393
394
395
    @Item  name     Attribute name.
    @Item  mlen     Number of allocated values provided for the attribute.
    @Item  ip       Pointer location for returned integer attribute value(s).
396

Uwe Schulzweida's avatar
Uwe Schulzweida committed
397
398
399
400
401
@Description
The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.

@EndFunction
*/
402
int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
403
{
404
  return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, mlen*sizeof(int), (void *) ip);
405
406
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
408
409
410
/*
@Function  vlistInqAttFlt
@Title     Get the value(s) of a floating point attribute

411
@Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
414
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
415
416
417
    @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).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
418
419
420
421
422
423

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

@EndFunction
*/
424
int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
425
{
426
  return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
427
428
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
/*
@Function  vlistInqAttTxt
@Title     Get the value(s) of a text attribute

433
@Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
436
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
437
438
439
    @Item  name     Attribute name.
    @Item  mlen     Number of allocated values provided for the attribute.
    @Item  tp       Pointer location for returned text attribute value(s).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440
441
442
443
444
445

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

@EndFunction
*/
446
int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
447
{
448
  return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
449
}
450
451
452
453
454

enum {
  vlist_att_nints = 4,          /* namesz, exdtype, indtype, nelems */
};

455
456
static inline int
vlistAttTypeLookup(cdi_att_t *attp)
457
{
458
  int type;
Thomas Jahns's avatar
Thomas Jahns committed
459
  switch (attp->indtype)
460
461
  {
  case DATATYPE_FLT:
462
    type = DATATYPE_FLT64;
463
464
465
    break;
  case DATATYPE_INT:
  case DATATYPE_TXT:
466
    type = attp->indtype;
467
468
    break;
  default:
469
    xabort("Unknown datatype encountered in attribute %s: %d\n",
Thomas Jahns's avatar
Thomas Jahns committed
470
            attp->name, attp->indtype);
471
  }
472
473
474
  return type;
}

Thomas Jahns's avatar
Thomas Jahns committed
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB,
                      int attnum)
{
  cdi_atts_t *attspa = get_attsp(a, varIDA),
    *attspb = get_attsp(b, varIDB);
  if (attspa == NULL && attspb == NULL)
    return 0;
  xassert(attnum >= 0 && attnum < (int)attspa->nelems
          && attnum < (int)attspb->nelems);
  cdi_att_t *attpa = attspa->value + attnum,
    *attpb = attspb->value + attnum;
  size_t len;
  if ((len = attpa->namesz) != attpb->namesz)
    return 1;
  int diff;
  if ((diff = memcmp(attpa->name, attpb->name, len)))
    return 1;
  if (attpa->indtype != attpb->indtype
      || attpa->exdtype != attpb->exdtype
      || attpa->nelems != attpb->nelems)
    return 1;
  return memcmp(attpa->xvalue, attpb->xvalue, attpa->xsz);
}


501
502
503
504
505
506
507
508
509
510
511
512
static int
vlistAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
{
  cdi_atts_t *attsp;
  cdi_att_t *attp;

  xassert(attsp = get_attsp(vlistptr, varID));
  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
  attp = &(attsp->value[attnum]);
  int txsize = serializeGetSize(vlist_att_nints, DATATYPE_INT, context)
    + serializeGetSize(attp->namesz, DATATYPE_TXT, context);
  txsize += serializeGetSize((int)attp->nelems, vlistAttTypeLookup(attp), context);
513
514
515
516
  return txsize;
}

int
517
vlistAttsGetSize(vlist_t *p, int varID, void *context)
518
519
520
{
  int numAtts, i;
  cdi_atts_t *attsp = get_attsp(p, varID);
521
  int txsize = serializeGetSize(1, DATATYPE_INT, context);
522
523
  numAtts = attsp->nelems;
  for (i = 0; i < numAtts; ++i)
524
    txsize += vlistAttGetSize(p, varID, i, context);
525
526
527
  return txsize;
}

528
static void
529
vlistAttPack(vlist_t *vlistptr, int varID, int attnum,
530
             void * buf, int size, int *position, void *context)
531
532
533
534
535
{
  cdi_atts_t *attsp;
  cdi_att_t *attp;
  int tempbuf[vlist_att_nints];

Deike Kleberg's avatar
Deike Kleberg committed
536
537
  xassert(attsp = get_attsp(vlistptr, varID));
  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
538
539
540
541
542
  attp = &(attsp->value[attnum]);
  tempbuf[0] = attp->namesz;
  tempbuf[1] = attp->exdtype;
  tempbuf[2] = attp->indtype;
  tempbuf[3] = attp->nelems;
543
544
545
546
  serializePack(tempbuf, vlist_att_nints, DATATYPE_INT, buf, size, position, context);
  serializePack(attp->name, attp->namesz, DATATYPE_TXT, buf, size, position, context);
  serializePack(attp->xvalue, (int)attp->nelems, vlistAttTypeLookup(attp),
                buf, size, position, context);
547
548
549
550
}

void
vlistAttsPack(vlist_t *p, int varID,
551
              void * buf, int size, int *position, void *context)
552
553
554
555
{
  int numAtts, i;
  cdi_atts_t *attsp = get_attsp(p, varID);
  numAtts = attsp->nelems;
556
  serializePack(&numAtts, 1, DATATYPE_INT, buf, size, position, context);
557
  for (i = 0; i < numAtts; ++i)
558
    vlistAttPack(p, varID, i, buf, size, position, context);
559
560
}

561
static void
562
vlistAttUnpack(int vlistID, int varID,
563
               void * buf, int size, int *position, void *context)
564
565
566
{
  char *attName;
  int tempbuf[vlist_att_nints];
567
  int attVDt;
568
  int elemSize;
569

570
571
  serializeUnpack(buf, size, position,
                  tempbuf, vlist_att_nints, DATATYPE_INT, context);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
  attName = (char*) xmalloc(tempbuf[0] + 1);
573
  serializeUnpack(buf, size, position, attName, tempbuf[0], DATATYPE_TXT, context);
574
  attName[tempbuf[0]] = '\0';
575
576
577
  switch (tempbuf[2])
  {
  case DATATYPE_FLT:
578
    attVDt = DATATYPE_FLT64;
579
580
581
    elemSize = sizeof(double);
    break;
  case DATATYPE_INT:
582
    attVDt = DATATYPE_INT;
583
584
585
    elemSize = sizeof(int);
    break;
  case DATATYPE_TXT:
586
    attVDt = DATATYPE_TXT;
587
588
589
    elemSize = 1;
    break;
  default:
590
591
    xabort("Unknown datatype encountered in attribute %s: %d\n",
           attName, tempbuf[2]);
592
  }
593
594
  void *attData = xmalloc(elemSize * tempbuf[3]);
  serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
595
596
597
598
599
600
601
602
  vlist_def_att(tempbuf[2], tempbuf[1], vlistID, varID, attName,
                tempbuf[3], tempbuf[3] * elemSize, attData);
  free(attName);
  free(attData);
}

void
vlistAttsUnpack(int vlistID, int varID,
603
                void * buf, int size, int *position, void *context)
604
605
{
  int numAtts, i;
606
  serializeUnpack(buf, size, position, &numAtts, 1, DATATYPE_INT, context);
607
608
  for (i = 0; i < numAtts; ++i)
  {
609
    vlistAttUnpack(vlistID, varID, buf, size, position, context);
610
611
612
  }
}

613
614
615
616
617
618
619
620
621
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */