Coverage Report

Created: 2025-10-28 07:06

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
26.8k
{
30
31
26.8k
  if(attrp == NULL)
32
0
    return;
33
26.8k
  free_NC_string(attrp->name);
34
26.8k
  free(attrp);
35
26.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
26.8k
{
45
26.8k
  switch(type) {
46
798
  case NC_BYTE:
47
1.26k
  case NC_CHAR:
48
1.26k
    return ncx_len_char(nelems);
49
15
  case NC_SHORT:
50
15
    return ncx_len_short(nelems);
51
191
  case NC_INT:
52
191
    return ncx_len_int(nelems);
53
2.86k
  case NC_FLOAT:
54
2.86k
    return ncx_len_float(nelems);
55
5
  case NC_DOUBLE:
56
5
    return ncx_len_double(nelems);
57
21.6k
  case NC_UBYTE:
58
21.6k
    return ncx_len_ubyte(nelems);
59
136
  case NC_USHORT:
60
136
    return ncx_len_ushort(nelems);
61
447
  case NC_UINT:
62
447
    return ncx_len_uint(nelems);
63
4
  case NC_INT64:
64
4
    return ncx_len_int64(nelems);
65
302
  case NC_UINT64:
66
302
    return ncx_len_uint64(nelems);
67
0
  default:
68
0
          assert("ncx_len_NC_attr bad type" == 0);
69
26.8k
  }
70
0
  return 0;
71
26.8k
}
72
73
74
NC_attr *
75
new_x_NC_attr(
76
  NC_string *strp,
77
  nc_type type,
78
  size_t nelems)
79
26.8k
{
80
26.8k
  NC_attr *attrp;
81
26.8k
  const size_t xsz = ncx_len_NC_attrV(type, nelems);
82
26.8k
  size_t sz = M_RNDUP(sizeof(NC_attr));
83
84
26.8k
  assert(!(xsz == 0 && nelems != 0));
85
86
26.8k
  if(sz > SIZE_MAX -xsz)
87
3
    return NULL;
88
89
26.8k
  sz += xsz;
90
91
26.8k
  attrp = (NC_attr *) malloc(sz);
92
26.8k
  if(attrp == NULL )
93
2
    return NULL;
94
95
26.8k
  attrp->xsz = xsz;
96
97
26.8k
  attrp->name = strp;
98
26.8k
  attrp->type = type;
99
26.8k
  attrp->nelems = nelems;
100
26.8k
  if(xsz != 0)
101
2.04k
    attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr));
102
24.8k
  else
103
24.8k
    attrp->xvalue = NULL;
104
105
26.8k
  return(attrp);
106
26.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
224
{
166
224
  assert(ncap != NULL);
167
168
224
  if(ncap->nelems == 0)
169
23
    return;
170
171
224
  assert(ncap->value != NULL);
172
173
201
  {
174
201
    NC_attr **app = ncap->value;
175
201
    NC_attr *const *const end = &app[ncap->nelems];
176
27.0k
    for( /*NADA*/; app < end; app++)
177
26.8k
    {
178
26.8k
      free_NC_attr(*app);
179
26.8k
      *app = NULL;
180
26.8k
    }
181
201
  }
182
201
  ncap->nelems = 0;
183
201
}
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
143k
{
194
143k
  assert(ncap != NULL);
195
196
143k
  if(ncap->nalloc == 0)
197
142k
    return;
198
199
143k
  assert(ncap->value != NULL);
200
201
224
  free_NC_attrarrayV0(ncap);
202
203
224
  free(ncap->value);
204
224
  ncap->value = NULL;
205
224
  ncap->nalloc = 0;
206
224
}
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
  (void) strncpy(name, attrp->name->cp, attrp->name->nchars);
442
0
  name[attrp->name->nchars] = 0;
443
444
0
  return NC_NOERR;
445
0
}
446
447
448
int
449
NC3_inq_attid(int ncid, int varid, const char *name, int *attnump)
450
0
{
451
0
  int status;
452
0
  NC *nc;
453
0
  NC3_INFO* ncp;
454
0
  NC_attrarray *ncap;
455
0
  NC_attr **attrpp;
456
457
0
  status = NC_check_id(ncid, &nc);
458
0
  if(status != NC_NOERR)
459
0
    return status;
460
0
  ncp = NC3_DATA(nc);
461
462
0
  ncap = NC_attrarray0(ncp, varid);
463
0
  if(ncap == NULL)
464
0
    return NC_ENOTVAR;
465
466
467
0
  attrpp = NC_findattr(ncap, name);
468
0
  if(attrpp == NULL)
469
0
    return NC_ENOTATT;
470
471
0
  if(attnump != NULL)
472
0
    *attnump = (int)(attrpp - ncap->value);
473
474
0
  return NC_NOERR;
475
0
}
476
477
int
478
NC3_inq_att(int ncid,
479
  int varid,
480
  const char *name, /* input, attribute name */
481
  nc_type *datatypep,
482
  size_t *lenp)
483
0
{
484
0
  int status;
485
0
  NC_attr *attrp;
486
487
0
  status = NC_lookupattr(ncid, varid, name, &attrp);
488
0
  if(status != NC_NOERR)
489
0
    return status;
490
491
0
  if(datatypep != NULL)
492
0
    *datatypep = attrp->type;
493
0
  if(lenp != NULL)
494
0
    *lenp = attrp->nelems;
495
496
0
  return NC_NOERR;
497
0
}
498
499
500
int
501
NC3_rename_att( int ncid, int varid, const char *name, const char *unewname)
502
0
{
503
0
  int status = NC_NOERR;
504
0
  NC *nc = NULL;
505
0
  NC3_INFO* ncp = NULL;
506
0
  NC_attrarray *ncap = NULL;
507
0
  NC_attr **tmp = NULL;
508
0
  NC_attr *attrp = NULL;
509
0
  NC_string *newStr, *old;
510
0
  char *newname = NULL;  /* normalized version */
511
512
/* start sortof inline clone of NC_lookupattr() */
513
514
0
  status = NC_check_id(ncid, &nc);
515
0
  if(status != NC_NOERR)
516
0
    goto done;
517
0
  ncp = NC3_DATA(nc);
518
519
0
  if(NC_readonly(ncp))
520
0
    {status = NC_EPERM; goto done;}
521
522
0
  ncap = NC_attrarray0(ncp, varid);
523
0
  if(ncap == NULL)
524
0
    {status = NC_ENOTVAR; goto done;}
525
526
0
  status = NC_check_name(unewname);
527
0
  if(status != NC_NOERR)
528
0
    goto done;
529
530
0
  tmp = NC_findattr(ncap, name);
531
0
  if(tmp == NULL)
532
0
    {status = NC_ENOTATT; goto done;}
533
0
  attrp = *tmp;
534
/* end inline clone NC_lookupattr() */
535
536
0
  if(NC_findattr(ncap, unewname) != NULL)
537
0
      {status = NC_ENAMEINUSE; goto done;} /* name in use */
538
539
0
  old = attrp->name;
540
0
  status = nc_utf8_normalize((const unsigned char *)unewname,(unsigned char**)&newname);
541
0
  if(status != NC_NOERR)
542
0
      goto done;
543
0
  if(NC_indef(ncp))
544
0
  {
545
0
    newStr = new_NC_string(strlen(newname), newname);
546
0
    if( newStr == NULL)
547
0
      {status = NC_ENOMEM; goto done;}
548
0
    attrp->name = newStr;
549
0
    free_NC_string(old);
550
0
    goto done;
551
0
  }
552
  /* else not in define mode */
553
554
  /* If new name is longer than old, then complain,
555
           but otherwise, no change (test is same as set_NC_string)*/
556
0
  if(old->nchars < strlen(newname))
557
0
      {status = NC_ENOTINDEFINE; goto done;}
558
559
0
  status = set_NC_string(old, newname);
560
0
  if( status != NC_NOERR)
561
0
    goto done;
562
563
0
  set_NC_hdirty(ncp);
564
565
0
  if(NC_doHsync(ncp))
566
0
  {
567
0
    status = NC_sync(ncp);
568
0
    if(status != NC_NOERR)
569
0
      goto done;
570
0
  }
571
0
done:
572
0
  if(newname) free(newname);
573
0
  return status;
574
0
}
575
576
int
577
NC3_del_att(int ncid, int varid, const char *uname)
578
0
{
579
0
  int status = NC_NOERR;
580
0
  NC *nc = NULL;
581
0
  NC3_INFO* ncp = NULL;
582
0
  NC_attrarray *ncap = NULL;
583
0
  NC_attr **attrpp = NULL;
584
0
  NC_attr *old = NULL;
585
0
  int attrid;
586
0
  size_t slen;
587
0
  char* name = NULL;
588
589
0
  status = NC_check_id(ncid, &nc);
590
0
  if(status != NC_NOERR)
591
0
    goto done;
592
0
  ncp = NC3_DATA(nc);
593
594
0
  if(!NC_indef(ncp))
595
0
    {status = NC_ENOTINDEFINE; goto done;}
596
597
0
  ncap = NC_attrarray0(ncp, varid);
598
0
  if(ncap == NULL)
599
0
    {status = NC_ENOTVAR; goto done;}
600
601
0
  status = nc_utf8_normalize((const unsigned char *)uname,(unsigned char**)&name);
602
0
  if(status != NC_NOERR)
603
0
      goto done;
604
605
/* start sortof inline NC_findattr() */
606
0
  slen = strlen(name);
607
608
0
  attrpp = (NC_attr **) ncap->value;
609
0
  for(attrid = 0; (size_t) attrid < ncap->nelems; attrid++, attrpp++)
610
0
      {
611
0
    if( slen == (*attrpp)->name->nchars &&
612
0
      strncmp(name, (*attrpp)->name->cp, slen) == 0)
613
0
    {
614
0
      old = *attrpp;
615
0
      break;
616
0
    }
617
0
      }
618
0
  if( (size_t) attrid == ncap->nelems )
619
0
    {status = NC_ENOTATT; goto done;}
620
/* end inline NC_findattr() */
621
622
  /* shuffle down */
623
0
  for(attrid++; (size_t) attrid < ncap->nelems; attrid++)
624
0
  {
625
0
    *attrpp = *(attrpp + 1);
626
0
    attrpp++;
627
0
  }
628
0
  *attrpp = NULL;
629
  /* decrement count */
630
0
  ncap->nelems--;
631
632
0
  free_NC_attr(old);
633
634
0
done:
635
0
  if(name) free(name);
636
0
  return status;
637
0
}
638
639
640
static int
641
ncx_pad_putn_Iuchar(void **xpp, size_t nelems, const uchar *tp, nc_type type, void *fillp)
642
0
{
643
0
  switch(type) {
644
0
  case NC_CHAR:
645
0
    return NC_ECHAR;
646
0
  case NC_BYTE:
647
0
    return ncx_pad_putn_schar_uchar(xpp, nelems, tp, fillp);
648
0
  case NC_SHORT:
649
0
    return ncx_pad_putn_short_uchar(xpp, nelems, tp, fillp);
650
0
  case NC_INT:
651
0
    return ncx_putn_int_uchar(xpp, nelems, tp, fillp);
652
0
  case NC_FLOAT:
653
0
    return ncx_putn_float_uchar(xpp, nelems, tp, fillp);
654
0
  case NC_DOUBLE:
655
0
    return ncx_putn_double_uchar(xpp, nelems, tp, fillp);
656
0
  case NC_UBYTE:
657
0
    return ncx_pad_putn_uchar_uchar(xpp, nelems, tp, fillp);
658
0
  case NC_USHORT:
659
0
    return ncx_putn_ushort_uchar(xpp, nelems, tp, fillp);
660
0
  case NC_UINT:
661
0
    return ncx_putn_uint_uchar(xpp, nelems, tp, fillp);
662
0
  case NC_INT64:
663
0
    return ncx_putn_longlong_uchar(xpp, nelems, tp, fillp);
664
0
  case NC_UINT64:
665
0
    return ncx_putn_ulonglong_uchar(xpp, nelems, tp, fillp);
666
0
  default:
667
0
                assert("ncx_pad_putn_Iuchar invalid type" == 0);
668
0
  }
669
0
  return NC_EBADTYPE;
670
0
}
671
672
static int
673
ncx_pad_getn_Iuchar(const void **xpp, size_t nelems, uchar *tp, nc_type type)
674
0
{
675
0
  switch(type) {
676
0
  case NC_CHAR:
677
0
    return NC_ECHAR;
678
0
  case NC_BYTE:
679
0
    return ncx_pad_getn_schar_uchar(xpp, nelems, tp);
680
0
  case NC_SHORT:
681
0
    return ncx_pad_getn_short_uchar(xpp, nelems, tp);
682
0
  case NC_INT:
683
0
    return ncx_getn_int_uchar(xpp, nelems, tp);
684
0
  case NC_FLOAT:
685
0
    return ncx_getn_float_uchar(xpp, nelems, tp);
686
0
  case NC_DOUBLE:
687
0
    return ncx_getn_double_uchar(xpp, nelems, tp);
688
0
  case NC_UBYTE:
689
0
    return ncx_pad_getn_uchar_uchar(xpp, nelems, tp);
690
0
  case NC_USHORT:
691
0
    return ncx_getn_ushort_uchar(xpp, nelems, tp);
692
0
  case NC_UINT:
693
0
    return ncx_getn_uint_uchar(xpp, nelems, tp);
694
0
  case NC_INT64:
695
0
    return ncx_getn_longlong_uchar(xpp, nelems, tp);
696
0
  case NC_UINT64:
697
0
    return ncx_getn_ulonglong_uchar(xpp, nelems, tp);
698
0
  default:
699
0
          assert("ncx_pad_getn_Iuchar invalid type" == 0);
700
0
  }
701
0
  return NC_EBADTYPE;
702
0
}
703
704
705
static int
706
ncx_pad_putn_Ischar(void **xpp, size_t nelems, const schar *tp, nc_type type, void *fillp)
707
0
{
708
0
  switch(type) {
709
0
  case NC_CHAR:
710
0
    return NC_ECHAR;
711
0
  case NC_BYTE:
712
0
    return ncx_pad_putn_schar_schar(xpp, nelems, tp, fillp);
713
0
  case NC_SHORT:
714
0
    return ncx_pad_putn_short_schar(xpp, nelems, tp, fillp);
715
0
  case NC_INT:
716
0
    return ncx_putn_int_schar(xpp, nelems, tp, fillp);
717
0
  case NC_FLOAT:
718
0
    return ncx_putn_float_schar(xpp, nelems, tp, fillp);
719
0
  case NC_DOUBLE:
720
0
    return ncx_putn_double_schar(xpp, nelems, tp, fillp);
721
0
  case NC_UBYTE:
722
0
    return ncx_pad_putn_uchar_schar(xpp, nelems, tp, fillp);
723
0
  case NC_USHORT:
724
0
    return ncx_putn_ushort_schar(xpp, nelems, tp, fillp);
725
0
  case NC_UINT:
726
0
    return ncx_putn_uint_schar(xpp, nelems, tp, fillp);
727
0
  case NC_INT64:
728
0
    return ncx_putn_longlong_schar(xpp, nelems, tp, fillp);
729
0
  case NC_UINT64:
730
0
    return ncx_putn_ulonglong_schar(xpp, nelems, tp, fillp);
731
0
  default:
732
0
                assert("ncx_pad_putn_Ischar invalid type" == 0);
733
0
  }
734
0
  return NC_EBADTYPE;
735
0
}
736
737
static int
738
ncx_pad_getn_Ischar(const void **xpp, size_t nelems, schar *tp, nc_type type)
739
0
{
740
0
  switch(type) {
741
0
  case NC_CHAR:
742
0
    return NC_ECHAR;
743
0
  case NC_BYTE:
744
0
    return ncx_pad_getn_schar_schar(xpp, nelems, tp);
745
0
  case NC_SHORT:
746
0
    return ncx_pad_getn_short_schar(xpp, nelems, tp);
747
0
  case NC_INT:
748
0
    return ncx_getn_int_schar(xpp, nelems, tp);
749
0
  case NC_FLOAT:
750
0
    return ncx_getn_float_schar(xpp, nelems, tp);
751
0
  case NC_DOUBLE:
752
0
    return ncx_getn_double_schar(xpp, nelems, tp);
753
0
  case NC_UBYTE:
754
0
    return ncx_pad_getn_uchar_schar(xpp, nelems, tp);
755
0
  case NC_USHORT:
756
0
    return ncx_getn_ushort_schar(xpp, nelems, tp);
757
0
  case NC_UINT:
758
0
    return ncx_getn_uint_schar(xpp, nelems, tp);
759
0
  case NC_INT64:
760
0
    return ncx_getn_longlong_schar(xpp, nelems, tp);
761
0
  case NC_UINT64:
762
0
    return ncx_getn_ulonglong_schar(xpp, nelems, tp);
763
0
  default:
764
0
          assert("ncx_pad_getn_Ischar invalid type" == 0);
765
0
  }
766
0
  return NC_EBADTYPE;
767
0
}
768
769
770
static int
771
ncx_pad_putn_Ishort(void **xpp, size_t nelems, const short *tp, nc_type type, void *fillp)
772
0
{
773
0
  switch(type) {
774
0
  case NC_CHAR:
775
0
    return NC_ECHAR;
776
0
  case NC_BYTE:
777
0
    return ncx_pad_putn_schar_short(xpp, nelems, tp, fillp);
778
0
  case NC_SHORT:
779
0
    return ncx_pad_putn_short_short(xpp, nelems, tp, fillp);
780
0
  case NC_INT:
781
0
    return ncx_putn_int_short(xpp, nelems, tp, fillp);
782
0
  case NC_FLOAT:
783
0
    return ncx_putn_float_short(xpp, nelems, tp, fillp);
784
0
  case NC_DOUBLE:
785
0
    return ncx_putn_double_short(xpp, nelems, tp, fillp);
786
0
  case NC_UBYTE:
787
0
    return ncx_pad_putn_uchar_short(xpp, nelems, tp, fillp);
788
0
  case NC_USHORT:
789
0
    return ncx_putn_ushort_short(xpp, nelems, tp, fillp);
790
0
  case NC_UINT:
791
0
    return ncx_putn_uint_short(xpp, nelems, tp, fillp);
792
0
  case NC_INT64:
793
0
    return ncx_putn_longlong_short(xpp, nelems, tp, fillp);
794
0
  case NC_UINT64:
795
0
    return ncx_putn_ulonglong_short(xpp, nelems, tp, fillp);
796
0
  default:
797
0
                assert("ncx_pad_putn_Ishort invalid type" == 0);
798
0
  }
799
0
  return NC_EBADTYPE;
800
0
}
801
802
static int
803
ncx_pad_getn_Ishort(const void **xpp, size_t nelems, short *tp, nc_type type)
804
0
{
805
0
  switch(type) {
806
0
  case NC_CHAR:
807
0
    return NC_ECHAR;
808
0
  case NC_BYTE:
809
0
    return ncx_pad_getn_schar_short(xpp, nelems, tp);
810
0
  case NC_SHORT:
811
0
    return ncx_pad_getn_short_short(xpp, nelems, tp);
812
0
  case NC_INT:
813
0
    return ncx_getn_int_short(xpp, nelems, tp);
814
0
  case NC_FLOAT:
815
0
    return ncx_getn_float_short(xpp, nelems, tp);
816
0
  case NC_DOUBLE:
817
0
    return ncx_getn_double_short(xpp, nelems, tp);
818
0
  case NC_UBYTE:
819
0
    return ncx_pad_getn_uchar_short(xpp, nelems, tp);
820
0
  case NC_USHORT:
821
0
    return ncx_getn_ushort_short(xpp, nelems, tp);
822
0
  case NC_UINT:
823
0
    return ncx_getn_uint_short(xpp, nelems, tp);
824
0
  case NC_INT64:
825
0
    return ncx_getn_longlong_short(xpp, nelems, tp);
826
0
  case NC_UINT64:
827
0
    return ncx_getn_ulonglong_short(xpp, nelems, tp);
828
0
  default:
829
0
          assert("ncx_pad_getn_Ishort invalid type" == 0);
830
0
  }
831
0
  return NC_EBADTYPE;
832
0
}
833
834
835
static int
836
ncx_pad_putn_Iint(void **xpp, size_t nelems, const int *tp, nc_type type, void *fillp)
837
0
{
838
0
  switch(type) {
839
0
  case NC_CHAR:
840
0
    return NC_ECHAR;
841
0
  case NC_BYTE:
842
0
    return ncx_pad_putn_schar_int(xpp, nelems, tp, fillp);
843
0
  case NC_SHORT:
844
0
    return ncx_pad_putn_short_int(xpp, nelems, tp, fillp);
845
0
  case NC_INT:
846
0
    return ncx_putn_int_int(xpp, nelems, tp, fillp);
847
0
  case NC_FLOAT:
848
0
    return ncx_putn_float_int(xpp, nelems, tp, fillp);
849
0
  case NC_DOUBLE:
850
0
    return ncx_putn_double_int(xpp, nelems, tp, fillp);
851
0
  case NC_UBYTE:
852
0
    return ncx_pad_putn_uchar_int(xpp, nelems, tp, fillp);
853
0
  case NC_USHORT:
854
0
    return ncx_putn_ushort_int(xpp, nelems, tp, fillp);
855
0
  case NC_UINT:
856
0
    return ncx_putn_uint_int(xpp, nelems, tp, fillp);
857
0
  case NC_INT64:
858
0
    return ncx_putn_longlong_int(xpp, nelems, tp, fillp);
859
0
  case NC_UINT64:
860
0
    return ncx_putn_ulonglong_int(xpp, nelems, tp, fillp);
861
0
  default:
862
0
                assert("ncx_pad_putn_Iint invalid type" == 0);
863
0
  }
864
0
  return NC_EBADTYPE;
865
0
}
866
867
static int
868
ncx_pad_getn_Iint(const void **xpp, size_t nelems, int *tp, nc_type type)
869
0
{
870
0
  switch(type) {
871
0
  case NC_CHAR:
872
0
    return NC_ECHAR;
873
0
  case NC_BYTE:
874
0
    return ncx_pad_getn_schar_int(xpp, nelems, tp);
875
0
  case NC_SHORT:
876
0
    return ncx_pad_getn_short_int(xpp, nelems, tp);
877
0
  case NC_INT:
878
0
    return ncx_getn_int_int(xpp, nelems, tp);
879
0
  case NC_FLOAT:
880
0
    return ncx_getn_float_int(xpp, nelems, tp);
881
0
  case NC_DOUBLE:
882
0
    return ncx_getn_double_int(xpp, nelems, tp);
883
0
  case NC_UBYTE:
884
0
    return ncx_pad_getn_uchar_int(xpp, nelems, tp);
885
0
  case NC_USHORT:
886
0
    return ncx_getn_ushort_int(xpp, nelems, tp);
887
0
  case NC_UINT:
888
0
    return ncx_getn_uint_int(xpp, nelems, tp);
889
0
  case NC_INT64:
890
0
    return ncx_getn_longlong_int(xpp, nelems, tp);
891
0
  case NC_UINT64:
892
0
    return ncx_getn_ulonglong_int(xpp, nelems, tp);
893
0
  default:
894
0
          assert("ncx_pad_getn_Iint invalid type" == 0);
895
0
  }
896
0
  return NC_EBADTYPE;
897
0
}
898
899
900
static int
901
ncx_pad_putn_Ifloat(void **xpp, size_t nelems, const float *tp, nc_type type, void *fillp)
902
0
{
903
0
  switch(type) {
904
0
  case NC_CHAR:
905
0
    return NC_ECHAR;
906
0
  case NC_BYTE:
907
0
    return ncx_pad_putn_schar_float(xpp, nelems, tp, fillp);
908
0
  case NC_SHORT:
909
0
    return ncx_pad_putn_short_float(xpp, nelems, tp, fillp);
910
0
  case NC_INT:
911
0
    return ncx_putn_int_float(xpp, nelems, tp, fillp);
912
0
  case NC_FLOAT:
913
0
    return ncx_putn_float_float(xpp, nelems, tp, fillp);
914
0
  case NC_DOUBLE:
915
0
    return ncx_putn_double_float(xpp, nelems, tp, fillp);
916
0
  case NC_UBYTE:
917
0
    return ncx_pad_putn_uchar_float(xpp, nelems, tp, fillp);
918
0
  case NC_USHORT:
919
0
    return ncx_putn_ushort_float(xpp, nelems, tp, fillp);
920
0
  case NC_UINT:
921
0
    return ncx_putn_uint_float(xpp, nelems, tp, fillp);
922
0
  case NC_INT64:
923
0
    return ncx_putn_longlong_float(xpp, nelems, tp, fillp);
924
0
  case NC_UINT64:
925
0
    return ncx_putn_ulonglong_float(xpp, nelems, tp, fillp);
926
0
  default:
927
0
                assert("ncx_pad_putn_Ifloat invalid type" == 0);
928
0
  }
929
0
  return NC_EBADTYPE;
930
0
}
931
932
static int
933
ncx_pad_getn_Ifloat(const void **xpp, size_t nelems, float *tp, nc_type type)
934
0
{
935
0
  switch(type) {
936
0
  case NC_CHAR:
937
0
    return NC_ECHAR;
938
0
  case NC_BYTE:
939
0
    return ncx_pad_getn_schar_float(xpp, nelems, tp);
940
0
  case NC_SHORT:
941
0
    return ncx_pad_getn_short_float(xpp, nelems, tp);
942
0
  case NC_INT:
943
0
    return ncx_getn_int_float(xpp, nelems, tp);
944
0
  case NC_FLOAT:
945
0
    return ncx_getn_float_float(xpp, nelems, tp);
946
0
  case NC_DOUBLE:
947
0
    return ncx_getn_double_float(xpp, nelems, tp);
948
0
  case NC_UBYTE:
949
0
    return ncx_pad_getn_uchar_float(xpp, nelems, tp);
950
0
  case NC_USHORT:
951
0
    return ncx_getn_ushort_float(xpp, nelems, tp);
952
0
  case NC_UINT:
953
0
    return ncx_getn_uint_float(xpp, nelems, tp);
954
0
  case NC_INT64:
955
0
    return ncx_getn_longlong_float(xpp, nelems, tp);
956
0
  case NC_UINT64:
957
0
    return ncx_getn_ulonglong_float(xpp, nelems, tp);
958
0
  default:
959
0
          assert("ncx_pad_getn_Ifloat invalid type" == 0);
960
0
  }
961
0
  return NC_EBADTYPE;
962
0
}
963
964
965
static int
966
ncx_pad_putn_Idouble(void **xpp, size_t nelems, const double *tp, nc_type type, void *fillp)
967
0
{
968
0
  switch(type) {
969
0
  case NC_CHAR:
970
0
    return NC_ECHAR;
971
0
  case NC_BYTE:
972
0
    return ncx_pad_putn_schar_double(xpp, nelems, tp, fillp);
973
0
  case NC_SHORT:
974
0
    return ncx_pad_putn_short_double(xpp, nelems, tp, fillp);
975
0
  case NC_INT:
976
0
    return ncx_putn_int_double(xpp, nelems, tp, fillp);
977
0
  case NC_FLOAT:
978
0
    return ncx_putn_float_double(xpp, nelems, tp, fillp);
979
0
  case NC_DOUBLE:
980
0
    return ncx_putn_double_double(xpp, nelems, tp, fillp);
981
0
  case NC_UBYTE:
982
0
    return ncx_pad_putn_uchar_double(xpp, nelems, tp, fillp);
983
0
  case NC_USHORT:
984
0
    return ncx_putn_ushort_double(xpp, nelems, tp, fillp);
985
0
  case NC_UINT:
986
0
    return ncx_putn_uint_double(xpp, nelems, tp, fillp);
987
0
  case NC_INT64:
988
0
    return ncx_putn_longlong_double(xpp, nelems, tp, fillp);
989
0
  case NC_UINT64:
990
0
    return ncx_putn_ulonglong_double(xpp, nelems, tp, fillp);
991
0
  default:
992
0
                assert("ncx_pad_putn_Idouble invalid type" == 0);
993
0
  }
994
0
  return NC_EBADTYPE;
995
0
}
996
997
static int
998
ncx_pad_getn_Idouble(const void **xpp, size_t nelems, double *tp, nc_type type)
999
0
{
1000
0
  switch(type) {
1001
0
  case NC_CHAR:
1002
0
    return NC_ECHAR;
1003
0
  case NC_BYTE:
1004
0
    return ncx_pad_getn_schar_double(xpp, nelems, tp);
1005
0
  case NC_SHORT:
1006
0
    return ncx_pad_getn_short_double(xpp, nelems, tp);
1007
0
  case NC_INT:
1008
0
    return ncx_getn_int_double(xpp, nelems, tp);
1009
0
  case NC_FLOAT:
1010
0
    return ncx_getn_float_double(xpp, nelems, tp);
1011
0
  case NC_DOUBLE:
1012
0
    return ncx_getn_double_double(xpp, nelems, tp);
1013
0
  case NC_UBYTE:
1014
0
    return ncx_pad_getn_uchar_double(xpp, nelems, tp);
1015
0
  case NC_USHORT:
1016
0
    return ncx_getn_ushort_double(xpp, nelems, tp);
1017
0
  case NC_UINT:
1018
0
    return ncx_getn_uint_double(xpp, nelems, tp);
1019
0
  case NC_INT64:
1020
0
    return ncx_getn_longlong_double(xpp, nelems, tp);
1021
0
  case NC_UINT64:
1022
0
    return ncx_getn_ulonglong_double(xpp, nelems, tp);
1023
0
  default:
1024
0
          assert("ncx_pad_getn_Idouble invalid type" == 0);
1025
0
  }
1026
0
  return NC_EBADTYPE;
1027
0
}
1028
1029
1030
#ifdef IGNORE
1031
static int
1032
ncx_pad_putn_Ilong(void **xpp, size_t nelems, const long *tp, nc_type type, void *fillp)
1033
{
1034
  switch(type) {
1035
  case NC_CHAR:
1036
    return NC_ECHAR;
1037
  case NC_BYTE:
1038
    return ncx_pad_putn_schar_long(xpp, nelems, tp, fillp);
1039
  case NC_SHORT:
1040
    return ncx_pad_putn_short_long(xpp, nelems, tp, fillp);
1041
  case NC_INT:
1042
    return ncx_putn_int_long(xpp, nelems, tp, fillp);
1043
  case NC_FLOAT:
1044
    return ncx_putn_float_long(xpp, nelems, tp, fillp);
1045
  case NC_DOUBLE:
1046
    return ncx_putn_double_long(xpp, nelems, tp, fillp);
1047
  case NC_UBYTE:
1048
    return ncx_pad_putn_uchar_long(xpp, nelems, tp, fillp);
1049
  case NC_USHORT:
1050
    return ncx_putn_ushort_long(xpp, nelems, tp, fillp);
1051
  case NC_UINT:
1052
    return ncx_putn_uint_long(xpp, nelems, tp, fillp);
1053
  case NC_INT64:
1054
    return ncx_putn_longlong_long(xpp, nelems, tp, fillp);
1055
  case NC_UINT64:
1056
    return ncx_putn_ulonglong_long(xpp, nelems, tp, fillp);
1057
  default:
1058
                assert("ncx_pad_putn_Ilong invalid type" == 0);
1059
  }
1060
  return NC_EBADTYPE;
1061
}
1062
1063
static int
1064
ncx_pad_getn_Ilong(const void **xpp, size_t nelems, long *tp, nc_type type)
1065
{
1066
  switch(type) {
1067
  case NC_CHAR:
1068
    return NC_ECHAR;
1069
  case NC_BYTE:
1070
    return ncx_pad_getn_schar_long(xpp, nelems, tp);
1071
  case NC_SHORT:
1072
    return ncx_pad_getn_short_long(xpp, nelems, tp);
1073
  case NC_INT:
1074
    return ncx_getn_int_long(xpp, nelems, tp);
1075
  case NC_FLOAT:
1076
    return ncx_getn_float_long(xpp, nelems, tp);
1077
  case NC_DOUBLE:
1078
    return ncx_getn_double_long(xpp, nelems, tp);
1079
  case NC_UBYTE:
1080
    return ncx_pad_getn_uchar_long(xpp, nelems, tp);
1081
  case NC_USHORT:
1082
    return ncx_getn_ushort_long(xpp, nelems, tp);
1083
  case NC_UINT:
1084
    return ncx_getn_uint_long(xpp, nelems, tp);
1085
  case NC_INT64:
1086
    return ncx_getn_longlong_long(xpp, nelems, tp);
1087
  case NC_UINT64:
1088
    return ncx_getn_ulonglong_long(xpp, nelems, tp);
1089
  default:
1090
          assert("ncx_pad_getn_Ilong invalid type" == 0);
1091
  }
1092
  return NC_EBADTYPE;
1093
}
1094
1095
#endif
1096
1097
static int
1098
ncx_pad_putn_Ilonglong(void **xpp, size_t nelems, const longlong *tp, nc_type type, void *fillp)
1099
0
{
1100
0
  switch(type) {
1101
0
  case NC_CHAR:
1102
0
    return NC_ECHAR;
1103
0
  case NC_BYTE:
1104
0
    return ncx_pad_putn_schar_longlong(xpp, nelems, tp, fillp);
1105
0
  case NC_SHORT:
1106
0
    return ncx_pad_putn_short_longlong(xpp, nelems, tp, fillp);
1107
0
  case NC_INT:
1108
0
    return ncx_putn_int_longlong(xpp, nelems, tp, fillp);
1109
0
  case NC_FLOAT:
1110
0
    return ncx_putn_float_longlong(xpp, nelems, tp, fillp);
1111
0
  case NC_DOUBLE:
1112
0
    return ncx_putn_double_longlong(xpp, nelems, tp, fillp);
1113
0
  case NC_UBYTE:
1114
0
    return ncx_pad_putn_uchar_longlong(xpp, nelems, tp, fillp);
1115
0
  case NC_USHORT:
1116
0
    return ncx_putn_ushort_longlong(xpp, nelems, tp, fillp);
1117
0
  case NC_UINT:
1118
0
    return ncx_putn_uint_longlong(xpp, nelems, tp, fillp);
1119
0
  case NC_INT64:
1120
0
    return ncx_putn_longlong_longlong(xpp, nelems, tp, fillp);
1121
0
  case NC_UINT64:
1122
0
    return ncx_putn_ulonglong_longlong(xpp, nelems, tp, fillp);
1123
0
  default:
1124
0
                assert("ncx_pad_putn_Ilonglong invalid type" == 0);
1125
0
  }
1126
0
  return NC_EBADTYPE;
1127
0
}
1128
1129
static int
1130
ncx_pad_getn_Ilonglong(const void **xpp, size_t nelems, longlong *tp, nc_type type)
1131
0
{
1132
0
  switch(type) {
1133
0
  case NC_CHAR:
1134
0
    return NC_ECHAR;
1135
0
  case NC_BYTE:
1136
0
    return ncx_pad_getn_schar_longlong(xpp, nelems, tp);
1137
0
  case NC_SHORT:
1138
0
    return ncx_pad_getn_short_longlong(xpp, nelems, tp);
1139
0
  case NC_INT:
1140
0
    return ncx_getn_int_longlong(xpp, nelems, tp);
1141
0
  case NC_FLOAT:
1142
0
    return ncx_getn_float_longlong(xpp, nelems, tp);
1143
0
  case NC_DOUBLE:
1144
0
    return ncx_getn_double_longlong(xpp, nelems, tp);
1145
0
  case NC_UBYTE:
1146
0
    return ncx_pad_getn_uchar_longlong(xpp, nelems, tp);
1147
0
  case NC_USHORT:
1148
0
    return ncx_getn_ushort_longlong(xpp, nelems, tp);
1149
0
  case NC_UINT:
1150
0
    return ncx_getn_uint_longlong(xpp, nelems, tp);
1151
0
  case NC_INT64:
1152
0
    return ncx_getn_longlong_longlong(xpp, nelems, tp);
1153
0
  case NC_UINT64:
1154
0
    return ncx_getn_ulonglong_longlong(xpp, nelems, tp);
1155
0
  default:
1156
0
          assert("ncx_pad_getn_Ilonglong invalid type" == 0);
1157
0
  }
1158
0
  return NC_EBADTYPE;
1159
0
}
1160
1161
1162
static int
1163
ncx_pad_putn_Iushort(void **xpp, size_t nelems, const ushort *tp, nc_type type, void *fillp)
1164
0
{
1165
0
  switch(type) {
1166
0
  case NC_CHAR:
1167
0
    return NC_ECHAR;
1168
0
  case NC_BYTE:
1169
0
    return ncx_pad_putn_schar_ushort(xpp, nelems, tp, fillp);
1170
0
  case NC_SHORT:
1171
0
    return ncx_pad_putn_short_ushort(xpp, nelems, tp, fillp);
1172
0
  case NC_INT:
1173
0
    return ncx_putn_int_ushort(xpp, nelems, tp, fillp);
1174
0
  case NC_FLOAT:
1175
0
    return ncx_putn_float_ushort(xpp, nelems, tp, fillp);
1176
0
  case NC_DOUBLE:
1177
0
    return ncx_putn_double_ushort(xpp, nelems, tp, fillp);
1178
0
  case NC_UBYTE:
1179
0
    return ncx_pad_putn_uchar_ushort(xpp, nelems, tp, fillp);
1180
0
  case NC_USHORT:
1181
0
    return ncx_putn_ushort_ushort(xpp, nelems, tp, fillp);
1182
0
  case NC_UINT:
1183
0
    return ncx_putn_uint_ushort(xpp, nelems, tp, fillp);
1184
0
  case NC_INT64:
1185
0
    return ncx_putn_longlong_ushort(xpp, nelems, tp, fillp);
1186
0
  case NC_UINT64:
1187
0
    return ncx_putn_ulonglong_ushort(xpp, nelems, tp, fillp);
1188
0
  default:
1189
0
                assert("ncx_pad_putn_Iushort invalid type" == 0);
1190
0
  }
1191
0
  return NC_EBADTYPE;
1192
0
}
1193
1194
static int
1195
ncx_pad_getn_Iushort(const void **xpp, size_t nelems, ushort *tp, nc_type type)
1196
0
{
1197
0
  switch(type) {
1198
0
  case NC_CHAR:
1199
0
    return NC_ECHAR;
1200
0
  case NC_BYTE:
1201
0
    return ncx_pad_getn_schar_ushort(xpp, nelems, tp);
1202
0
  case NC_SHORT:
1203
0
    return ncx_pad_getn_short_ushort(xpp, nelems, tp);
1204
0
  case NC_INT:
1205
0
    return ncx_getn_int_ushort(xpp, nelems, tp);
1206
0
  case NC_FLOAT:
1207
0
    return ncx_getn_float_ushort(xpp, nelems, tp);
1208
0
  case NC_DOUBLE:
1209
0
    return ncx_getn_double_ushort(xpp, nelems, tp);
1210
0
  case NC_UBYTE:
1211
0
    return ncx_pad_getn_uchar_ushort(xpp, nelems, tp);
1212
0
  case NC_USHORT:
1213
0
    return ncx_getn_ushort_ushort(xpp, nelems, tp);
1214
0
  case NC_UINT:
1215
0
    return ncx_getn_uint_ushort(xpp, nelems, tp);
1216
0
  case NC_INT64:
1217
0
    return ncx_getn_longlong_ushort(xpp, nelems, tp);
1218
0
  case NC_UINT64:
1219
0
    return ncx_getn_ulonglong_ushort(xpp, nelems, tp);
1220
0
  default:
1221
0
          assert("ncx_pad_getn_Iushort invalid type" == 0);
1222
0
  }
1223
0
  return NC_EBADTYPE;
1224
0
}
1225
1226
1227
static int
1228
ncx_pad_putn_Iuint(void **xpp, size_t nelems, const uint *tp, nc_type type, void *fillp)
1229
0
{
1230
0
  switch(type) {
1231
0
  case NC_CHAR:
1232
0
    return NC_ECHAR;
1233
0
  case NC_BYTE:
1234
0
    return ncx_pad_putn_schar_uint(xpp, nelems, tp, fillp);
1235
0
  case NC_SHORT:
1236
0
    return ncx_pad_putn_short_uint(xpp, nelems, tp, fillp);
1237
0
  case NC_INT:
1238
0
    return ncx_putn_int_uint(xpp, nelems, tp, fillp);
1239
0
  case NC_FLOAT:
1240
0
    return ncx_putn_float_uint(xpp, nelems, tp, fillp);
1241
0
  case NC_DOUBLE:
1242
0
    return ncx_putn_double_uint(xpp, nelems, tp, fillp);
1243
0
  case NC_UBYTE:
1244
0
    return ncx_pad_putn_uchar_uint(xpp, nelems, tp, fillp);
1245
0
  case NC_USHORT:
1246
0
    return ncx_putn_ushort_uint(xpp, nelems, tp, fillp);
1247
0
  case NC_UINT:
1248
0
    return ncx_putn_uint_uint(xpp, nelems, tp, fillp);
1249
0
  case NC_INT64:
1250
0
    return ncx_putn_longlong_uint(xpp, nelems, tp, fillp);
1251
0
  case NC_UINT64:
1252
0
    return ncx_putn_ulonglong_uint(xpp, nelems, tp, fillp);
1253
0
  default:
1254
0
                assert("ncx_pad_putn_Iuint invalid type" == 0);
1255
0
  }
1256
0
  return NC_EBADTYPE;
1257
0
}
1258
1259
static int
1260
ncx_pad_getn_Iuint(const void **xpp, size_t nelems, uint *tp, nc_type type)
1261
0
{
1262
0
  switch(type) {
1263
0
  case NC_CHAR:
1264
0
    return NC_ECHAR;
1265
0
  case NC_BYTE:
1266
0
    return ncx_pad_getn_schar_uint(xpp, nelems, tp);
1267
0
  case NC_SHORT:
1268
0
    return ncx_pad_getn_short_uint(xpp, nelems, tp);
1269
0
  case NC_INT:
1270
0
    return ncx_getn_int_uint(xpp, nelems, tp);
1271
0
  case NC_FLOAT:
1272
0
    return ncx_getn_float_uint(xpp, nelems, tp);
1273
0
  case NC_DOUBLE:
1274
0
    return ncx_getn_double_uint(xpp, nelems, tp);
1275
0
  case NC_UBYTE:
1276
0
    return ncx_pad_getn_uchar_uint(xpp, nelems, tp);
1277
0
  case NC_USHORT:
1278
0
    return ncx_getn_ushort_uint(xpp, nelems, tp);
1279
0
  case NC_UINT:
1280
0
    return ncx_getn_uint_uint(xpp, nelems, tp);
1281
0
  case NC_INT64:
1282
0
    return ncx_getn_longlong_uint(xpp, nelems, tp);
1283
0
  case NC_UINT64:
1284
0
    return ncx_getn_ulonglong_uint(xpp, nelems, tp);
1285
0
  default:
1286
0
          assert("ncx_pad_getn_Iuint invalid type" == 0);
1287
0
  }
1288
0
  return NC_EBADTYPE;
1289
0
}
1290
1291
1292
static int
1293
ncx_pad_putn_Iulonglong(void **xpp, size_t nelems, const ulonglong *tp, nc_type type, void *fillp)
1294
0
{
1295
0
  switch(type) {
1296
0
  case NC_CHAR:
1297
0
    return NC_ECHAR;
1298
0
  case NC_BYTE:
1299
0
    return ncx_pad_putn_schar_ulonglong(xpp, nelems, tp, fillp);
1300
0
  case NC_SHORT:
1301
0
    return ncx_pad_putn_short_ulonglong(xpp, nelems, tp, fillp);
1302
0
  case NC_INT:
1303
0
    return ncx_putn_int_ulonglong(xpp, nelems, tp, fillp);
1304
0
  case NC_FLOAT:
1305
0
    return ncx_putn_float_ulonglong(xpp, nelems, tp, fillp);
1306
0
  case NC_DOUBLE:
1307
0
    return ncx_putn_double_ulonglong(xpp, nelems, tp, fillp);
1308
0
  case NC_UBYTE:
1309
0
    return ncx_pad_putn_uchar_ulonglong(xpp, nelems, tp, fillp);
1310
0
  case NC_USHORT:
1311
0
    return ncx_putn_ushort_ulonglong(xpp, nelems, tp, fillp);
1312
0
  case NC_UINT:
1313
0
    return ncx_putn_uint_ulonglong(xpp, nelems, tp, fillp);
1314
0
  case NC_INT64:
1315
0
    return ncx_putn_longlong_ulonglong(xpp, nelems, tp, fillp);
1316
0
  case NC_UINT64:
1317
0
    return ncx_putn_ulonglong_ulonglong(xpp, nelems, tp, fillp);
1318
0
  default:
1319
0
                assert("ncx_pad_putn_Iulonglong invalid type" == 0);
1320
0
  }
1321
0
  return NC_EBADTYPE;
1322
0
}
1323
1324
static int
1325
ncx_pad_getn_Iulonglong(const void **xpp, size_t nelems, ulonglong *tp, nc_type type)
1326
0
{
1327
0
  switch(type) {
1328
0
  case NC_CHAR:
1329
0
    return NC_ECHAR;
1330
0
  case NC_BYTE:
1331
0
    return ncx_pad_getn_schar_ulonglong(xpp, nelems, tp);
1332
0
  case NC_SHORT:
1333
0
    return ncx_pad_getn_short_ulonglong(xpp, nelems, tp);
1334
0
  case NC_INT:
1335
0
    return ncx_getn_int_ulonglong(xpp, nelems, tp);
1336
0
  case NC_FLOAT:
1337
0
    return ncx_getn_float_ulonglong(xpp, nelems, tp);
1338
0
  case NC_DOUBLE:
1339
0
    return ncx_getn_double_ulonglong(xpp, nelems, tp);
1340
0
  case NC_UBYTE:
1341
0
    return ncx_pad_getn_uchar_ulonglong(xpp, nelems, tp);
1342
0
  case NC_USHORT:
1343
0
    return ncx_getn_ushort_ulonglong(xpp, nelems, tp);
1344
0
  case NC_UINT:
1345
0
    return ncx_getn_uint_ulonglong(xpp, nelems, tp);
1346
0
  case NC_INT64:
1347
0
    return ncx_getn_longlong_ulonglong(xpp, nelems, tp);
1348
0
  case NC_UINT64:
1349
0
    return ncx_getn_ulonglong_ulonglong(xpp, nelems, tp);
1350
0
  default:
1351
0
          assert("ncx_pad_getn_Iulonglong invalid type" == 0);
1352
0
  }
1353
0
  return NC_EBADTYPE;
1354
0
}
1355
1356
1357
1358
/* Common dispatcher for put cases */
1359
static int
1360
dispatchput(void **xpp, size_t nelems, const void* tp,
1361
      nc_type atype, nc_type memtype, void *fillp)
1362
0
{
1363
0
    switch (memtype) {
1364
0
    case NC_CHAR:
1365
0
        return ncx_pad_putn_text(xpp,nelems, (char *)tp);
1366
0
    case NC_BYTE:
1367
0
        return ncx_pad_putn_Ischar(xpp, nelems, (schar*)tp, atype, fillp);
1368
0
    case NC_SHORT:
1369
0
        return ncx_pad_putn_Ishort(xpp, nelems, (short*)tp, atype, fillp);
1370
0
    case NC_INT:
1371
0
          return ncx_pad_putn_Iint(xpp, nelems, (int*)tp, atype, fillp);
1372
0
    case NC_FLOAT:
1373
0
        return ncx_pad_putn_Ifloat(xpp, nelems, (float*)tp, atype, fillp);
1374
0
    case NC_DOUBLE:
1375
0
        return ncx_pad_putn_Idouble(xpp, nelems, (double*)tp, atype, fillp);
1376
0
    case NC_UBYTE: /*Synthetic*/
1377
0
        return ncx_pad_putn_Iuchar(xpp,nelems, (uchar *)tp, atype, fillp);
1378
0
    case NC_INT64:
1379
0
          return ncx_pad_putn_Ilonglong(xpp, nelems, (longlong*)tp, atype, fillp);
1380
0
    case NC_USHORT:
1381
0
          return ncx_pad_putn_Iushort(xpp, nelems, (ushort*)tp, atype, fillp);
1382
0
    case NC_UINT:
1383
0
          return ncx_pad_putn_Iuint(xpp, nelems, (uint*)tp, atype, fillp);
1384
0
    case NC_UINT64:
1385
0
          return ncx_pad_putn_Iulonglong(xpp, nelems, (ulonglong*)tp, atype, fillp);
1386
0
    case NC_NAT:
1387
0
        return NC_EBADTYPE;
1388
0
    default:
1389
0
        break;
1390
0
    }
1391
0
    return NC_EBADTYPE;
1392
0
}
1393
1394
int
1395
NC3_put_att(
1396
  int ncid,
1397
  int varid,
1398
  const char *name,
1399
  nc_type type,
1400
  size_t nelems,
1401
  const void *value,
1402
  nc_type memtype)
1403
0
{
1404
0
    int status;
1405
0
    NC *nc;
1406
0
    NC3_INFO* ncp;
1407
0
    NC_attrarray *ncap;
1408
0
    NC_attr **attrpp;
1409
0
    NC_attr *old = NULL;
1410
0
    NC_attr *attrp;
1411
0
    unsigned char fill[8]; /* fill value in internal representation */
1412
1413
0
    status = NC_check_id(ncid, &nc);
1414
0
    if(status != NC_NOERR)
1415
0
  return status;
1416
0
    ncp = NC3_DATA(nc);
1417
1418
0
    if(NC_readonly(ncp))
1419
0
  return NC_EPERM;
1420
1421
0
    ncap = NC_attrarray0(ncp, varid);
1422
0
    if(ncap == NULL)
1423
0
  return NC_ENOTVAR;
1424
1425
0
    if (name == NULL)
1426
0
        return NC_EBADNAME;
1427
1428
    /* check NC_EBADTYPE */
1429
0
    status = nc3_cktype(nc->mode, type);
1430
0
    if(status != NC_NOERR)
1431
0
  return status;
1432
1433
0
    if(memtype == NC_NAT) memtype = type;
1434
1435
0
    if(memtype != NC_CHAR && type == NC_CHAR)
1436
0
  return NC_ECHAR;
1437
0
    if(memtype == NC_CHAR && type != NC_CHAR)
1438
0
  return NC_ECHAR;
1439
1440
    /* cast needed for braindead systems with signed size_t */
1441
0
    if((unsigned long) nelems > X_INT_MAX) /* backward compat */
1442
0
  return NC_EINVAL; /* Invalid nelems */
1443
1444
0
    if(nelems != 0 && value == NULL)
1445
0
  return NC_EINVAL; /* Null arg */
1446
1447
    /* Temporarily removed to preserve extant
1448
       workflows (NCO based and others). See
1449
1450
       https://github.com/Unidata/netcdf-c/issues/843
1451
1452
       for more information. */
1453
1454
#if 0
1455
    if (varid != NC_GLOBAL && !strcmp(name, _FillValue)) {
1456
        /* Fill value must be of the same data type */
1457
        if (type != ncp->vars.value[varid]->type) return NC_EBADTYPE;
1458
1459
        /* Fill value must have exactly one value */
1460
        if (nelems != 1) return NC_EINVAL;
1461
1462
        /* Only allow for variables defined in initial define mode */
1463
        if (ncp->old != NULL && varid < ncp->old->vars.nelems)
1464
            return NC_ELATEFILL; /* try put attribute for an old variable */
1465
    }
1466
#endif
1467
1468
0
    attrpp = NC_findattr(ncap, name);
1469
1470
    /* 4 cases: exists X indef */
1471
1472
0
    status = NC3_inq_default_fill_value(type, &fill);
1473
0
    if (status != NC_NOERR) return status;
1474
1475
0
    if(attrpp != NULL) { /* name in use */
1476
0
        if(!NC_indef(ncp)) {
1477
0
      const size_t xsz = ncx_len_NC_attrV(type, nelems);
1478
0
            attrp = *attrpp; /* convenience */
1479
1480
0
      if(xsz > attrp->xsz) return NC_ENOTINDEFINE;
1481
      /* else, we can reuse existing without redef */
1482
1483
0
      attrp->xsz = xsz;
1484
0
            attrp->type = type;
1485
0
            attrp->nelems = nelems;
1486
1487
0
            if(nelems != 0) {
1488
0
                void *xp = attrp->xvalue;
1489
                /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
1490
0
                if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) {
1491
0
                    status = NC3_inq_default_fill_value(NC_UBYTE, &fill);
1492
0
                    if (status != NC_NOERR) return status;
1493
0
                    status = dispatchput(&xp, nelems, value, memtype, memtype, &fill);
1494
0
                } else
1495
0
                    status = dispatchput(&xp, nelems, value, type, memtype, &fill);
1496
0
            }
1497
1498
0
            set_NC_hdirty(ncp);
1499
1500
0
            if(NC_doHsync(ncp)) {
1501
0
          const int lstatus = NC_sync(ncp);
1502
                /*
1503
                 * N.B.: potentially overrides NC_ERANGE
1504
                 * set by ncx_pad_putn_I$1
1505
                 */
1506
0
                if(lstatus != NC_NOERR) return lstatus;
1507
0
            }
1508
1509
0
            return status;
1510
0
        }
1511
        /* else, redefine using existing array slot */
1512
0
        old = *attrpp;
1513
0
    } else {
1514
0
        if(!NC_indef(ncp)) return NC_ENOTINDEFINE;
1515
0
    }
1516
1517
0
    status = NC_check_name(name);
1518
0
    if(status != NC_NOERR) return status;
1519
1520
0
    attrp = new_NC_attr(name, type, nelems);
1521
0
    if(attrp == NULL) return NC_ENOMEM;
1522
1523
0
    if(nelems != 0) {
1524
0
        void *xp = attrp->xvalue;
1525
        /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
1526
0
        if (!fIsSet(ncp->flags,NC_64BIT_DATA) && type == NC_BYTE && memtype == NC_UBYTE) {
1527
0
            status = NC3_inq_default_fill_value(NC_UBYTE, &fill);
1528
0
            if (status != NC_NOERR) return status;
1529
0
            status = dispatchput(&xp, nelems, (const void*)value, memtype, memtype, &fill);
1530
0
        } else
1531
0
            status = dispatchput(&xp, nelems, (const void*)value, type, memtype, &fill);
1532
0
    }
1533
1534
0
    if(attrpp != NULL) {
1535
0
        *attrpp = attrp;
1536
0
  if(old != NULL)
1537
0
          free_NC_attr(old);
1538
0
    } else {
1539
0
        const int lstatus = incr_NC_attrarray(ncap, attrp);
1540
        /*
1541
         * N.B.: potentially overrides NC_ERANGE
1542
         * set by ncx_pad_putn_I$1
1543
         */
1544
0
        if(lstatus != NC_NOERR) {
1545
0
           free_NC_attr(attrp);
1546
0
           return lstatus;
1547
0
        }
1548
0
    }
1549
0
    return status;
1550
0
}
1551
1552
int
1553
NC3_get_att(
1554
  int ncid,
1555
  int varid,
1556
  const char *name,
1557
  void *value,
1558
  nc_type memtype)
1559
0
{
1560
0
    int status;
1561
0
    NC *nc;
1562
0
    NC3_INFO* ncp;
1563
0
    NC_attr *attrp;
1564
0
    const void *xp;
1565
1566
0
    status = NC_check_id(ncid, &nc);
1567
0
    if(status != NC_NOERR)
1568
0
  return status;
1569
0
    ncp = NC3_DATA(nc);
1570
1571
0
    status = NC_lookupattr(ncid, varid, name, &attrp);
1572
0
    if(status != NC_NOERR) return status;
1573
1574
0
    if(attrp->nelems == 0) return NC_NOERR;
1575
1576
0
    if(memtype == NC_NAT) memtype = attrp->type;
1577
1578
0
    if(memtype != NC_CHAR && attrp->type == NC_CHAR)
1579
0
  return NC_ECHAR;
1580
0
    if(memtype == NC_CHAR && attrp->type != NC_CHAR)
1581
0
  return NC_ECHAR;
1582
1583
0
    xp = attrp->xvalue;
1584
0
    switch (memtype) {
1585
0
    case NC_CHAR:
1586
0
        return ncx_pad_getn_text(&xp, attrp->nelems, (char *)value);
1587
0
    case NC_BYTE:
1588
0
        return ncx_pad_getn_Ischar(&xp,attrp->nelems,(schar*)value,attrp->type);
1589
0
    case NC_SHORT:
1590
0
        return ncx_pad_getn_Ishort(&xp,attrp->nelems,(short*)value,attrp->type);
1591
0
    case NC_INT:
1592
0
          return ncx_pad_getn_Iint(&xp,attrp->nelems,(int*)value,attrp->type);
1593
0
    case NC_FLOAT:
1594
0
        return ncx_pad_getn_Ifloat(&xp,attrp->nelems,(float*)value,attrp->type);
1595
0
    case NC_DOUBLE:
1596
0
        return ncx_pad_getn_Idouble(&xp,attrp->nelems,(double*)value,attrp->type);
1597
0
    case NC_INT64:
1598
0
          return ncx_pad_getn_Ilonglong(&xp,attrp->nelems,(longlong*)value,attrp->type);
1599
0
    case NC_UBYTE: /* Synthetic */
1600
        /* for CDF-1 and CDF-2, NC_BYTE is treated the same type as uchar memtype */
1601
0
        if (!fIsSet(ncp->flags,NC_64BIT_DATA) && attrp->type == NC_BYTE)
1602
0
            return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, NC_UBYTE);
1603
0
        else
1604
0
            return ncx_pad_getn_Iuchar(&xp, attrp->nelems, (uchar *)value, attrp->type);
1605
0
    case NC_USHORT:
1606
0
          return ncx_pad_getn_Iushort(&xp,attrp->nelems,(ushort*)value,attrp->type);
1607
0
    case NC_UINT:
1608
0
          return ncx_pad_getn_Iuint(&xp,attrp->nelems,(uint*)value,attrp->type);
1609
0
    case NC_UINT64:
1610
0
          return ncx_pad_getn_Iulonglong(&xp,attrp->nelems,(ulonglong*)value,attrp->type);
1611
0
    case NC_NAT:
1612
0
        return NC_EBADTYPE;
1613
0
    default:
1614
0
        break;
1615
0
    }
1616
0
    status =  NC_EBADTYPE;
1617
0
    return status;
1618
0
}