cdi_att.c 16.7 KB
Newer Older
1 2
#include <assert.h>
#include <limits.h>
3 4 5 6 7 8
#include <stdio.h>
#include <string.h>

#include "dmemory.h"

#include "cdi.h"
9
#include "cdi_int.h"
10
#include "vlist.h"
11
#include "cdi_att.h"
12
#include "error.h"
13
#include "serialize.h"
14
#include "grid.h"
15
#include "zaxis.h"
16 17
#include "resource_unpack.h"

18

Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
20
cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
21
{
22 23
  if ( varID == CDI_GLOBAL ) return &vlistptr->atts;
  else if ( varID >= 0 && varID < vlistptr->nvars ) return &(vlistptr->vars[varID].atts);
24

25
  return NULL;
26 27
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29
cdi_att_t *find_att(cdi_atts_t *attsp, const char *name)
30
{
Deike Kleberg's avatar
Deike Kleberg committed
31
  xassert(attsp != NULL);
32 33 34

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

35
  size_t slen = strlen(name);
36
  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
37

Thomas Jahns's avatar
Thomas Jahns committed
38
  cdi_att_t *atts = attsp->value;
39
  for ( size_t attid = 0; attid < attsp->nelems; attid++ )
40
    {
Thomas Jahns's avatar
Thomas Jahns committed
41
      cdi_att_t *attp = atts + attid;
42
      if ( attp->namesz == slen && memcmp(attp->name, name, slen) == 0 )
43
        return attp; // Normal return
44 45
    }

46
  return NULL;
47 48
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
51
{
Deike Kleberg's avatar
Deike Kleberg committed
52 53
  xassert(attsp != NULL);
  xassert(name  != NULL);
54

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

57
  cdi_att_t *attp = &(attsp->value[attsp->nelems]);
58 59
  attsp->nelems++;

60
  size_t slen = strlen(name);
61
  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
62

63
  attp->name = (char *) Malloc(slen+1);
64 65
  memcpy(attp->name, name, slen+1);
  attp->namesz = slen;
66
  attp->xvalue = NULL;
67

68
  return attp;
69 70
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
static
72
void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t xsz, const void *xvalue)
73
{
Deike Kleberg's avatar
Deike Kleberg committed
74
  xassert(attp != NULL);
75

76
  attp->xsz = xsz;
77 78 79
  attp->indtype = indtype;
  attp->exdtype = exdtype;
  attp->nelems  = nelems;
80

81 82
  if ( xsz > 0 )
    {
83
      attp->xvalue = Realloc(attp->xvalue, xsz);
84 85
      memcpy(attp->xvalue, xvalue, xsz);
    }
86 87
}

88 89 90
static
cdi_atts_t *cdi_get_attsp(int objID, int varID)
{
91
  cdi_atts_t *attsp = NULL;
92

93 94
  if ( varID == CDI_GLOBAL && reshGetTxCode(objID) == GRID )
    {
95
      grid_t *gridptr = grid_to_pointer(objID);
96 97
      attsp = &gridptr->atts;
    }
98 99
  else if ( varID == CDI_GLOBAL && reshGetTxCode(objID) == ZAXIS )
    {
100
      zaxis_t *zaxisptr = zaxis_to_pointer(objID);
101 102
      attsp = &zaxisptr->atts;
    }
103 104 105 106 107
  else
    {
      vlist_t *vlistptr = vlist_to_pointer(objID);
      attsp = get_attsp(vlistptr, varID);
    }
108 109 110 111

  return attsp;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
112
/*
113
@Function  cdiInqNatts
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
@Title     Get number of attributes
Uwe Schulzweida's avatar
Uwe Schulzweida committed
115

116
@Prototype int cdiInqNatts(int cdiID, int varID, int *nattsp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
117
@Parameter
118
    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
119
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
120
    @Item  nattsp   Pointer to location for returned number of attributes.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121 122

@Description
123
The function @func{cdiInqNatts} gets the number of attributes assigned to this variable.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
124 125 126

@EndFunction
*/
127
int cdiInqNatts(int cdiID, int varID, int *nattsp)
128 129 130
{
  int status = CDI_NOERR;

131
  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
Deike Kleberg's avatar
Deike Kleberg committed
132
  xassert(attsp != NULL);
133

134
  *nattsp = (int)attsp->nelems;
135

136
  return status;
137 138
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
/*
140
@Function  cdiInqAtt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
141 142
@Title     Get information about an attribute

143
@Prototype int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *lenp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
144
@Parameter
145
    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
146
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
147
    @Item  attnum   Attribute number (from 0 to natts-1).
148
    @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
149
                    returned string. The maximum possible length, in characters, of
150
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Deike Kleberg's avatar
Deike Kleberg committed
151 152
    @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
153 154

@Description
155
The function @func{cdiInqAtt} gets information about an attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156 157 158

@EndFunction
*/
159
int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *lenp)
160 161 162
{
  int status = CDI_NOERR;

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

165
  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
Deike Kleberg's avatar
Deike Kleberg committed
166
  xassert(attsp != NULL);
167

168
  cdi_att_t *attp = NULL;
169 170
  if ( attnum >= 0 && attnum < (int)attsp->nelems )
    attp = &(attsp->value[attnum]);
171

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

186
  return status;
187 188 189
}


190
int cdiDeleteAtts(int cdiID, int varID)
191 192 193
{
  int status = CDI_NOERR;

194
  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
Deike Kleberg's avatar
Deike Kleberg committed
195
  xassert(attsp != NULL);
196

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

  attsp->nelems = 0;

206
  return status;
207 208 209
}


210
int cdiDelAtt(int cdiID, int varID, const char *name)
211 212 213
{
  int status = CDI_NOERR;

214
  UNUSED(cdiID);
215 216 217
  UNUSED(varID);
  UNUSED(name);

218
  fprintf(stderr, "cdiDelAtt not implemented!\n");
219

220
  return status;
221 222
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
static
224
int cdi_def_att(int indtype, int exdtype, int cdiID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
225 226 227
{
  int status = CDI_NOERR;

228
  if ( len != 0 && xp == NULL ) // Null arg
229
    return CDI_EINVAL;
230

231
  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
Deike Kleberg's avatar
Deike Kleberg committed
232
  xassert(attsp != NULL);
233

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

237
  if ( attp != NULL ) fill_att(attp, indtype, exdtype, len, xsz, xp);
238

239
  return status;
240 241
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
242
static
243
int cdi_inq_att(int indtype, int cdiID, int varID, const char *name, size_t mxsz, void *xp)
244 245 246
{
  int status = CDI_NOERR;

247
  if ( mxsz != 0 && xp == NULL ) // Null arg
248
    return CDI_EINVAL;
249

250
  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
Deike Kleberg's avatar
Deike Kleberg committed
251
  xassert(attsp != NULL);
252

253
  cdi_att_t *attp = find_att(attsp, name);
254
  if ( attp != NULL ) // name in use
255
    {
256 257
      if ( attp->indtype == indtype )
	{
258
	  size_t xsz = attp->xsz;
259 260 261 262 263 264 265
	  if ( mxsz < xsz ) xsz = mxsz;
	  if ( xsz > 0 )
	    memcpy(xp, attp->xvalue, xsz);
	}
      else
	{
	  Warning("Attribute %s has wrong data type!", name);
266
          status = -2;
267
	}
268 269 270
    }
  else
    {
271 272
      //Warning("Internal problem, attribute %s not found!", name);
      status = -1;
273 274
    }

275
  return status;
276 277 278
}


279
int cdiCopyAtts(int cdiID1, int varID1, int cdiID2, int varID2)
280 281 282
{
  int status = CDI_NOERR;

283
  cdi_atts_t *attsp1 = cdi_get_attsp(cdiID1, varID1);
Deike Kleberg's avatar
Deike Kleberg committed
284
  xassert(attsp1 != NULL);
285

286
  for ( size_t attid = 0; attid < attsp1->nelems; attid++ )
287
    {
288
      cdi_att_t *attp = &(attsp1->value[attid]);
289
      cdi_def_att(attp->indtype, attp->exdtype, cdiID2, varID2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
290 291
    }

292
  return status;
293 294
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
295
/*
296
@Function  cdiDefAttInt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
297 298
@Title     Define an integer attribute

299
@Prototype int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int *ip)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
300 301

@Parameter
302
    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
303
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
304
    @Item  name     Attribute name.
305
    @Item  type     External data type (@func{CDI_DATATYPE_INT16} or @func{CDI_DATATYPE_INT32}).
Deike Kleberg's avatar
Deike Kleberg committed
306 307
    @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
308 309

@Description
310
The function @func{cdiDefAttInt} defines an integer attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311 312 313

@EndFunction
*/
314
int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int *ip)
315
{
316
  return cdi_def_att(CDI_DATATYPE_INT, type, cdiID, varID, name, (size_t)len, (size_t)len * sizeof(int), ip);
317 318
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
/*
320
@Function  cdiDefAttFlt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
321 322
@Title     Define a floating point attribute

323
@Prototype int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double *dp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324 325

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

@Description
334
The function @func{cdiDefAttFlt} defines a floating point attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335 336 337

@EndFunction
*/
338
int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double *dp)
339
{
340
  return cdi_def_att(CDI_DATATYPE_FLT, type, cdiID, varID, name, (size_t)len, (size_t)len * sizeof(double), dp);
341 342
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
343
/*
344
@Function  cdiDefAttTxt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345 346
@Title     Define a text attribute

347
@Prototype int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348 349

@Parameter
350
    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
351
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
352 353 354
    @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
355 356

@Description
357
The function @func{cdiDefAttTxt} defines a text attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358 359 360

@EndFunction
*/
361
int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp)
362
{
363
  return cdi_def_att(CDI_DATATYPE_TXT, CDI_DATATYPE_TXT, cdiID, varID, name, (size_t)len, (size_t)len, tp);
364 365
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
366
/*
367
@Function  cdiInqAttInt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368 369
@Title     Get the value(s) of an integer attribute

370
@Prototype int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int *ip)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
@Parameter
372
    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
373
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
374 375 376
    @Item  name     Attribute name.
    @Item  mlen     Number of allocated values provided for the attribute.
    @Item  ip       Pointer location for returned integer attribute value(s).
377

Uwe Schulzweida's avatar
Uwe Schulzweida committed
378
@Description
379
The function @func{cdiInqAttInt} gets the values(s) of an integer attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
380 381 382

@EndFunction
*/
383
int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int *ip)
384
{
385
  return cdi_inq_att(CDI_DATATYPE_INT, cdiID, varID, name, (size_t)mlen * sizeof(int), ip);
386 387
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
/*
389
@Function  cdiInqAttFlt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390 391
@Title     Get the value(s) of a floating point attribute

392
@Prototype int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double *dp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
393
@Parameter
394
    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
395
    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
Deike Kleberg's avatar
Deike Kleberg committed
396 397 398
    @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
399 400

@Description
401
The function @func{cdiInqAttFlt} gets the values(s) of a floating point attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402 403 404

@EndFunction
*/
405
int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double *dp)
406
{
407
  return cdi_inq_att(CDI_DATATYPE_FLT, cdiID, varID, name, (size_t)mlen * sizeof(double), dp);
408 409
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
410
/*
411
@Function  cdiInqAttTxt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412 413
@Title     Get the value(s) of a text attribute

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

@Description
423
The function @func{cdiInqAttTxt} gets the values(s) of a text attribute.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424 425 426

@EndFunction
*/
427
int cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp)
428
{
429
  return cdi_inq_att(CDI_DATATYPE_TXT, cdiID, varID, name, (size_t)mlen * sizeof(char), tp);
430
}
431 432

enum {
433
  cdi_att_nints = 4,          /* namesz, exdtype, indtype, nelems */
434 435
};

436 437
static inline
int cdiAttTypeLookup(cdi_att_t *attp)
438
{
439
  int type;
Thomas Jahns's avatar
Thomas Jahns committed
440
  switch (attp->indtype)
441
  {
442 443
  case CDI_DATATYPE_FLT:
    type = CDI_DATATYPE_FLT64;
444
    break;
445 446
  case CDI_DATATYPE_INT:
  case CDI_DATATYPE_TXT:
447
    type = attp->indtype;
448 449
    break;
  default:
450
    xabort("Unknown datatype encountered in attribute %s: %d\n",
Thomas Jahns's avatar
Thomas Jahns committed
451
            attp->name, attp->indtype);
452
  }
453 454 455
  return type;
}

Thomas Jahns's avatar
Thomas Jahns committed
456

457
int cdi_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum)
Thomas Jahns's avatar
Thomas Jahns committed
458 459
{
  cdi_atts_t *attspa = get_attsp(a, varIDA),
460 461 462
             *attspb = get_attsp(b, varIDB);
  if (attspa == NULL && attspb == NULL) return 0;
  xassert(attnum >= 0 && attnum < (int)attspa->nelems && attnum < (int)attspb->nelems);
Thomas Jahns's avatar
Thomas Jahns committed
463
  cdi_att_t *attpa = attspa->value + attnum,
464
            *attpb = attspb->value + attnum;
Thomas Jahns's avatar
Thomas Jahns committed
465
  size_t len;
466
  if ((len = attpa->namesz) != attpb->namesz) return 1;
Thomas Jahns's avatar
Thomas Jahns committed
467 468 469 470 471 472 473
  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;
474

Thomas Jahns's avatar
Thomas Jahns committed
475 476 477 478
  return memcmp(attpa->xvalue, attpb->xvalue, attpa->xsz);
}


479 480
static
int cdiAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
481 482 483 484 485 486 487
{
  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]);
488 489
  int txsize = serializeGetSize(cdi_att_nints, CDI_DATATYPE_INT, context)
    + serializeGetSize((int)attp->namesz, CDI_DATATYPE_TXT, context);
490
  txsize += serializeGetSize((int)attp->nelems, cdiAttTypeLookup(attp), context);
491 492 493
  return txsize;
}

494

495
int cdiAttsGetSize(void *vp, int varID, void *context)
496
{
497
  vlist_t *p = (vlist_t*) vp;
498
  cdi_atts_t *attsp = get_attsp(p, varID);
499
  int txsize = serializeGetSize(1, CDI_DATATYPE_INT, context);
500 501
  size_t numAtts = attsp->nelems;
  for (size_t i = 0; i < numAtts; ++i)
502
    txsize += cdiAttGetSize(p, varID, (int)i, context);
503 504 505
  return txsize;
}

506
static
507 508
void cdiAttPack(vlist_t *vlistptr, int varID, int attnum,
                void *buf, int size, int *position, void *context)
509 510 511
{
  cdi_atts_t *attsp;
  cdi_att_t *attp;
512
  int tempbuf[cdi_att_nints];
513

Deike Kleberg's avatar
Deike Kleberg committed
514 515
  xassert(attsp = get_attsp(vlistptr, varID));
  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
516
  attp = &(attsp->value[attnum]);
517
  tempbuf[0] = (int)attp->namesz;
518 519
  tempbuf[1] = attp->exdtype;
  tempbuf[2] = attp->indtype;
520
  tempbuf[3] = (int)attp->nelems;
521 522
  serializePack(tempbuf, cdi_att_nints, CDI_DATATYPE_INT, buf, size, position, context);
  serializePack(attp->name, (int)attp->namesz, CDI_DATATYPE_TXT, buf, size, position, context);
523
  serializePack(attp->xvalue, (int)attp->nelems, cdiAttTypeLookup(attp),
524
                buf, size, position, context);
525 526
}

527 528

void cdiAttsPack(void *vp, int varID, void *buf, int size, int *position, void *context)
529
{
530
  vlist_t *p = (vlist_t*) vp;
531
  cdi_atts_t *attsp = get_attsp(p, varID);
532 533 534
  size_t numAtts = attsp->nelems;
  int numAttsI = (int)numAtts;
  xassert(numAtts <= INT_MAX);
535
  serializePack(&numAttsI, 1, CDI_DATATYPE_INT, buf, size, position, context);
536
  for (size_t i = 0; i < numAtts; ++i)
537
    cdiAttPack(p, varID, (int)i, buf, size, position, context);
538 539
}

540
static
541
void cdiAttUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context)
542
{
543
  int tempbuf[cdi_att_nints];
544

545
  serializeUnpack(buf, size, position,
546
                  tempbuf, cdi_att_nints, CDI_DATATYPE_INT, context);
547
  char *attName = (char *) Malloc((size_t)tempbuf[0] + 1);
548
  serializeUnpack(buf, size, position, attName, tempbuf[0], CDI_DATATYPE_TXT, context);
549
  attName[tempbuf[0]] = '\0';
550 551
  int attVDt;
  size_t elemSize;
552 553
  switch (tempbuf[2])
  {
554 555
  case CDI_DATATYPE_FLT:
    attVDt = CDI_DATATYPE_FLT64;
556 557
    elemSize = sizeof(double);
    break;
558 559
  case CDI_DATATYPE_INT:
    attVDt = CDI_DATATYPE_INT;
560 561
    elemSize = sizeof(int);
    break;
562 563
  case CDI_DATATYPE_TXT:
    attVDt = CDI_DATATYPE_TXT;
564 565 566
    elemSize = 1;
    break;
  default:
567 568
    xabort("Unknown datatype encountered in attribute %s: %d\n",
           attName, tempbuf[2]);
569
  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
  void *attData = Malloc(elemSize * (size_t)tempbuf[3]);
571
  serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
572 573
  cdi_def_att(tempbuf[2], tempbuf[1], cdiID, varID, attName,
              (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
574 575
  Free(attName);
  Free(attData);
576 577
}

578 579

void cdiAttsUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context)
580
{
581
  int numAtts;
582
  serializeUnpack(buf, size, position, &numAtts, 1, CDI_DATATYPE_INT, context);
583
  for ( int i = 0; i < numAtts; ++i )
584
    cdiAttUnpack(cdiID, varID, buf, size, position, context);
585 586
}

587 588 589 590 591 592 593 594 595
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */