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
124
125

  vlistptr = vlist_to_pointer(vlistID);
  
  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
142
143
    @Item  attnum   Attribute number (from 0 to natts-1).
    @Item  name     Pointer to the location for the returned attribute name. The caller must allocate space for the 
                    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;
156
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
157
158
  cdi_att_t *attp = NULL;
  cdi_atts_t *attsp;
159

Deike Kleberg's avatar
Deike Kleberg committed
160
  xassert(name != NULL);
161
162
163
164

  vlistptr = vlist_to_pointer(vlistID);

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

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

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

  return (status);
}


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

  vlistptr = vlist_to_pointer(vlistID);

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

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

  attsp->nelems = 0;

  return (status);
}


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

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

  return (status);
}

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

  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
238
  xassert(attsp != NULL);
239

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

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

247
248
249
  return (status);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
250
static
251
int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
252
253
{
  int status = CDI_NOERR;
254
  vlist_t *vlistptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
256
  cdi_att_t *attp;
  cdi_atts_t *attsp;
257
258
259
260
261
262
263
264
265
266
  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
267
  xassert(attsp != NULL);
268

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

  return (status);
}


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

  vlistptr1 = vlist_to_pointer(vlistID1);

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

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

  return (status);
}

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

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

@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
322
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
323
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
324
    @Item  name     Attribute name.
325
    @Item  type     External data type (@func{DATATYPE_INT16} or @func{DATATYPE_INT32}).
Deike Kleberg's avatar
Deike Kleberg committed
326
327
    @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
328
329
330
331
332
333

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

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

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

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

@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
346
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
347
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
348
    @Item  name     Attribute name.
349
    @Item  type     External data type (@func{DATATYPE_FLT32} or @func{DATATYPE_FLT64}).
Deike Kleberg's avatar
Deike Kleberg committed
350
351
    @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
352
353
354
355
356
357

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
363
364
365
366
367
368
369
/*
@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
370
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
371
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
372
373
374
    @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
375
376
377
378
379
380

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

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

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

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

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

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

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

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

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

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

434
@Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
437
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
438
439
440
    @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
441
442
443
444
445
446

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

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

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

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

Thomas Jahns's avatar
Thomas Jahns committed
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
501

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);
}


502
503
504
505
506
507
508
509
510
511
512
513
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);
514
515
516
517
  return txsize;
}

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

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

Deike Kleberg's avatar
Deike Kleberg committed
537
538
  xassert(attsp = get_attsp(vlistptr, varID));
  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
539
540
541
542
543
  attp = &(attsp->value[attnum]);
  tempbuf[0] = attp->namesz;
  tempbuf[1] = attp->exdtype;
  tempbuf[2] = attp->indtype;
  tempbuf[3] = attp->nelems;
544
545
546
547
  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);
548
549
550
551
}

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

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

571
572
  serializeUnpack(buf, size, position,
                  tempbuf, vlist_att_nints, DATATYPE_INT, context);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
  attName = (char*) xmalloc(tempbuf[0] + 1);
574
  serializeUnpack(buf, size, position, attName, tempbuf[0], DATATYPE_TXT, context);
575
  attName[tempbuf[0]] = '\0';
576
577
578
  switch (tempbuf[2])
  {
  case DATATYPE_FLT:
579
    attVDt = DATATYPE_FLT64;
580
581
582
    elemSize = sizeof(double);
    break;
  case DATATYPE_INT:
583
    attVDt = DATATYPE_INT;
584
585
586
    elemSize = sizeof(int);
    break;
  case DATATYPE_TXT:
587
    attVDt = DATATYPE_TXT;
588
589
590
    elemSize = 1;
    break;
  default:
591
592
    xabort("Unknown datatype encountered in attribute %s: %d\n",
           attName, tempbuf[2]);
593
  }
594
595
  void *attData = xmalloc(elemSize * tempbuf[3]);
  serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
596
597
598
599
600
601
602
603
  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,
604
                void * buf, int size, int *position, void *context)
605
606
{
  int numAtts, i;
607
  serializeUnpack(buf, size, position, &numAtts, 1, DATATYPE_INT, context);
608
609
  for (i = 0; i < numAtts; ++i)
  {
610
    vlistAttUnpack(vlistID, varID, buf, size, position, context);
611
612
613
  }
}

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