Coverage Report

Created: 2023-05-28 06:42

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