Coverage Report

Created: 2026-07-16 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/netcdf-c/build/libsrc/attr.c
Line
Count
Source
1
/* Do not edit this file. It is produced from the corresponding .m4 source */
2
/*
3
 *  Copyright 2018, University Corporation for Atmospheric Research
4
 *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
5
 */
6
7
#if HAVE_CONFIG_H
8
#include <config.h>
9
#endif
10
11
#include "nc3internal.h"
12
#include "ncdispatch.h"
13
#include "nc3dispatch.h"
14
#include <stdlib.h>
15
#include <string.h>
16
#include <assert.h>
17
#include "ncx.h"
18
#include "fbits.h"
19
#include "rnd.h"
20
#include "ncutf8.h"
21
22
/*
23
 * Free attr
24
 * Formerly
25
NC_free_attr()
26
 */
27
void
28
free_NC_attr(NC_attr *attrp)
29
16.8k
{
30
31
16.8k
  if(attrp == NULL)
32
0
    return;
33
16.8k
  free_NC_string(attrp->name);
34
16.8k
  free(attrp);
35
16.8k
}
36
37
38
/*
39
 * How much space will 'nelems' of 'type' take in
40
 *  external representation (as the values of an attribute)?
41
 */
42
static size_t
43
ncx_len_NC_attrV(nc_type type, size_t nelems)
44
16.8k
{
45
16.8k
  switch(type) {
46
609
  case NC_BYTE:
47
609
  case NC_CHAR:
48
609
    return ncx_len_char(nelems);
49
6
  case NC_SHORT:
50
6
    return ncx_len_short(nelems);
51
6
  case NC_INT:
52
6
    return ncx_len_int(nelems);
53
1.23k
  case NC_FLOAT:
54
1.23k
    return ncx_len_float(nelems);
55
0
  case NC_DOUBLE:
56
0
    return ncx_len_double(nelems);
57
0
  case NC_UBYTE:
58
0
    return ncx_len_ubyte(nelems);
59
14.5k
  case NC_USHORT:
60
14.5k
    return ncx_len_ushort(nelems);
61
349
  case NC_UINT:
62
349
    return ncx_len_uint(nelems);
63
2
  case NC_INT64:
64
2
    return ncx_len_int64(nelems);
65
105
  case NC_UINT64:
66
105
    return ncx_len_uint64(nelems);
67
0
  default:
68
0
          assert("ncx_len_NC_attr bad type" == 0);
69
16.8k
  }
70
0
  return 0;
71
16.8k
}
72
73
74
NC_attr *
75
new_x_NC_attr(
76
  NC_string *strp,
77
  nc_type type,
78
  size_t nelems)
79
16.8k
{
80
16.8k
  NC_attr *attrp;
81
16.8k
  const size_t xsz = ncx_len_NC_attrV(type, nelems);
82
16.8k
  size_t sz = M_RNDUP(sizeof(NC_attr));
83
84
16.8k
  assert(!(xsz == 0 && nelems != 0));
85
86
16.8k
  if(sz > SIZE_MAX -xsz)
87
0
    return NULL;
88
89
16.8k
  sz += xsz;
90
91
16.8k
  attrp = (NC_attr *) malloc(sz);
92
16.8k
  if(attrp == NULL )
93
0
    return NULL;
94
95
16.8k
  attrp->xsz = xsz;
96
97
16.8k
  attrp->name = strp;
98
16.8k
  attrp->type = type;
99
16.8k
  attrp->nelems = nelems;
100
16.8k
  if(xsz != 0)
101
963
    attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr));
102
15.8k
  else
103
15.8k
    attrp->xvalue = NULL;
104
105
16.8k
  return(attrp);
106
16.8k
}
107
108
109
/*
110
 * Formerly
111
NC_new_attr(name,type,count,value)
112
 */
113
static NC_attr *
114
new_NC_attr(
115
  const char *uname,
116
  nc_type type,
117
  size_t nelems)
118
0
{
119
0
  NC_string *strp = NULL;
120
0
  NC_attr *attrp = NULL;
121
0
  char *name = NULL;
122
0
  int stat = NC_NOERR;
123
124
0
  stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
125
0
  if(stat != NC_NOERR)
126
0
      goto done;
127
0
  assert(name != NULL && *name != 0);
128
129
0
  strp = new_NC_string(strlen(name), name);
130
0
  if(strp == NULL)
131
0
    goto done;
132
133
0
  attrp = new_x_NC_attr(strp, type, nelems);
134
0
  if(attrp == NULL)
135
0
  {
136
0
    free_NC_string(strp);
137
0
    goto done;
138
0
  }
139
0
done:
140
0
  if(name) free(name);
141
0
  return (attrp);
142
0
}
143
144
145
static NC_attr *
146
dup_NC_attr(const NC_attr *rattrp)
147
0
{
148
0
  NC_attr *attrp = new_NC_attr(rattrp->name->cp,
149
0
     rattrp->type, rattrp->nelems);
150
0
  if(attrp == NULL)
151
0
    return NULL;
152
0
        if(attrp->xvalue != NULL && rattrp->xvalue != NULL)
153
0
            (void) memcpy(attrp->xvalue, rattrp->xvalue, rattrp->xsz);
154
0
  return attrp;
155
0
}
156
157
/* attrarray */
158
159
/*
160
 * Free the stuff "in" (referred to by) an NC_attrarray.
161
 * Leaves the array itself allocated.
162
 */
163
void
164
free_NC_attrarrayV0(NC_attrarray *ncap)
165
32
{
166
32
  assert(ncap != NULL);
167
168
32
  if(ncap->nelems == 0)
169
7
    return;
170
171
32
  assert(ncap->value != NULL);
172
173
25
  {
174
25
    NC_attr **app = ncap->value;
175
25
    NC_attr *const *const end = &app[ncap->nelems];
176
16.8k
    for( /*NADA*/; app < end; app++)
177
16.8k
    {
178
16.8k
      free_NC_attr(*app);
179
16.8k
      *app = NULL;
180
16.8k
    }
181
25
  }
182
25
  ncap->nelems = 0;
183
25
}
184
185
186
/*
187
 * Free NC_attrarray values.
188
 * formerly
189
NC_free_array()
190
 */
191
void
192
free_NC_attrarrayV(NC_attrarray *ncap)
193
102k
{
194
102k
  assert(ncap != NULL);
195
196
102k
  if(ncap->nalloc == 0)
197
102k
    return;
198
199
102k
  assert(ncap->value != NULL);
200
201
32
  free_NC_attrarrayV0(ncap);
202
203
32
  free(ncap->value);
204
32
  ncap->value = NULL;
205
32
  ncap->nalloc = 0;
206
32
}
207
208
209
int
210
dup_NC_attrarrayV(NC_attrarray *ncap, const NC_attrarray *ref)
211
0
{
212
0
  int status = NC_NOERR;
213
214
0
  assert(ref != NULL);
215
0
  assert(ncap != NULL);
216
217
0
  if(ref->nelems != 0)
218
0
  {
219
0
    const size_t sz = ref->nelems * sizeof(NC_attr *);
220
0
    ncap->value = (NC_attr **) malloc(sz);
221
0
    if(ncap->value == NULL)
222
0
      return NC_ENOMEM;
223
224
0
    (void) memset(ncap->value, 0, sz);
225
0
    ncap->nalloc = ref->nelems;
226
0
  }
227
228
0
  ncap->nelems = 0;
229
0
  {
230
0
    NC_attr **app = ncap->value;
231
0
    if (app)
232
0
    {
233
0
      const NC_attr **drpp = (const NC_attr **)ref->value;
234
0
      NC_attr *const *const end = &app[ref->nelems];
235
0
      for( /*NADA*/; app < end; drpp++, app++, ncap->nelems++)
236
0
      {
237
0
        *app = dup_NC_attr(*drpp);
238
0
        if(*app == NULL)
239
0
        {
240
0
          status = NC_ENOMEM;
241
0
          break;
242
0
        }
243
0
      }
244
0
    }
245
0
  }
246
247
0
  if(status != NC_NOERR)
248
0
  {
249
0
    free_NC_attrarrayV(ncap);
250
0
    return status;
251
0
  }
252
253
0
  assert(ncap->nelems == ref->nelems);
254
255
0
  return NC_NOERR;
256
0
}
257
258
259
/*
260
 * Add a new handle on the end of an array of handles
261
 * Formerly
262
NC_incr_array(array, tail)
263
 */
264
static int
265
incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp)
266
0
{
267
0
  NC_attr **vp;
268
269
0
  assert(ncap != NULL);
270
271
0
  if(ncap->nalloc == 0)
272
0
  {
273
0
    assert(ncap->nelems == 0);
274
0
    vp = (NC_attr **) malloc(NC_ARRAY_GROWBY * sizeof(NC_attr *));
275
0
    if(vp == NULL)
276
0
      return NC_ENOMEM;
277
278
0
    ncap->value = vp;
279
0
    ncap->nalloc = NC_ARRAY_GROWBY;
280
0
  }
281
0
  else if(ncap->nelems +1 > ncap->nalloc)
282
0
  {
283
0
    vp = (NC_attr **) realloc(ncap->value,
284
0
      (ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_attr *));
285
0
    if(vp == NULL)
286
0
      return NC_ENOMEM;
287
288
0
    ncap->value = vp;
289
0
    ncap->nalloc += NC_ARRAY_GROWBY;
290
0
  }
291
292
0
  if(newelemp != NULL)
293
0
  {
294
0
    ncap->value[ncap->nelems] = newelemp;
295
0
    ncap->nelems++;
296
0
  }
297
0
  return NC_NOERR;
298
0
}
299
300
301
NC_attr *
302
elem_NC_attrarray(const NC_attrarray *ncap, size_t elem)
303
0
{
304
0
  assert(ncap != NULL);
305
  /* cast needed for braindead systems with signed size_t */
306
0
  if(ncap->nelems == 0 || (unsigned long) elem >= ncap->nelems)
307
0
    return NULL;
308
309
0
  assert(ncap->value != NULL);
310
311
0
  return ncap->value[elem];
312
0
}
313
314
/* End attarray per se */
315
316
/*
317
 * Given ncp and varid, return ptr to array of attributes
318
 *  else NULL on error
319
 */
320
static NC_attrarray *
321
NC_attrarray0(NC3_INFO* ncp, int varid)
322
0
{
323
0
  NC_attrarray *ap;
324
325
0
  if(varid == NC_GLOBAL) /* Global attribute, attach to cdf */
326
0
  {
327
0
    ap = &ncp->attrs;
328
0
  }
329
0
  else if(varid >= 0 && (size_t) varid < ncp->vars.nelems)
330
0
  {
331
0
    NC_var **vpp;
332
0
    vpp = (NC_var **)ncp->vars.value;
333
0
    vpp += varid;
334
0
    ap = &(*vpp)->attrs;
335
0
  } else {
336
0
    ap = NULL;
337
0
  }
338
0
  return(ap);
339
0
}
340
341
342
/*
343
 * Step thru NC_ATTRIBUTE array, seeking match on name.
344
 *  return match or NULL if Not Found or out of memory.
345
 */
346
NC_attr **
347
NC_findattr(const NC_attrarray *ncap, const char *uname)
348
0
{
349
0
  NC_attr **attrpp = NULL;
350
0
  size_t attrid;
351
0
  size_t slen;
352
0
  char *name = NULL;
353
0
  int stat = NC_NOERR;
354
355
0
  assert(ncap != NULL);
356
357
0
  if(ncap->nelems == 0)
358
0
      goto done;
359
360
  /* normalized version of uname */
361
0
  stat = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
362
0
  if(stat != NC_NOERR)
363
0
      goto done; /* TODO: need better way to indicate no memory */
364
0
  slen = strlen(name);
365
366
0
  attrpp = (NC_attr **) ncap->value;
367
0
  for(attrid = 0; attrid < ncap->nelems; attrid++, attrpp++)
368
0
  {
369
0
    if(strlen((*attrpp)->name->cp) == slen &&
370
0
      strncmp((*attrpp)->name->cp, name, slen) == 0)
371
0
            goto done;
372
0
  }
373
0
  attrpp = NULL; /* not found */
374
0
done:
375
0
        if(name) free(name);
376
0
        return (attrpp); /* Normal return */
377
0
}
378
379
380
/*
381
 * Look up by ncid, varid and name, return NULL if not found
382
 */
383
static int
384
NC_lookupattr(int ncid,
385
  int varid,
386
  const char *name, /* attribute name */
387
  NC_attr **attrpp) /* modified on return */
388
0
{
389
0
  int status;
390
0
  NC* nc;
391
0
  NC3_INFO *ncp;
392
0
  NC_attrarray *ncap;
393
0
  NC_attr **tmp;
394
395
0
  status = NC_check_id(ncid, &nc);
396
0
  if(status != NC_NOERR)
397
0
    return status;
398
0
  ncp = NC3_DATA(nc);
399
400
0
  ncap = NC_attrarray0(ncp, varid);
401
0
  if(ncap == NULL)
402
0
    return NC_ENOTVAR;
403
404
0
  if(name == NULL)
405
0
    return NC_EBADNAME;
406
407
0
  tmp = NC_findattr(ncap, name);
408
0
  if(tmp == NULL)
409
0
    return NC_ENOTATT;
410
411
0
  if(attrpp != NULL)
412
0
    *attrpp = *tmp;
413
414
0
  return NC_NOERR;
415
0
}
416
417
/* Public */
418
419
int
420
NC3_inq_attname(int ncid, int varid, int attnum, char *name)
421
0
{
422
0
  int status;
423
0
  NC* nc;
424
0
  NC3_INFO *ncp;
425
0
  NC_attrarray *ncap;
426
0
  NC_attr *attrp;
427
428
0
  status = NC_check_id(ncid, &nc);
429
0
  if(status != NC_NOERR)
430
0
    return status;
431
0
  ncp = NC3_DATA(nc);
432
433
0
  ncap = NC_attrarray0(ncp, varid);
434
0
  if(ncap == NULL)
435
0
    return NC_ENOTVAR;
436
437
0
  attrp = elem_NC_attrarray(ncap, (size_t)attnum);
438
0
  if(attrp == NULL)
439
0
    return NC_ENOTATT;
440
441
0
    {
442
0
    size_t copy_len = attrp->name->nchars < NC_MAX_NAME
443
0
                      ? attrp->name->nchars : NC_MAX_NAME;
444
0
    (void) strncpy(name, attrp->name->cp, copy_len);
445
0
    name[copy_len] = 0;
446
0
    }
447
448
0
  return NC_NOERR;
449
0
}
450
451
452
int
453
NC3_inq_attid(int ncid, int varid, const char *name, int *attnump)
454
0
{
455
0
  int status;
456
0
  NC *nc;
457
0
  NC3_INFO* ncp;
458
0
  NC_attrarray *ncap;
459
0
  NC_attr **attrpp;
460
461
0
  status = NC_check_id(ncid, &nc);
462
0
  if(status != NC_NOERR)
463
0
    return status;
464
0
  ncp = NC3_DATA(nc);
465
466
0
  ncap = NC_attrarray0(ncp, varid);
467
0
  if(ncap == NULL)
468
0
    return NC_ENOTVAR;
469
470
471
0
  attrpp = NC_findattr(ncap, name);
472
0
  if(attrpp == NULL)
473
0
    return NC_ENOTATT;
474
475
0
  if(attnump != NULL)
476
0
    *attnump = (int)(attrpp - ncap->value);
477
478
0
  return NC_NOERR;
479
0
}
480
481
int
482
NC3_inq_att(int ncid,
483
  int varid,
484
  const char *name, /* input, attribute name */
485
  nc_type *datatypep,
486
  size_t *lenp)
487
0
{
488
0
  int status;
489
0
  NC_attr *attrp;
490
491
0
  status = NC_lookupattr(ncid, varid, name, &attrp);
492
0
  if(status != NC_NOERR)
493
0
    return status;
494
495
0
  if(datatypep != NULL)
496
0
    *datatypep = attrp->type;
497
0
  if(lenp != NULL)
498
0
    *lenp = attrp->nelems;
499
500
0
  return NC_NOERR;
501
0
}
502
503
504
int
505
NC3_rename_att( int ncid, int varid, const char *name, const char *unewname)
506
0
{
507
0
  int status = NC_NOERR;
508
0
  NC *nc = NULL;
509
0
  NC3_INFO* ncp = NULL;
510
0
  NC_attrarray *ncap = NULL;
511
0
  NC_attr **tmp = NULL;
512
0
  NC_attr *attrp = NULL;
513
0
  NC_string *newStr, *old;
514
0
  char *newname = NULL;  /* normalized version */
515
516
/* start sortof inline clone of NC_lookupattr() */
517
518
0
  status = NC_check_id(ncid, &nc);
519
0
  if(status != NC_NOERR)
520
0
    goto done;
521
0
  ncp = NC3_DATA(nc);
522
523
0
  if(NC_readonly(ncp))
524
0
    {status = NC_EPERM; goto done;}
525
526
0
  ncap = NC_attrarray0(ncp, varid);
527
0
  if(ncap == NULL)
528
0
    {status = NC_ENOTVAR; goto done;}
529
530
0
  status = NC_check_name(unewname);
531
0
  if(status != NC_NOERR)
532
0
    goto done;
533
534
0
  tmp = NC_findattr(ncap, name);
535
0
  if(tmp == NULL)
536
0
    {status = NC_ENOTATT; goto done;}
537
0
  attrp = *tmp;
538
/* end inline clone NC_lookupattr() */
539
540
0
  if(NC_findattr(ncap, unewname) != NULL)
541
0
      {status = NC_ENAMEINUSE; goto done;} /* name in use */
542
543
0
  old = attrp->name;
544
0
  status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char**)&newname);
545
0
  if(status != NC_NOERR)
546
0
      goto done;
547
0
  if(NC_indef(ncp))
548
0
  {
549
0
    newStr = new_NC_string(strlen(newname), newname);
550
0
    if( newStr == NULL)
551
0
      {status = NC_ENOMEM; goto done;}
552
0
    attrp->name = newStr;
553
0
    free_NC_string(old);
554
0
    goto done;
555
0
  }
556
  /* else not in define mode */
557
558
  /* If new name is longer than old, then complain,
559
           but otherwise, no change (test is same as set_NC_string)*/
560
0
  if(old->nchars < strlen(newname))
561
0
      {status = NC_ENOTINDEFINE; goto done;}
562
563
0
  status = set_NC_string(old, newname);
564
0
  if( status != NC_NOERR)
565
0
    goto done;
566
567
0
  set_NC_hdirty(ncp);
568
569
0
  if(NC_doHsync(ncp))
570
0
  {
571
0
    status = NC_sync(ncp);
572
0
    if(status != NC_NOERR)
573
0
      goto done;
574
0
  }
575
0
done:
576
0
  if(newname) free(newname);
577
0
  return status;
578
0
}
579
580
int
581
NC3_del_att(int ncid, int varid, const char *uname)
582
0
{
583
0
  int status = NC_NOERR;
584
0
  NC *nc = NULL;
585
0
  NC3_INFO* ncp = NULL;
586
0
  NC_attrarray *ncap = NULL;
587
0
  NC_attr **attrpp = NULL;
588
0
  NC_attr *old = NULL;
589
0
  int attrid;
590
0
  size_t slen;
591
0
  char* name = NULL;
592
593
0
  status = NC_check_id(ncid, &nc);
594
0
  if(status != NC_NOERR)
595
0
    goto done;
596
0
  ncp = NC3_DATA(nc);
597
598
0
  if(!NC_indef(ncp))
599
0
    {status = NC_ENOTINDEFINE; goto done;}
600
601
0
  ncap = NC_attrarray0(ncp, varid);
602
0
  if(ncap == NULL)
603
0
    {status = NC_ENOTVAR; goto done;}
604
605
0
  status = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
606
0
  if(status != NC_NOERR)
607
0
      goto done;
608
609
/* start sortof inline NC_findattr() */
610
0
  slen = strlen(name);
611
612
0
  attrpp = (NC_attr **) ncap->value;
613
0
  for(attrid = 0; (size_t) attrid < ncap->nelems; attrid++, attrpp++)
614
0
      {
615
0
    if( slen == (*attrpp)->name->nchars &&
616
0
      strncmp(name, (*attrpp)->name->cp, slen) == 0)
617
0
    {
618
0
      old = *attrpp;
619
0
      break;
620
0
    }
621
0
      }
622
0
  if( (size_t) attrid == ncap->nelems )
623
0
    {status = NC_ENOTATT; goto done;}
624
/* end inline NC_findattr() */
625
626
  /* shuffle down */
627
0
  for(attrid++; (size_t) attrid < ncap->nelems; attrid++)
628
0
  {
629
0
    *attrpp = *(attrpp + 1);
630
0
    attrpp++;
631
0
  }
632
0
  *attrpp = NULL;
633
  /* decrement count */
634
0
  ncap->nelems--;
635
636
0
  free_NC_attr(old);
637
638
0
done:
639
0
  if(name) free(name);
640
0
  return status;
641
0
}
642
643
644
static int
645
ncx_pad_putn_Iuchar(void **xpp, size_t nelems, const uchar *tp, nc_type type, void *fillp)
646
0
{
647
0
  switch(type) {
648
0
  case NC_CHAR:
649
0
    return NC_ECHAR;
650
0
  case NC_BYTE:
651
0
    return ncx_pad_putn_schar_uchar(xpp, nelems, tp, fillp);
652
0
  case NC_SHORT:
653
0
    return ncx_pad_putn_short_uchar(xpp, nelems, tp, fillp);
654
0
  case NC_INT:
655
0
    return ncx_putn_int_uchar(xpp, nelems, tp, fillp);
656
0
  case NC_FLOAT:
657
0
    return ncx_putn_float_uchar(xpp, nelems, tp, fillp);
658
0
  case NC_DOUBLE:
659
0
    return ncx_putn_double_uchar(xpp, nelems, tp, fillp);
660
0
  case NC_UBYTE:
661
0
    return ncx_pad_putn_uchar_uchar(xpp, nelems, tp, fillp);
662
0
  case NC_USHORT:
663
0
    return ncx_putn_ushort_uchar(xpp, nelems, tp, fillp);
664
0
  case NC_UINT:
665
0
    return ncx_putn_uint_uchar(xpp, nelems, tp, fillp);
666
0
  case NC_INT64:
667
0
    return ncx_putn_longlong_uchar(xpp, nelems, tp, fillp);
668
0
  case NC_UINT64:
669
0
    return ncx_putn_ulonglong_uchar(xpp, nelems, tp, fillp);
670
0
  default:
671
0
                assert("ncx_pad_putn_Iuchar invalid type" == 0);
672
0
  }
673
0
  return NC_EBADTYPE;
674
0
}
675
676
static int
677
ncx_pad_getn_Iuchar(const void **xpp, size_t nelems, uchar *tp, nc_type type)
678
0
{
679
0
  switch(type) {
680
0
  case NC_CHAR:
681
0
    return NC_ECHAR;
682
0
  case NC_BYTE:
683
0
    return ncx_pad_getn_schar_uchar(xpp, nelems, tp);
684
0
  case NC_SHORT:
685
0
    return ncx_pad_getn_short_uchar(xpp, nelems, tp);
686
0
  case NC_INT:
687
0
    return ncx_getn_int_uchar(xpp, nelems, tp);
688
0
  case NC_FLOAT:
689
0
    return ncx_getn_float_uchar(xpp, nelems, tp);
690
0
  case NC_DOUBLE:
691
0
    return ncx_getn_double_uchar(xpp, nelems, tp);
692
0
  case NC_UBYTE:
693
0
    return ncx_pad_getn_uchar_uchar(xpp, nelems, tp);
694
0
  case NC_USHORT:
695
0
    return ncx_getn_ushort_uchar(xpp, nelems, tp);
696
0
  case NC_UINT:
697
0
    return ncx_getn_uint_uchar(xpp, nelems, tp);
698
0
  case NC_INT64:
699
0
    return ncx_getn_longlong_uchar(xpp, nelems, tp);
700
0
  case NC_UINT64:
701
0
    return ncx_getn_ulonglong_uchar(xpp, nelems, tp);
702
0
  default:
703
0
          assert("ncx_pad_getn_Iuchar invalid type" == 0);
704
0
  }
705
0
  return NC_EBADTYPE;
706
0
}
707
708
709
static int
710
ncx_pad_putn_Ischar(void **xpp, size_t nelems, const schar *tp, nc_type type, void *fillp)
711
0
{
712
0
  switch(type) {
713
0
  case NC_CHAR:
714
0
    return NC_ECHAR;
715
0
  case NC_BYTE:
716
0
    return ncx_pad_putn_schar_schar(xpp, nelems, tp, fillp);
717
0
  case NC_SHORT:
718
0
    return ncx_pad_putn_short_schar(xpp, nelems, tp, fillp);
719
0
  case NC_INT:
720
0
    return ncx_putn_int_schar(xpp, nelems, tp, fillp);
721
0
  case NC_FLOAT:
722
0
    return ncx_putn_float_schar(xpp, nelems, tp, fillp);
723
0
  case NC_DOUBLE:
724
0
    return ncx_putn_double_schar(xpp, nelems, tp, fillp);
725
0
  case NC_UBYTE:
726
0
    return ncx_pad_putn_uchar_schar(xpp, nelems, tp, fillp);
727
0
  case NC_USHORT:
728
0
    return ncx_putn_ushort_schar(xpp, nelems, tp, fillp);
729
0
  case NC_UINT:
730
0
    return ncx_putn_uint_schar(xpp, nelems, tp, fillp);
731
0
  case NC_INT64:
732
0
    return ncx_putn_longlong_schar(xpp, nelems, tp, fillp);
733
0
  case NC_UINT64:
734
0
    return ncx_putn_ulonglong_schar(xpp, nelems, tp, fillp);
735
0
  default:
736
0
                assert("ncx_pad_putn_Ischar invalid type" == 0);
737
0
  }
738
0
  return NC_EBADTYPE;
739
0
}
740
741
static int
742
ncx_pad_getn_Ischar(const void **xpp, size_t nelems, schar *tp, nc_type type)
743
0
{
744
0
  switch(type) {
745
0
  case NC_CHAR:
746
0
    return NC_ECHAR;
747
0
  case NC_BYTE:
748
0
    return ncx_pad_getn_schar_schar(xpp, nelems, tp);
749
0
  case NC_SHORT:
750
0
    return ncx_pad_getn_short_schar(xpp, nelems, tp);
751
0
  case NC_INT:
752
0
    return ncx_getn_int_schar(xpp, nelems, tp);
753
0
  case NC_FLOAT:
754
0
    return ncx_getn_float_schar(xpp, nelems, tp);
755
0
  case NC_DOUBLE:
756
0
    return ncx_getn_double_schar(xpp, nelems, tp);
757
0
  case NC_UBYTE:
758
0
    return ncx_pad_getn_uchar_schar(xpp, nelems, tp);
759
0
  case NC_USHORT:
760
0
    return ncx_getn_ushort_schar(xpp, nelems, tp);
761
0
  case NC_UINT:
762
0
    return ncx_getn_uint_schar(xpp, nelems, tp);
763
0
  case NC_INT64:
764
0
    return ncx_getn_longlong_schar(xpp, nelems, tp);
765
0
  case NC_UINT64:
766
0
    return ncx_getn_ulonglong_schar(xpp, nelems, tp);
767
0
  default:
768
0
          assert("ncx_pad_getn_Ischar invalid type" == 0);
769
0
  }
770
0
  return NC_EBADTYPE;
771
0
}
772
773
774
static int
775
ncx_pad_putn_Ishort(void **xpp, size_t nelems, const short *tp, nc_type type, void *fillp)
776
0
{
777
0
  switch(type) {
778
0
  case NC_CHAR:
779
0
    return NC_ECHAR;
780
0
  case NC_BYTE:
781
0
    return ncx_pad_putn_schar_short(xpp, nelems, tp, fillp);
782
0
  case NC_SHORT:
783
0
    return ncx_pad_putn_short_short(xpp, nelems, tp, fillp);
784
0
  case NC_INT:
785
0
    return ncx_putn_int_short(xpp, nelems, tp, fillp);
786
0
  case NC_FLOAT:
787
0
    return ncx_putn_float_short(xpp, nelems, tp, fillp);
788
0
  case NC_DOUBLE:
789
0
    return ncx_putn_double_short(xpp, nelems, tp, fillp);
790
0
  case NC_UBYTE:
791
0
    return ncx_pad_putn_uchar_short(xpp, nelems, tp, fillp);
792
0
  case NC_USHORT:
793
0
    return ncx_putn_ushort_short(xpp, nelems, tp, fillp);
794
0
  case NC_UINT:
795
0
    return ncx_putn_uint_short(xpp, nelems, tp, fillp);
796
0
  case NC_INT64:
797
0
    return ncx_putn_longlong_short(xpp, nelems, tp, fillp);
798
0
  case NC_UINT64:
799
0
    return ncx_putn_ulonglong_short(xpp, nelems, tp, fillp);
800
0
  default:
801
0
                assert("ncx_pad_putn_Ishort invalid type" == 0);
802
0
  }
803
0
  return NC_EBADTYPE;
804
0
}
805
806
static int
807
ncx_pad_getn_Ishort(const void **xpp, size_t nelems, short *tp, nc_type type)
808
0
{
809
0
  switch(type) {
810
0
  case NC_CHAR:
811
0
    return NC_ECHAR;
812
0
  case NC_BYTE:
813
0
    return ncx_pad_getn_schar_short(xpp, nelems, tp);
814
0
  case NC_SHORT:
815
0
    return ncx_pad_getn_short_short(xpp, nelems, tp);
816
0
  case NC_INT:
817
0
    return ncx_getn_int_short(xpp, nelems, tp);
818
0
  case NC_FLOAT:
819
0
    return ncx_getn_float_short(xpp, nelems, tp);
820
0
  case NC_DOUBLE:
821
0
    return ncx_getn_double_short(xpp, nelems, tp);
822
0
  case NC_UBYTE:
823
0
    return ncx_pad_getn_uchar_short(xpp, nelems, tp);
824
0
  case NC_USHORT:
825
0
    return ncx_getn_ushort_short(xpp, nelems, tp);
826
0
  case NC_UINT:
827
0
    return ncx_getn_uint_short(xpp, nelems, tp);
828
0
  case NC_INT64:
829
0
    return ncx_getn_longlong_short(xpp, nelems, tp);
830
0
  case NC_UINT64:
831
0
    return ncx_getn_ulonglong_short(xpp, nelems, tp);
832
0
  default:
833
0
          assert("ncx_pad_getn_Ishort invalid type" == 0);
834
0
  }
835
0
  return NC_EBADTYPE;
836
0
}
837
838
839
static int
840
ncx_pad_putn_Iint(void **xpp, size_t nelems, const int *tp, nc_type type, void *fillp)
841
0
{
842
0
  switch(type) {
843
0
  case NC_CHAR:
844
0
    return NC_ECHAR;
845
0
  case NC_BYTE:
846
0
    return ncx_pad_putn_schar_int(xpp, nelems, tp, fillp);
847
0
  case NC_SHORT:
848
0
    return ncx_pad_putn_short_int(xpp, nelems, tp, fillp);
849
0
  case NC_INT:
850
0
    return ncx_putn_int_int(xpp, nelems, tp, fillp);
851
0
  case NC_FLOAT:
852
0
    return ncx_putn_float_int(xpp, nelems, tp, fillp);
853
0
  case NC_DOUBLE:
854
0
    return ncx_putn_double_int(xpp, nelems, tp, fillp);
855
0
  case NC_UBYTE:
856
0
    return ncx_pad_putn_uchar_int(xpp, nelems, tp, fillp);
857
0
  case NC_USHORT:
858
0
    return ncx_putn_ushort_int(xpp, nelems, tp, fillp);
859
0
  case NC_UINT:
860
0
    return ncx_putn_uint_int(xpp, nelems, tp, fillp);
861
0
  case NC_INT64:
862
0
    return ncx_putn_longlong_int(xpp, nelems, tp, fillp);
863
0
  case NC_UINT64:
864
0
    return ncx_putn_ulonglong_int(xpp, nelems, tp, fillp);
865
0
  default:
866
0
                assert("ncx_pad_putn_Iint invalid type" == 0);
867
0
  }
868
0
  return NC_EBADTYPE;
869
0
}
870
871
static int
872
ncx_pad_getn_Iint(const void **xpp, size_t nelems, int *tp, nc_type type)
873
0
{
874
0
  switch(type) {
875
0
  case NC_CHAR:
876
0
    return NC_ECHAR;
877
0
  case NC_BYTE:
878
0
    return ncx_pad_getn_schar_int(xpp, nelems, tp);
879
0
  case NC_SHORT:
880
0
    return ncx_pad_getn_short_int(xpp, nelems, tp);
881
0
  case NC_INT:
882
0
    return ncx_getn_int_int(xpp, nelems, tp);
883
0
  case NC_FLOAT:
884
0
    return ncx_getn_float_int(xpp, nelems, tp);
885
0
  case NC_DOUBLE:
886
0
    return ncx_getn_double_int(xpp, nelems, tp);
887
0
  case NC_UBYTE:
888
0
    return ncx_pad_getn_uchar_int(xpp, nelems, tp);
889
0
  case NC_USHORT:
890
0
    return ncx_getn_ushort_int(xpp, nelems, tp);
891
0
  case NC_UINT:
892
0
    return ncx_getn_uint_int(xpp, nelems, tp);
893
0
  case NC_INT64:
894
0
    return ncx_getn_longlong_int(xpp, nelems, tp);
895
0
  case NC_UINT64:
896
0
    return ncx_getn_ulonglong_int(xpp, nelems, tp);
897
0
  default:
898
0
          assert("ncx_pad_getn_Iint invalid type" == 0);
899
0
  }
900
0
  return NC_EBADTYPE;
901
0
}
902
903
904
static int
905
ncx_pad_putn_Ifloat(void **xpp, size_t nelems, const float *tp, nc_type type, void *fillp)
906
0
{
907
0
  switch(type) {
908
0
  case NC_CHAR:
909
0
    return NC_ECHAR;
910
0
  case NC_BYTE:
911
0
    return ncx_pad_putn_schar_float(xpp, nelems, tp, fillp);
912
0
  case NC_SHORT:
913
0
    return ncx_pad_putn_short_float(xpp, nelems, tp, fillp);
914
0
  case NC_INT:
915
0
    return ncx_putn_int_float(xpp, nelems, tp, fillp);
916
0
  case NC_FLOAT:
917
0
    return ncx_putn_float_float(xpp, nelems, tp, fillp);
918
0
  case NC_DOUBLE:
919
0
    return ncx_putn_double_float(xpp, nelems, tp, fillp);
920
0
  case NC_UBYTE:
921
0
    return ncx_pad_putn_uchar_float(xpp, nelems, tp, fillp);
922
0
  case NC_USHORT:
923
0
    return ncx_putn_ushort_float(xpp, nelems, tp, fillp);
924
0
  case NC_UINT:
925
0
    return ncx_putn_uint_float(xpp, nelems, tp, fillp);
926
0
  case NC_INT64:
927
0
    return ncx_putn_longlong_float(xpp, nelems, tp, fillp);
928
0
  case NC_UINT64:
929
0
    return ncx_putn_ulonglong_float(xpp, nelems, tp, fillp);
930
0
  default:
931
0
                assert("ncx_pad_putn_Ifloat invalid type" == 0);
932
0
  }
933
0
  return NC_EBADTYPE;
934
0
}
935
936
static int
937
ncx_pad_getn_Ifloat(const void **xpp, size_t nelems, float *tp, nc_type type)
938
0
{
939
0
  switch(type) {
940
0
  case NC_CHAR:
941
0
    return NC_ECHAR;
942
0
  case NC_BYTE:
943
0
    return ncx_pad_getn_schar_float(xpp, nelems, tp);
944
0
  case NC_SHORT:
945
0
    return ncx_pad_getn_short_float(xpp, nelems, tp);
946
0
  case NC_INT:
947
0
    return ncx_getn_int_float(xpp, nelems, tp);
948
0
  case NC_FLOAT:
949
0
    return ncx_getn_float_float(xpp, nelems, tp);
950
0
  case NC_DOUBLE:
951
0
    return ncx_getn_double_float(xpp, nelems, tp);
952
0
  case NC_UBYTE:
953
0
    return ncx_pad_getn_uchar_float(xpp, nelems, tp);
954
0
  case NC_USHORT:
955
0
    return ncx_getn_ushort_float(xpp, nelems, tp);
956
0
  case NC_UINT:
957
0
    return ncx_getn_uint_float(xpp, nelems, tp);
958
0
  case NC_INT64:
959
0
    return ncx_getn_longlong_float(xpp, nelems, tp);
960
0
  case NC_UINT64:
961
0
    return ncx_getn_ulonglong_float(xpp, nelems, tp);
962
0
  default:
963
0
          assert("ncx_pad_getn_Ifloat invalid type" == 0);
964
0
  }
965
0
  return NC_EBADTYPE;
966
0
}
967
968
969
static int
970
ncx_pad_putn_Idouble(void **xpp, size_t nelems, const double *tp, nc_type type, void *fillp)
971
0
{
972
0
  switch(type) {
973
0
  case NC_CHAR:
974
0
    return NC_ECHAR;
975
0
  case NC_BYTE:
976
0
    return ncx_pad_putn_schar_double(xpp, nelems, tp, fillp);
977
0
  case NC_SHORT:
978
0
    return ncx_pad_putn_short_double(xpp, nelems, tp, fillp);
979
0
  case NC_INT:
980
0
    return ncx_putn_int_double(xpp, nelems, tp, fillp);
981
0
  case NC_FLOAT:
982
0
    return ncx_putn_float_double(xpp, nelems, tp, fillp);
983
0
  case NC_DOUBLE:
984
0
    return ncx_putn_double_double(xpp, nelems, tp, fillp);
985
0
  case NC_UBYTE:
986
0
    return ncx_pad_putn_uchar_double(xpp, nelems, tp, fillp);
987
0
  case NC_USHORT:
988
0
    return ncx_putn_ushort_double(xpp, nelems, tp, fillp);
989
0
  case NC_UINT:
990
0
    return ncx_putn_uint_double(xpp, nelems, tp, fillp);
991
0
  case NC_INT64:
992
0
    return ncx_putn_longlong_double(xpp, nelems, tp, fillp);
993
0
  case NC_UINT64:
994
0
    return ncx_putn_ulonglong_double(xpp, nelems, tp, fillp);
995
0
  default:
996
0
                assert("ncx_pad_putn_Idouble invalid type" == 0);
997
0
  }
998
0
  return NC_EBADTYPE;
999
0
}
1000
1001
static int
1002
ncx_pad_getn_Idouble(const void **xpp, size_t nelems, double *tp, nc_type type)
1003
0
{
1004
0
  switch(type) {
1005
0
  case NC_CHAR:
1006
0
    return NC_ECHAR;
1007
0
  case NC_BYTE:
1008
0
    return ncx_pad_getn_schar_double(xpp, nelems, tp);
1009
0
  case NC_SHORT:
1010
0
    return ncx_pad_getn_short_double(xpp, nelems, tp);
1011
0
  case NC_INT:
1012
0
    return ncx_getn_int_double(xpp, nelems, tp);
1013
0
  case NC_FLOAT:
1014
0
    return ncx_getn_float_double(xpp, nelems, tp);
1015
0
  case NC_DOUBLE:
1016
0
    return ncx_getn_double_double(xpp, nelems, tp);
1017
0
  case NC_UBYTE:
1018
0
    return ncx_pad_getn_uchar_double(xpp, nelems, tp);
1019
0
  case NC_USHORT:
1020
0
    return ncx_getn_ushort_double(xpp, nelems, tp);
1021
0
  case NC_UINT:
1022
0
    return ncx_getn_uint_double(xpp, nelems, tp);
1023
0
  case NC_INT64:
1024
0
    return ncx_getn_longlong_double(xpp, nelems, tp);
1025
0
  case NC_UINT64:
1026
0
    return ncx_getn_ulonglong_double(xpp, nelems, tp);
1027
0
  default:
1028
0
          assert("ncx_pad_getn_Idouble invalid type" == 0);
1029
0
  }
1030
0
  return NC_EBADTYPE;
1031
0
}
1032
1033
1034
#ifdef IGNORE
1035
static int
1036
ncx_pad_putn_Ilong(void **xpp, size_t nelems, const long *tp, nc_type type, void *fillp)
1037
{
1038
  switch(type) {
1039
  case NC_CHAR:
1040
    return NC_ECHAR;
1041
  case NC_BYTE:
1042
    return ncx_pad_putn_schar_long(xpp, nelems, tp, fillp);
1043
  case NC_SHORT:
1044
    return ncx_pad_putn_short_long(xpp, nelems, tp, fillp);
1045
  case NC_INT:
1046
    return ncx_putn_int_long(xpp, nelems, tp, fillp);
1047
  case NC_FLOAT:
1048
    return ncx_putn_float_long(xpp, nelems, tp, fillp);
1049
  case NC_DOUBLE:
1050
    return ncx_putn_double_long(xpp, nelems, tp, fillp);
1051
  case NC_UBYTE:
1052
    return ncx_pad_putn_uchar_long(xpp, nelems, tp, fillp);
1053
  case NC_USHORT:
1054
    return ncx_putn_ushort_long(xpp, nelems, tp, fillp);
1055
  case NC_UINT:
1056
    return ncx_putn_uint_long(xpp, nelems, tp, fillp);
1057
  case NC_INT64:
1058
    return ncx_putn_longlong_long(xpp, nelems, tp, fillp);
1059
  case NC_UINT64:
1060
    return ncx_putn_ulonglong_long(xpp, nelems, tp, fillp);
1061
  default:
1062
                assert("ncx_pad_putn_Ilong invalid type" == 0);
1063
  }
1064
  return NC_EBADTYPE;
1065
}
1066
1067
static int
1068
ncx_pad_getn_Ilong(const void **xpp, size_t nelems, long *tp, nc_type type)
1069
{
1070
  switch(type) {
1071
  case NC_CHAR:
1072
    return NC_ECHAR;
1073
  case NC_BYTE:
1074
    return ncx_pad_getn_schar_long(xpp, nelems, tp);
1075
  case NC_SHORT:
1076
    return ncx_pad_getn_short_long(xpp, nelems, tp);
1077
  case NC_INT:
1078
    return ncx_getn_int_long(xpp, nelems, tp);
1079
  case NC_FLOAT:
1080
    return ncx_getn_float_long(xpp, nelems, tp);
1081
  case NC_DOUBLE:
1082
    return ncx_getn_double_long(xpp, nelems, tp);
1083
  case NC_UBYTE:
1084
    return ncx_pad_getn_uchar_long(xpp, nelems, tp);
1085
  case NC_USHORT:
1086
    return ncx_getn_ushort_long(xpp, nelems, tp);
1087
  case NC_UINT:
1088
    return ncx_getn_uint_long(xpp, nelems, tp);
1089
  case NC_INT64:
1090
    return ncx_getn_longlong_long(xpp, nelems, tp);
1091
  case NC_UINT64:
1092
    return ncx_getn_ulonglong_long(xpp, nelems, tp);
1093
  default:
1094
          assert("ncx_pad_getn_Ilong invalid type" == 0);
1095
  }
1096
  return NC_EBADTYPE;
1097
}
1098
1099
#endif
1100
1101
static int
1102
ncx_pad_putn_Ilonglong(void **xpp, size_t nelems, const longlong *tp, nc_type type, void *fillp)
1103
0
{
1104
0
  switch(type) {
1105
0
  case NC_CHAR:
1106
0
    return NC_ECHAR;
1107
0
  case NC_BYTE:
1108
0
    return ncx_pad_putn_schar_longlong(xpp, nelems, tp, fillp);
1109
0
  case NC_SHORT:
1110
0
    return ncx_pad_putn_short_longlong(xpp, nelems, tp, fillp);
1111
0
  case NC_INT:
1112
0
    return ncx_putn_int_longlong(xpp, nelems, tp, fillp);
1113
0
  case NC_FLOAT:
1114
0
    return ncx_putn_float_longlong(xpp, nelems, tp, fillp);
1115
0
  case NC_DOUBLE:
1116
0
    return ncx_putn_double_longlong(xpp, nelems, tp, fillp);
1117
0
  case NC_UBYTE:
1118
0
    return ncx_pad_putn_uchar_longlong(xpp, nelems, tp, fillp);
1119
0
  case NC_USHORT:
1120
0
    return ncx_putn_ushort_longlong(xpp, nelems, tp, fillp);
1121
0
  case NC_UINT:
1122
0
    return ncx_putn_uint_longlong(xpp, nelems, tp, fillp);
1123
0
  case NC_INT64:
1124
0
    return ncx_putn_longlong_longlong(xpp, nelems, tp, fillp);
1125
0
  case NC_UINT64:
1126
0
    return ncx_putn_ulonglong_longlong(xpp, nelems, tp, fillp);
1127
0
  default:
1128
0
                assert("ncx_pad_putn_Ilonglong invalid type" == 0);
1129
0
  }
1130
0
  return NC_EBADTYPE;
1131
0
}
1132
1133
static int
1134
ncx_pad_getn_Ilonglong(const void **xpp, size_t nelems, longlong *tp, nc_type type)
1135
0
{
1136
0
  switch(type) {
1137
0
  case NC_CHAR:
1138
0
    return NC_ECHAR;
1139
0
  case NC_BYTE:
1140
0
    return ncx_pad_getn_schar_longlong(xpp, nelems, tp);
1141
0
  case NC_SHORT:
1142
0
    return ncx_pad_getn_short_longlong(xpp, nelems, tp);
1143
0
  case NC_INT:
1144
0
    return ncx_getn_int_longlong(xpp, nelems, tp);
1145
0
  case NC_FLOAT:
1146
0
    return ncx_getn_float_longlong(xpp, nelems, tp);
1147
0
  case NC_DOUBLE:
1148
0
    return ncx_getn_double_longlong(xpp, nelems, tp);
1149
0
  case NC_UBYTE:
1150
0
    return ncx_pad_getn_uchar_longlong(xpp, nelems, tp);
1151
0
  case NC_USHORT:
1152
0
    return ncx_getn_ushort_longlong(xpp, nelems, tp);
1153
0
  case NC_UINT:
1154
0
    return ncx_getn_uint_longlong(xpp, nelems, tp);
1155
0
  case NC_INT64:
1156
0
    return ncx_getn_longlong_longlong(xpp, nelems, tp);
1157
0
  case NC_UINT64:
1158
0
    return ncx_getn_ulonglong_longlong(xpp, nelems, tp);
1159
0
  default:
1160
0
          assert("ncx_pad_getn_Ilonglong invalid type" == 0);
1161
0
  }
1162
0
  return NC_EBADTYPE;
1163
0
}
1164
1165
1166
static int
1167
ncx_pad_putn_Iushort(void **xpp, size_t nelems, const ushort *tp, nc_type type, void *fillp)
1168
0
{
1169
0
  switch(type) {
1170
0
  case NC_CHAR:
1171
0
    return NC_ECHAR;
1172
0
  case NC_BYTE:
1173
0
    return ncx_pad_putn_schar_ushort(xpp, nelems, tp, fillp);
1174
0
  case NC_SHORT:
1175
0
    return ncx_pad_putn_short_ushort(xpp, nelems, tp, fillp);
1176
0
  case NC_INT:
1177
0
    return ncx_putn_int_ushort(xpp, nelems, tp, fillp);
1178
0
  case NC_FLOAT:
1179
0
    return ncx_putn_float_ushort(xpp, nelems, tp, fillp);
1180
0
  case NC_DOUBLE:
1181
0
    return ncx_putn_double_ushort(xpp, nelems, tp, fillp);
1182
0
  case NC_UBYTE:
1183
0
    return ncx_pad_putn_uchar_ushort(xpp, nelems, tp, fillp);
1184
0
  case NC_USHORT:
1185
0
    return ncx_putn_ushort_ushort(xpp, nelems, tp, fillp);
1186
0
  case NC_UINT:
1187
0
    return ncx_putn_uint_ushort(xpp, nelems, tp, fillp);
1188
0
  case NC_INT64:
1189
0
    return ncx_putn_longlong_ushort(xpp, nelems, tp, fillp);
1190
0
  case NC_UINT64:
1191
0
    return ncx_putn_ulonglong_ushort(xpp, nelems, tp, fillp);
1192
0
  default:
1193
0
                assert("ncx_pad_putn_Iushort invalid type" == 0);
1194
0
  }
1195
0
  return NC_EBADTYPE;
1196
0
}
1197
1198
static int
1199
ncx_pad_getn_Iushort(const void **xpp, size_t nelems, ushort *tp, nc_type type)
1200
0
{
1201
0
  switch(type) {
1202
0
  case NC_CHAR:
1203
0
    return NC_ECHAR;
1204
0
  case NC_BYTE:
1205
0
    return ncx_pad_getn_schar_ushort(xpp, nelems, tp);
1206
0
  case NC_SHORT:
1207
0
    return ncx_pad_getn_short_ushort(xpp, nelems, tp);
1208
0
  case NC_INT:
1209
0
    return ncx_getn_int_ushort(xpp, nelems, tp);
1210
0
  case NC_FLOAT:
1211
0
    return ncx_getn_float_ushort(xpp, nelems, tp);
1212
0
  case NC_DOUBLE:
1213
0
    return ncx_getn_double_ushort(xpp, nelems, tp);
1214
0
  case NC_UBYTE:
1215
0
    return ncx_pad_getn_uchar_ushort(xpp, nelems, tp);
1216
0
  case NC_USHORT:
1217
0
    return ncx_getn_ushort_ushort(xpp, nelems, tp);
1218
0
  case NC_UINT:
1219
0
    return ncx_getn_uint_ushort(xpp, nelems, tp);
1220
0
  case NC_INT64:
1221
0
    return ncx_getn_longlong_ushort(xpp, nelems, tp);
1222
0
  case NC_UINT64:
1223
0
    return ncx_getn_ulonglong_ushort(xpp, nelems, tp);
1224
0
  default:
1225
0
          assert("ncx_pad_getn_Iushort invalid type" == 0);
1226
0
  }
1227
0
  return NC_EBADTYPE;
1228
0
}
1229
1230
1231
static int
1232
ncx_pad_putn_Iuint(void **xpp, size_t nelems, const uint *tp, nc_type type, void *fillp)
1233
0
{
1234
0
  switch(type) {
1235
0
  case NC_CHAR:
1236
0
    return NC_ECHAR;
1237
0
  case NC_BYTE:
1238
0
    return ncx_pad_putn_schar_uint(xpp, nelems, tp, fillp);
1239
0
  case NC_SHORT:
1240
0
    return ncx_pad_putn_short_uint(xpp, nelems, tp, fillp);
1241
0
  case NC_INT:
1242
0
    return ncx_putn_int_uint(xpp, nelems, tp, fillp);
1243
0
  case NC_FLOAT:
1244
0
    return ncx_putn_float_uint(xpp, nelems, tp, fillp);
1245
0
  case NC_DOUBLE:
1246
0
    return ncx_putn_double_uint(xpp, nelems, tp, fillp);
1247
0
  case NC_UBYTE:
1248
0
    return ncx_pad_putn_uchar_uint(xpp, nelems, tp, fillp);
1249
0
  case NC_USHORT:
1250
0
    return ncx_putn_ushort_uint(xpp, nelems, tp, fillp);
1251
0
  case NC_UINT:
1252
0
    return ncx_putn_uint_uint(xpp, nelems, tp, fillp);
1253
0
  case NC_INT64:
1254
0
    return ncx_putn_longlong_uint(xpp, nelems, tp, fillp);
1255
0
  case NC_UINT64:
1256
0
    return ncx_putn_ulonglong_uint(xpp, nelems, tp, fillp);
1257
0
  default:
1258
0
                assert("ncx_pad_putn_Iuint invalid type" == 0);
1259
0
  }
1260
0
  return NC_EBADTYPE;
1261
0
}
1262
1263
static int
1264
ncx_pad_getn_Iuint(const void **xpp, size_t nelems, uint *tp, nc_type type)
1265
0
{
1266
0
  switch(type) {
1267
0
  case NC_CHAR:
1268
0
    return NC_ECHAR;
1269
0
  case NC_BYTE:
1270
0
    return ncx_pad_getn_schar_uint(xpp, nelems, tp);
1271
0
  case NC_SHORT:
1272
0
    return ncx_pad_getn_short_uint(xpp, nelems, tp);
1273
0
  case NC_INT:
1274
0
    return ncx_getn_int_uint(xpp, nelems, tp);
1275
0
  case NC_FLOAT:
1276
0
    return ncx_getn_float_uint(xpp, nelems, tp);
1277
0
  case NC_DOUBLE:
1278
0
    return ncx_getn_double_uint(xpp, nelems, tp);
1279
0
  case NC_UBYTE:
1280
0
    return ncx_pad_getn_uchar_uint(xpp, nelems, tp);
1281
0
  case NC_USHORT:
1282
0
    return ncx_getn_ushort_uint(xpp, nelems, tp);
1283
0
  case NC_UINT:
1284
0
    return ncx_getn_uint_uint(xpp, nelems, tp);
1285
0
  case NC_INT64:
1286
0
    return ncx_getn_longlong_uint(xpp, nelems, tp);
1287
0
  case NC_UINT64:
1288
0
    return ncx_getn_ulonglong_uint(xpp, nelems, tp);
1289
0
  default:
1290
0
          assert("ncx_pad_getn_Iuint invalid type" == 0);
1291
0
  }
1292
0
  return NC_EBADTYPE;
1293
0
}
1294
1295
1296
static int
1297
ncx_pad_putn_Iulonglong(void **xpp, size_t nelems, const ulonglong *tp, nc_type type, void *fillp)
1298
0
{
1299
0
  switch(type) {
1300
0
  case NC_CHAR:
1301
0
    return NC_ECHAR;
1302
0
  case NC_BYTE:
1303
0
    return ncx_pad_putn_schar_ulonglong(xpp, nelems, tp, fillp);
1304
0
  case NC_SHORT:
1305
0
    return ncx_pad_putn_short_ulonglong(xpp, nelems, tp, fillp);
1306
0
  case NC_INT:
1307
0
    return ncx_putn_int_ulonglong(xpp, nelems, tp, fillp);
1308
0
  case NC_FLOAT:
1309
0
    return ncx_putn_float_ulonglong(xpp, nelems, tp, fillp);
1310
0
  case NC_DOUBLE:
1311
0
    return ncx_putn_double_ulonglong(xpp, nelems, tp, fillp);
1312
0
  case NC_UBYTE:
1313
0
    return ncx_pad_putn_uchar_ulonglong(xpp, nelems, tp, fillp);
1314
0
  case NC_USHORT:
1315
0
    return ncx_putn_ushort_ulonglong(xpp, nelems, tp, fillp);
1316
0
  case NC_UINT:
1317
0
    return ncx_putn_uint_ulonglong(xpp, nelems, tp, fillp);
1318
0
  case NC_INT64:
1319
0
    return ncx_putn_longlong_ulonglong(xpp, nelems, tp, fillp);
1320
0
  case NC_UINT64:
1321
0
    return ncx_putn_ulonglong_ulonglong(xpp, nelems, tp, fillp);
1322
0
  default:
1323
0
                assert("ncx_pad_putn_Iulonglong invalid type" == 0);
1324
0
  }
1325
0
  return NC_EBADTYPE;
1326
0
}
1327
1328
static int
1329
ncx_pad_getn_Iulonglong(const void **xpp, size_t nelems, ulonglong *tp, nc_type type)
1330
0
{
1331
0
  switch(type) {
1332
0
  case NC_CHAR:
1333
0
    return NC_ECHAR;
1334
0
  case NC_BYTE:
1335
0
    return ncx_pad_getn_schar_ulonglong(xpp, nelems, tp);
1336
0
  case NC_SHORT:
1337
0
    return ncx_pad_getn_short_ulonglong(xpp, nelems, tp);
1338
0
  case NC_INT:
1339
0
    return ncx_getn_int_ulonglong(xpp, nelems, tp);
1340
0
  case NC_FLOAT:
1341
0
    return ncx_getn_float_ulonglong(xpp, nelems, tp);
1342
0
  case NC_DOUBLE:
1343
0
    return ncx_getn_double_ulonglong(xpp, nelems, tp);
1344
0
  case NC_UBYTE:
1345
0
    return ncx_pad_getn_uchar_ulonglong(xpp, nelems, tp);
1346
0
  case NC_USHORT:
1347
0
    return ncx_getn_ushort_ulonglong(xpp, nelems, tp);
1348
0
  case NC_UINT:
1349
0
    return ncx_getn_uint_ulonglong(xpp, nelems, tp);
1350
0
  case NC_INT64:
1351
0
    return ncx_getn_longlong_ulonglong(xpp, nelems, tp);
1352
0
  case NC_UINT64:
1353
0
    return ncx_getn_ulonglong_ulonglong(xpp, nelems, tp);
1354
0
  default:
1355
0
          assert("ncx_pad_getn_Iulonglong invalid type" == 0);
1356
0
  }
1357
0
  return NC_EBADTYPE;
1358
0
}
1359
1360
1361
1362
/* Common dispatcher for put cases */
1363
static int
1364
dispatchput(void **xpp, size_t nelems, const void* tp,
1365
      nc_type atype, nc_type memtype, void *fillp)
1366
0
{
1367
0
    switch (memtype) {
1368
0
    case NC_CHAR:
1369
0
        return ncx_pad_putn_text(xpp,nelems, (char *)tp);
1370
0
    case NC_BYTE:
1371
0
        return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype, fillp);
1372
0
    case NC_SHORT:
1373
0
        return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype, fillp);
1374
0
    case NC_INT:
1375
0
          return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype, fillp);
1376
0
    case NC_FLOAT:
1377
0
        return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype, fillp);
1378
0
    case NC_DOUBLE:
1379
0
        return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype, fillp);
1380
0
    case NC_UBYTE: /*Synthetic*/
1381
0
        return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype, fillp);
1382
0
    case NC_INT64:
1383
0
          return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype, fillp);
1384
0
    case NC_USHORT:
1385
0
          return ncx_pad_putn_Iushort(xpp, nelems, (ushort*)tp, atype, fillp);
1386
0
    case NC_UINT:
1387
0
          return ncx_pad_putn_Iuint(xpp, nelems, (uint*)tp, atype, fillp);
1388
0
    case NC_UINT64:
1389
0
          return ncx_pad_putn_Iulonglong(xpp, nelems, (ulonglong*)tp, atype, fillp);
1390
0
    case NC_NAT:
1391
0
        return NC_EBADTYPE;
1392
0
    default:
1393
0
        break;
1394
0
    }
1395
0
    return NC_EBADTYPE;
1396
0
}
1397
1398
int
1399
NC3_put_att(
1400
  int ncid,
1401
  int varid,
1402
  const char *name,
1403
  nc_type type,
1404
  size_t nelems,
1405
  const void *value,
1406
  nc_type memtype)
1407
0
{
1408
0
    int status;
1409
0
    NC *nc;
1410
0
    NC3_INFO* ncp;
1411
0
    NC_attrarray *ncap;
1412
0
    NC_attr **attrpp;
1413
0
    NC_attr *old = NULL;
1414
0
    NC_attr *attrp;
1415
0
    unsigned char fill[8]; /* fill value in internal representation */
1416
1417
0
    status = NC_check_id(ncid, &nc);
1418
0
    if(status != NC_NOERR)
1419
0
  return status;
1420
0
    ncp = NC3_DATA(nc);
1421
1422
0
    if(NC_readonly(ncp))
1423
0
  return NC_EPERM;
1424
1425
0
    ncap = NC_attrarray0(ncp, varid);
1426
0
    if(ncap == NULL)
1427
0
  return NC_ENOTVAR;
1428
1429
0
    if (name == NULL)
1430
0
        return NC_EBADNAME;
1431
1432
    /* check NC_EBADTYPE */
1433
0
    status = nc3_cktype(nc->mode, type);
1434
0
    if(status != NC_NOERR)
1435
0
  return status;
1436
1437
0
    if(memtype == NC_NAT) memtype = type;
1438
1439
0
    if(memtype != NC_CHAR && type == NC_CHAR)
1440
0
  return NC_ECHAR;
1441
0
    if(memtype == NC_CHAR && type != NC_CHAR)
1442
0
  return NC_ECHAR;
1443
1444
    /* cast needed for braindead systems with signed size_t */
1445
0
    if((unsigned long) nelems > X_INT_MAX) /* backward compat */
1446
0
  return NC_EINVAL; /* Invalid nelems */
1447
1448
0
    if(nelems != 0 && value == NULL)
1449
0
  return NC_EINVAL; /* Null arg */
1450
1451
    /* Temporarily removed to preserve extant
1452
       workflows (NCO based and others). See
1453
1454
       https://github.com/Unidata/netcdf-c/issues/843
1455
1456
       for more information. */
1457
1458
#if 0
1459
    if (varid != NC_GLOBAL && !strcmp(name, _FillValue)) {
1460
        /* Fill value must be of the same data type */
1461
        if (type != ncp->vars.value[varid]->type) return NC_EBADTYPE;
1462
1463
        /* Fill value must have exactly one value */
1464
        if (nelems != 1) return NC_EINVAL;
1465
1466
        /* Only allow for variables defined in initial define mode */
1467
        if (ncp->old != NULL && varid < ncp->old->vars.nelems)
1468
            return NC_ELATEFILL; /* try put attribute for an old variable */
1469
    }
1470
#endif
1471
1472
0
    attrpp = NC_findattr(ncap, name);
1473
1474
    /* 4 cases: exists X indef */
1475
1476
0
    status = NC3_inq_default_fill_value(type, &fill);
1477
0
    if (status != NC_NOERR) return status;
1478
1479
0
    if(attrpp != NULL) { /* name in use */
1480
0
        if(!NC_indef(ncp)) {
1481
0
      const size_t xsz = ncx_len_NC_attrV(type, nelems);
1482
0
            attrp = *attrpp; /* convenience */
1483
1484
0
      if(xsz > attrp->xsz) return NC_ENOTINDEFINE;
1485
      /* else, we can reuse existing without redef */
1486
1487
0
      attrp->xsz = xsz;
1488
0
            attrp->type = type;
1489
0
            attrp->nelems = nelems;
1490
1491
0
            if(nelems != 0) {
1492
0
                void *xp = attrp->xvalue;
1493
                /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
1494
0
                if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) {
1495
0
                    status = NC3_inq_default_fill_value(NC_UBYTE, &fill);
1496
0
                    if (status != NC_NOERR) return status;
1497
0
                    status = dispatchput(&xp, nelems, value, memtype, memtype, &fill);
1498
0
                } else
1499
0
                    status = dispatchput(&xp, nelems, value, type, memtype, &fill);
1500
0
            }
1501
1502
0
            set_NC_hdirty(ncp);
1503
1504
0
            if(NC_doHsync(ncp)) {
1505
0
          const int lstatus = NC_sync(ncp);
1506
                /*
1507
                 * N.B.: potentially overrides NC_ERANGE
1508
                 * set by ncx_pad_putn_I$1
1509
                 */
1510
0
                if(lstatus != NC_NOERR) return lstatus;
1511
0
            }
1512
1513
0
            return status;
1514
0
        }
1515
        /* else, redefine using existing array slot */
1516
0
        old = *attrpp;
1517
0
    } else {
1518
0
        if(!NC_indef(ncp)) return NC_ENOTINDEFINE;
1519
0
    }
1520
1521
0
    status = NC_check_name(name);
1522
0
    if(status != NC_NOERR) return status;
1523
1524
0
    attrp = new_NC_attr(name, type, nelems);
1525
0
    if(attrp == NULL) return NC_ENOMEM;
1526
1527
0
    if(nelems != 0) {
1528
0
        void *xp = attrp->xvalue;
1529
        /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
1530
0
        if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) {
1531
0
            status = NC3_inq_default_fill_value(NC_UBYTE, &fill);
1532
0
            if (status != NC_NOERR) return status;
1533
0
            status = dispatchput(&xp, nelems, (const void*)value, memtype, memtype, &fill);
1534
0
        } else
1535
0
            status = dispatchput(&xp, nelems, (const void*)value, type, memtype, &fill);
1536
0
    }
1537
1538
0
    if(attrpp != NULL) {
1539
0
        *attrpp = attrp;
1540
0
  if(old != NULL)
1541
0
          free_NC_attr(old);
1542
0
    } else {
1543
0
        const int lstatus = incr_NC_attrarray(ncap, attrp);
1544
        /*
1545
         * N.B.: potentially overrides NC_ERANGE
1546
         * set by ncx_pad_putn_I$1
1547
         */
1548
0
        if(lstatus != NC_NOERR) {
1549
0
           free_NC_attr(attrp);
1550
0
           return lstatus;
1551
0
        }
1552
0
    }
1553
0
    return status;
1554
0
}
1555
1556
int
1557
NC3_get_att(
1558
  int ncid,
1559
  int varid,
1560
  const char *name,
1561
  void *value,
1562
  nc_type memtype)
1563
0
{
1564
0
    int status;
1565
0
    NC *nc;
1566
0
    NC3_INFO* ncp;
1567
0
    NC_attr *attrp;
1568
0
    const void *xp;
1569
1570
0
    status = NC_check_id(ncid, &nc);
1571
0
    if(status != NC_NOERR)
1572
0
  return status;
1573
0
    ncp = NC3_DATA(nc);
1574
1575
0
    status = NC_lookupattr(ncid, varid, name, &attrp);
1576
0
    if(status != NC_NOERR) return status;
1577
1578
0
    if(attrp->nelems == 0) return NC_NOERR;
1579
1580
0
    if(memtype == NC_NAT) memtype = attrp->type;
1581
1582
0
    if(memtype != NC_CHAR && attrp->type == NC_CHAR)
1583
0
  return NC_ECHAR;
1584
0
    if(memtype == NC_CHAR && attrp->type != NC_CHAR)
1585
0
  return NC_ECHAR;
1586
1587
0
    xp = attrp->xvalue;
1588
0
    switch (memtype) {
1589
0
    case NC_CHAR:
1590
0
        return ncx_pad_getn_text(&xp, attrp->nelems, (char *)value);
1591
0
    case NC_BYTE:
1592
0
        return ncx_pad_getn_Ischar(&xp,attrp->nelems,(schar*)value,attrp->type);
1593
0
    case NC_SHORT:
1594
0
        return ncx_pad_getn_Ishort(&xp,attrp->nelems,(short*)value,attrp->type);
1595
0
    case NC_INT:
1596
0
          return ncx_pad_getn_Iint(&xp,attrp->nelems,(int*)value,attrp->type);
1597
0
    case NC_FLOAT:
1598
0
        return ncx_pad_getn_Ifloat(&xp,attrp->nelems,(float*)value,attrp->type);
1599
0
    case NC_DOUBLE:
1600
0
        return ncx_pad_getn_Idouble(&xp,attrp->nelems,(double*)value,attrp->type);
1601
0
    case NC_INT64:
1602
0
          return ncx_pad_getn_Ilonglong(&xp,attrp->nelems,(longlong*)value,attrp->type);
1603
0
    case NC_UBYTE: /* Synthetic */
1604
        /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
1605
0
        if (!fIsSet(ncp->flags,NC_64BIT_DATA) && attrp->type == NC_BYTE)
1606
0
            return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, NC_UBYTE);
1607
0
        else
1608
0
            return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, attrp->type);
1609
0
    case NC_USHORT:
1610
0
          return ncx_pad_getn_Iushort(&xp,attrp->nelems,(ushort*)value,attrp->type);
1611
0
    case NC_UINT:
1612
0
          return ncx_pad_getn_Iuint(&xp,attrp->nelems,(uint*)value,attrp->type);
1613
0
    case NC_UINT64:
1614
0
          return ncx_pad_getn_Iulonglong(&xp,attrp->nelems,(ulonglong*)value,attrp->type);
1615
0
    case NC_NAT:
1616
0
        return NC_EBADTYPE;
1617
0
    default:
1618
0
        break;
1619
0
    }
1620
0
    status =  NC_EBADTYPE;
1621
0
    return status;
1622
0
}