cdi_key.c 16.6 KB
Newer Older
1 2
#include "cdi.h"
#include "cdi_int.h"
3
#include "zaxis.h"
4
#include "grid.h"
5
#include "vlist.h"
6
#include "resource_unpack.h"
7 8 9


static
10
cdi_keys_t *vlist_get_keysp(vlist_t *vlistptr, int varID)
11
{
12 13
  if      (varID == CDI_GLOBAL) return &vlistptr->keys;
  else if (varID >= 0 && varID < vlistptr->nvars) return &(vlistptr->vars[varID].keys);
14

15
  return NULL;
16 17
}

18
static
19
cdi_keys_t *grid_get_keysp(grid_t *gridptr, int varID)
20
{
21 22 23
  if      (varID == CDI_GLOBAL) return &gridptr->keys;
  else if (varID == CDI_XAXIS)  return &gridptr->x.keys;
  else if (varID == CDI_YAXIS)  return &gridptr->y.keys;
24

25 26
  return NULL;
}
27

28 29 30 31 32 33
static
cdi_keys_t *zaxis_get_keysp(zaxis_t *zaxisptr, int varID)
{
  if (varID == CDI_GLOBAL) return &zaxisptr->keys;

  return NULL;
34 35
}

36 37 38 39 40 41 42 43 44 45 46
static
cdi_key_t *new_key(cdi_keys_t *keysp, int key)
{
  xassert(keysp != NULL);

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

  cdi_key_t *keyp = &(keysp->value[keysp->nelems]);
  keysp->nelems++;

  keyp->key = key;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
47 48 49
  keyp->length = 0;
  keyp->type = 0;
  keyp->v.s = NULL;
50 51 52 53

  return keyp;
}

54

55 56 57 58 59 60 61 62
cdi_key_t *find_key(cdi_keys_t *keysp, int key)
{
  xassert(keysp != NULL);

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

  for ( size_t keyid = 0; keyid < keysp->nelems; keyid++ )
    {
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
      cdi_key_t *keyp =  &(keysp->value[keyid]);
      if ( keyp->key == key ) return keyp; // Normal return
    }

  return NULL;
}

static
const cdi_key_t *find_key_const(const cdi_keys_t *keysp, int key)
{
  xassert(keysp != NULL);

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

  for ( size_t keyid = 0; keyid < keysp->nelems; keyid++ )
    {
      const cdi_key_t *keyp =  &(keysp->value[keyid]);
      if ( keyp->key == key ) return keyp; // Normal return
81 82 83 84 85 86 87 88
    }

  return NULL;
}

static
cdi_keys_t *cdi_get_keysp(int objID, int varID)
{
89 90 91
  if      ( reshGetTxCode(objID) == GRID )  return grid_get_keysp(grid_to_pointer(objID), varID);
  else if ( reshGetTxCode(objID) == ZAXIS ) return zaxis_get_keysp(zaxis_to_pointer(objID), varID);
  else if ( reshGetTxCode(objID) == VLIST ) return vlist_get_keysp(vlist_to_pointer(objID), varID);
92

93
  return NULL;
94 95
}

96

97
int cdi_key_compare(cdi_keys_t *keyspa, cdi_keys_t *keyspb, int keynum)
98
{
99
  xassert(keynum >= 0 && keynum < (int)keyspa->nelems && keynum < (int)keyspb->nelems);
100
  cdi_key_t *keypa = keyspa->value + keynum,
101
            *keypb = keyspb->value + keynum;
102

Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
  if (keypa->key != keypb->key) return 1;
104

Uwe Schulzweida's avatar
Uwe Schulzweida committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
  if (keypa->type != keypb->type) return 1;

  if (keypa->type == KEY_BYTES)
    {
      if (keypa->length != keypb->length) return 1;
      return memcmp(keypa->v.s, keypb->v.s, keypa->length);
    }
  else if (keypa->type == KEY_FLOAT)
    {
      if (IS_NOT_EQUAL(keypa->v.d, keypb->v.d)) return 1;
    }
  else if (keypa->type == KEY_INT)
    {
      if (keypa->v.i != keypb->v.i) return 1;
    }
120 121 122 123

  return 0;
}

124

125
void cdiDeleteVarKeys(cdi_keys_t *keysp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
126 127 128 129
{
  for ( int keyid = 0; keyid < (int)keysp->nelems; keyid++ )
    {
      cdi_key_t *keyp = &(keysp->value[keyid]);
130
      if ( keyp->length )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131 132 133 134 135 136 137 138
        {
          free(keyp->v.s);
          keyp->v.s = NULL;
          keyp->length = 0;
        }
    }

  keysp->nelems = 0;
139 140 141
}


142
void cdiDeleteKeys(int cdiID, int varID)
143 144 145 146 147
{
  cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  cdiDeleteVarKeys(keysp);
148
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
149

150 151 152 153 154 155 156 157 158 159

void cdiPrintVarKeys(cdi_keys_t *keysp)
{
  for ( int keyid = 0; keyid < (int)keysp->nelems; keyid++ )
    {
      cdi_key_t *keyp = &(keysp->value[keyid]);
      if (keyp->type == KEY_BYTES)
        {
          printf("%d key %d length %d value %s\n", keyid+1, keyp->key, keyp->length,  keyp->v.s);
        }
160 161 162 163
      else if (keyp->type == KEY_FLOAT)
        {
          printf("%d key %d value %g\n", keyid+1, keyp->key, keyp->v.d);
        }
164 165 166 167 168 169 170 171 172 173 174 175 176 177
      else if (keyp->type == KEY_INT)
        {
          printf("%d key %d value %d\n", keyid+1, keyp->key, keyp->v.i);
        }
    }
}


void cdiPrintKeys(int cdiID, int varID)
{
  cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  cdiPrintVarKeys(keysp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178 179
}

180 181 182 183 184
//  cdiInqKeyLen: Get the length of the string representation of the key
int cdiInqKeyLen(int cdiID, int varID, int key, int *length)
{
  int status = -1;

185
  const cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
186 187
  xassert(keysp != NULL);

188
  const cdi_key_t *keyp = find_key_const(keysp, key);
189 190 191 192 193 194 195 196 197 198
  if ( keyp != NULL )
    {
      *length = keyp->length;
      if ( *length == 0 ) *length = 1;
      status = CDI_NOERR;
    }

  return status;
}

199
static
200
void cdi_define_key(const cdi_key_t *keyp, cdi_keys_t *keysp)
201
{
202
  if      ( keyp->type == KEY_INT )
203
    cdiDefVarKeyInt(keysp, keyp->key, keyp->v.i);
204
  else if ( keyp->type == KEY_FLOAT )
205
    cdiDefVarKeyFloat(keysp, keyp->key, keyp->v.d);
206
  else if ( keyp->type == KEY_BYTES )
207
    cdiDefVarKeyBytes(keysp, keyp->key, keyp->v.s, keyp->length);
208 209
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
210

211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
int cdiDeleteKey(int cdiID, int varID, int key)
{
  int status = -1;

  cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  cdi_key_t *keyp = find_key(keysp, key);
  if ( keyp != NULL ) // key in use
    {
      if ( keyp->length )
        {
          free(keyp->v.s);
          keyp->v.s = NULL;
          keyp->length = 0;
        }
    }

  return status;
}


233
void cdiCopyVarKeys(const cdi_keys_t *keysp1, cdi_keys_t *keysp2)
234
{
235
  for ( size_t keyid = 0; keyid < keysp1->nelems; keyid++ )
236
    {
237 238
      const cdi_key_t *keyp = &(keysp1->value[keyid]);
      cdi_define_key(keyp, keysp2);
239 240 241
    }
}

242 243

int cdiCopyKeys(int cdiID1, int varID1, int cdiID2, int varID2)
244 245 246
{
  int status = CDI_NOERR;

247 248
  cdi_keys_t *keysp1 = cdi_get_keysp(cdiID1, varID1);
  xassert(keysp1 != NULL);
249

250 251 252 253
  cdi_keys_t *keysp2 = cdi_get_keysp(cdiID2, varID2);
  xassert(keysp2 != NULL);

  cdiCopyVarKeys(keysp1, keysp2);
254 255 256 257 258

  return status;
}


259
int cdiCopyVarKey(const cdi_keys_t *keysp1, int key, cdi_keys_t *keysp2)
260 261 262
{
  int status = CDI_NOERR;

263
  const cdi_key_t *keyp = find_key_const(keysp1, key);
264 265 266 267 268 269 270 271 272 273
  if (keyp == NULL) return -1;

  cdi_define_key(keyp, keysp2);

  return status;
}


int cdiCopyKey(int cdiID1, int varID1, int key, int cdiID2)
{
274 275
  cdi_keys_t *keysp1 = cdi_get_keysp(cdiID1, varID1);
  xassert(keysp1 != NULL);
276

277 278 279
  cdi_keys_t *keysp2 = cdi_get_keysp(cdiID2, varID1);
  xassert(keysp2 != NULL);

280
  return cdiCopyVarKey(keysp1, key, keysp2);
281 282 283
}


284 285
void cdiDefVarKeyInt(cdi_keys_t *keysp, int key, int value)
{
286 287 288 289 290
  cdi_key_t *keyp = find_key(keysp, key);
  if ( keyp == NULL ) keyp = new_key(keysp, key);

  if ( keyp != NULL )
    {
291
      //if ( keyp->v.i != value )
292
        {
293
          keyp->type = KEY_INT;
294 295 296
          keyp->v.i = value;
        }
    }
297 298
}

299 300
/*
@Function  cdiDefKeyInt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
301
@Title     Define an integer value from a key
302 303 304

@Prototype int cdiDefKeyInt(int cdiID, int varID, int key, int value)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
306
    @Item  varID    Variable identifier or CDI_GLOBAL.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
307 308
    @Item  key      The key to be searched.
    @Item  value    An integer where the data will be read.
309 310

@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
The function @func{cdiDefKeyInt} defines an integer value from a key.
312 313 314 315 316 317

@Result
@func{cdiDefKeyInt} returns CDI_NOERR if OK.

@EndFunction
*/
318 319 320 321 322 323 324 325
int cdiDefKeyInt(int cdiID, int varID, int key, int value)
{
  int status = CDI_NOERR;

  cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  cdiDefVarKeyInt(keysp, key, value);
326 327 328 329

  return status;
}

330 331
/*
@Function  cdiInqKeyInt
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332
@Title     Get an integer value from a key
333 334 335

@Prototype int cdiInqKeyInt(int cdiID, int varID, int key, int *value)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
337
    @Item  varID    Variable identifier or CDI_GLOBAL.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
    @Item  key      The key to be searched..
339 340 341
    @Item  value    The address of an integer where the data will be retrieved.

@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
The function @func{cdiInqKeyInt} gets an integer value from a key.
343 344 345 346 347 348

@Result
@func{cdiInqKeyInt} returns CDI_NOERR if key is available.

@EndFunction
*/
349
int cdiInqKeyInt(int cdiID, int varID, int key, int *value)
350
{
351 352
  int status = -1;

353
  // if ( varID != CDI_GLOBAL ) status = cdiInqKeyInt(cdiID, CDI_GLOBAL, key, value);
354

355
  const cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
356 357
  xassert(keysp != NULL);

358
  const cdi_key_t *keyp = find_key_const(keysp, key);
359 360
  if ( keyp != NULL ) // key in use
    {
361
      if ( keyp->type == KEY_INT )
362
	{
363 364
          *value = keyp->v.i;
          status = CDI_NOERR;
365 366 367 368 369 370
	}
    }

  return status;
}

371

372 373 374 375 376 377 378 379 380 381 382
int cdiInqVarKeyInt(const cdi_keys_t *keysp, int key)
{
  int value = 0;

  const cdi_key_t *keyp = find_key_const(keysp, key);
  if (keyp && keyp->type == KEY_INT ) value = keyp->v.i;

  return value;
}


383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
void cdiDefVarKeyFloat(cdi_keys_t *keysp, int key, double value)
{
  cdi_key_t *keyp = find_key(keysp, key);
  if ( keyp == NULL ) keyp = new_key(keysp, key);

  if ( keyp != NULL )
    {
      //if ( keyp->v.i != value )
        {
          keyp->type = KEY_INT;
          keyp->v.d = value;
        }
    }
}

/*
@Function  cdiDefKeyFloat
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
@Title     Define a floating point value from a key
401 402 403

@Prototype int cdiDefKeyFloat(int cdiID, int varID, int key, double value)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
    @Item  varID    Variable identifier or CDI_GLOBAL.
    @Item  key      The key to be searched
    @Item  value    A double where the data will be read

@Description
The function @func{cdiDefKeyFloat} defines a CDI floating point value from a key.

@Result
@func{cdiDefKeyFloat} returns CDI_NOERR if OK.

@EndFunction
*/
int cdiDefKeyFloat(int cdiID, int varID, int key, double value)
{
  int status = CDI_NOERR;

  cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  cdiDefVarKeyFloat(keysp, key, value);

  return status;
}

/*
@Function  cdiInqKeyFloat
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
@Title     Get a floating point value from a key
432 433 434

@Prototype int cdiInqKeyFloat(int cdiID, int varID, int key, double *value)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
435
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
436 437 438 439 440
    @Item  varID    Variable identifier or CDI_GLOBAL.
    @Item  key      The key to be searched.
    @Item  value    The address of a double where the data will be retrieved.

@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
The function @func{cdiInqKeyFloat} gets a floating point value from a key.
442 443 444 445 446 447 448 449 450 451 452 453

@Result
@func{cdiInqKeyFloat} returns CDI_NOERR if key is available.

@EndFunction
*/
int cdiInqKeyFloat(int cdiID, int varID, int key, double *value)
{
  int status = -1;

  // if ( varID != CDI_GLOBAL ) status = cdiInqKeyFloat(cdiID, CDI_GLOBAL, key, value);

454
  const cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
455 456
  xassert(keysp != NULL);

457
  const cdi_key_t *keyp = find_key_const(keysp, key);
458 459 460 461 462 463 464 465 466 467 468 469 470
  if ( keyp != NULL ) // key in use
    {
      if ( keyp->type == KEY_FLOAT )
	{
          *value = keyp->v.d;
          status = CDI_NOERR;
	}
    }

  return status;
}


471 472
void cdiDefVarKeyBytes(cdi_keys_t *keysp, int key, const unsigned char *bytes, int length)
{
473 474 475 476 477
  cdi_key_t *keyp = find_key(keysp, key);
  if ( keyp == NULL ) keyp = new_key(keysp, key);

  if ( keyp != NULL )
    {
478 479 480 481 482 483 484
      if ( keyp->length != 0 && keyp->length != length )
        {
          free(keyp->v.s);
          keyp->length = 0;
        }
      if ( keyp->length == 0 )
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
485
          keyp->v.s = (unsigned char *) malloc((size_t) length);
486 487 488
          keyp->length = length;
        }

489 490 491
      memcpy(keyp->v.s, bytes, length);
      keyp->type = KEY_BYTES;
    }
492 493
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
/*
@Function  cdiDefKeyBytes
@Title     Define a byte array from a key

@Prototype int cdiDefKeyBytes(int cdiID, int varID, int key, const unsigned char *bytes, int length)
@Parameter
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
    @Item  varID    Variable identifier or CDI_GLOBAL.
    @Item  key      The key to be searched.
    @Item  bytes    The address of a byte array where the data will be read.
    @Item  length   Length of the byte array

@Description
The function @func{cdiDefKeyBytes} defines a byte array from a key.

@Result
@func{cdiDefKeyBytes} returns CDI_NOERR if OK.

@EndFunction
*/
514 515 516 517 518 519 520 521
int cdiDefKeyBytes(int cdiID, int varID, int key, const unsigned char *bytes, int length)
{
  int status = CDI_NOERR;

  cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  cdiDefVarKeyBytes(keysp, key, bytes, length);
522 523 524 525

  return status;
}

526
int cdiInqVarKeyBytes(const cdi_keys_t *keysp, int key, unsigned char *bytes, int *length)
527 528
{
  int status = -1;
529

530
  const cdi_key_t *keyp = find_key_const(keysp, key);
531
  if ( keyp != NULL ) // key in use
532
    {
533 534 535 536 537 538
      if ( keyp->type == KEY_BYTES )
	{
          if ( keyp->length < *length ) *length = keyp->length;
          memcpy(bytes, keyp->v.s, *length);
          status = CDI_NOERR;
	}
539 540 541 542 543
    }

  return status;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
//  cdiInqKeyBytes: Get a byte array from a key
/*
@Function  cdiInqKeyBytes
@Title     Get a byte array from a key

@Prototype int cdiInqKeyBytes(int cdiID, int varID, int key, unsigned char *bytes, int *length)
@Parameter
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
    @Item  varID    Variable identifier or CDI_GLOBAL.
    @Item  key      The key to be searched.
    @Item  bytes    The address of a byte array where the data will be retrieved.
                    The caller must allocate space for the returned byte array.
    @Item  length   The allocated length of the byte array on input.
@Description
The function @func{cdiInqKeyBytes} gets a byte array from a key.

@Result
@func{cdiInqKeyBytes} returns CDI_NOERR if key is available.

@EndFunction
*/
565 566 567 568 569 570 571 572 573 574 575 576 577
int cdiInqKeyBytes(int cdiID, int varID, int key, unsigned char *bytes, int *length)
{
  xassert(bytes != NULL);
  xassert(length != NULL);

  // if ( varID != CDI_GLOBAL ) status = cdiInqKeyBytes(cdiID, CDI_GLOBAL, key, bytes, length);

  const cdi_keys_t *keysp = cdi_get_keysp(cdiID, varID);
  xassert(keysp != NULL);

  return cdiInqVarKeyBytes(keysp, key, bytes, length);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
578 579
/*
@Function  cdiDefKeyString
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
@Title     Define a string from a key
Uwe Schulzweida's avatar
Uwe Schulzweida committed
581 582 583

@Prototype int cdiDefKeyString(int cdiID, int varID, int key, const char *string)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585 586 587 588 589
    @Item  varID    Variable identifier or CDI_GLOBAL.
    @Item  key      The key to be searched.
    @Item  string   The address of a string where the data will be read.

@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590
The function @func{cdiDefKeyString} defines a text string from a key.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591 592 593 594

@Result
@func{cdiDefKeyString} returns CDI_NOERR if OK.

Uwe Schulzweida's avatar
Uwe Schulzweida committed
595 596 597 598 599 600 601 602 603 604 605 606 607 608
@Example
Here is an example using @func{cdiDefKeyString} to define the name of a variable:

@Source
#include "cdi.h"
   ...
int vlistID, varID, status;
   ...
vlistID = vlistCreate();
varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
   ...
status = cdiDefKeyString(vlistID, varID, CDI_KEY_NAME, "temperature");
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
609 610
@EndFunction
*/
611 612 613 614
int cdiDefKeyString(int cdiID, int varID, int key, const char *string)
{
  xassert(string != NULL);

615
  int length = strlen(string) + 1;
616 617 618 619 620
  int status = cdiDefKeyBytes(cdiID, varID, key, (const unsigned char *) string, length);

  return status;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
621 622
/*
@Function  cdiInqKeyString
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623
@Title     Get a string from a key
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624 625 626

@Prototype int cdiInqKeyString(int cdiID, int varID, int key, char *string, int *length)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
    @Item  cdiID    CDI object ID (vlistID, gridID, zaxisID).
Uwe Schulzweida's avatar
Uwe Schulzweida committed
628 629 630 631 632 633
    @Item  varID    Variable identifier or CDI_GLOBAL.
    @Item  key      The key to be searched.
    @Item  string   The address of a string where the data will be retrieved.
                    The caller must allocate space for the returned string.
    @Item  length   The allocated length of the string on input.
@Description
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
The function @func{cdiInqKeyString} gets a text string from a key.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635 636 637 638

@Result
@func{cdiInqKeyString} returns CDI_NOERR if key is available.

Uwe Schulzweida's avatar
Uwe Schulzweida committed
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
@Example
Here is an example using @func{cdiInqKeyString} to get the name of the first variable:

@Source
#include "cdi.h"
   ...
#define STRLEN 256
   ...
int streamID, vlistID, varID, status;
int length = STRLEN;
char name[STRLEN];
   ...
streamID = streamOpenRead(...);
vlistID = streamInqVlist(streamID);
   ...
varID = 0;
status = cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, &length);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658 659
@EndFunction
*/
660 661 662 663 664
int cdiInqKeyString(int cdiID, int varID, int key, char *string, int *length)
{
  xassert(string != NULL);
  xassert(length != NULL);

665 666
  int maxlength = *length;
  if (maxlength > 0) string[0] = '\0';
667 668

  int status = cdiInqKeyBytes(cdiID, varID, key, (unsigned char *) string, length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
  if (status != CDI_NOERR) *length = 0;
670
  else string[maxlength-1] = '\0';
671

672 673 674
  return status;
}

675
const char *cdiInqVarKeyStringPtr(const cdi_keys_t *keysp, int key)
676
{
677
  const cdi_key_t *keyp = find_key_const(keysp, key);
678 679 680 681 682 683 684 685
  if ( keyp != NULL ) // key in use
    {
      if ( keyp->type == KEY_BYTES ) return (const char *)keyp->v.s;
    }

  return NULL;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
686 687 688 689 690 691 692 693
void cdiInitKeys(cdi_keys_t *keysp)
{
  keysp->nalloc = MAX_KEYS;
  keysp->nelems = 0;
  for ( int i = 0; i < MAX_KEYS; ++i )
    keysp->value[i].length = 0;
}

694 695 696 697 698 699 700 701 702
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */